libxcoder 5.7.0
Loading...
Searching...
No Matches
ni_device_api_priv.c
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Copyright (C) 2022 NETINT Technologies
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 * SOFTWARE.
19 *
20 ******************************************************************************/
21
22/*!*****************************************************************************
23 * \file ni_device_api_priv.c
24 *
25 * \brief Private definitions used by ni_device_api.c for video processing
26 * tasks
27 ******************************************************************************/
28
29#ifdef _WIN32
30#include <windows.h>
31#elif __linux__ || __APPLE__
32#if __linux__
33#include <linux/types.h>
34#include <malloc.h>
35#include <sys/prctl.h>
36#endif
37#include <sys/file.h>
38#include <sys/ioctl.h>
39#include <sys/stat.h>
40#include <unistd.h>
41#include <sys/mman.h>
42#include <sys/types.h>
43#include <utime.h>
44#include <sys/time.h>
45#include <fcntl.h>
46#include <errno.h>
47#include <semaphore.h>
48#include <limits.h>
49#include <signal.h>
50#include <dirent.h>
51#include <sched.h>
52#include <sys/syscall.h>
53#include <sys/resource.h>
54#if !defined(_ANDROID) && !defined(__OPENHARMONY__)
55#include <execinfo.h>
56#endif
57#endif
58
59#include <stdint.h>
60#include <string.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <math.h>
64#ifdef __linux__
65#include <stdint.h>
66#include <poll.h>
67#include "ni_p2p_ioctl.h"
68#endif
69#include "inttypes.h"
70#include "ni_nvme.h"
71#include "ni_device_api.h"
72#include "ni_device_api_priv.h"
73#include "ni_util.h"
74#include "ni_lat_meas.h"
75#include "ni_rsrc_priv.h"
76
77#if defined(__linux__) && defined(XCODER_ENABLE_CPU_AFFINITY)
78#include <numa.h>
79#endif
80
81//Map the gopPresetIdx to gopSize,
82//gopPresetIdx -1: Adaptive Gop, using the biggest gopsize 8
83//gopPresetIdx 0 : Custom Gop as defined by -xcoder-gop
84//g_map_preset_to_gopsize[lookAheadEnable][gopPresetIdx + 1];
85//for the not support gopPresetIdx value, such as gopPresetIdx == 2, set g_map_preset_to_gopsize to -1
86static const int g_map_preset_to_gopsize[2][18] = {{8, 0, 1, -1, 1, 2, 4, -1, 4, 8, 1, 4, -1, -1, -1, -1, 16},
87 {8, 0, -1, -1, -1, 2, 4, -1, -1, 8, 1, -1, -1, -1, -1, -1, -1}};
88#define MIN(x,y) (((x)>(y))?(y):(x))
89#define MAX(x,y) (((x)<(y))?(y):(x))
90#define HEVC_LEVEL_NUM 13
91#define H264_LEVEL_NUM 20
92#define AV1_LEVEL_NUM 14
93#define HIGH_TIER 1
94static const uint64_t max_sample_rate_second_h265[ HEVC_LEVEL_NUM ] =
95{
96 552960, 3686400, 7372800, 16588800, 33177600, 66846720, 133693440, 267386880,
97 534773760, 1069547520, 1069547520, 2139095040, 4278190080
98};
99static const uint64_t max_sample_rate_second_h264[ H264_LEVEL_NUM ] =
100{
101 1485*256, 1485*256, 3000*256, 6000*256, 11880*256, 11880*256, 19800*256, 20250*256,
102 40500*256, 108000*256, 216000*256, 245760*256, 245760*256,
103 522240*256, 589824*256, 983040*256, 2073600*256,
104 4177920*256, 8355840*256, 16711680ULL*256
105};
106static const uint64_t max_sample_rate_second_av1[ AV1_LEVEL_NUM ] =
107{
108 5529600, 10454400, /*0, 0,*/ 24969600, 39938400, 77856768, 155713536,
109 273715200, 547430400, 1094860800, 1176502272, 1176502272, 2189721600, 4379443200, 4706009088
110};
111
112static const uint32_t max_pic_size_h265[ HEVC_LEVEL_NUM ] =
113{
114 36864, 122880, 245760, 552960, 983040, 2228224, 2228224, 8912896,
115 8912896, 8912896, 35651584, 35651584, 35651584
116};
117static const uint32_t max_pic_size_h264[ H264_LEVEL_NUM ] =
118{
119 99*256, 99*256, 396*256, 396*256, 396*256, 396*256, 792*256, 1620*256,
120 1620*256, 3600*256, 5120*256, 8192*256, 8192*256,
121 8704*256, 22080*256, 36864*256, 36864*256,
122 139264*256, 139264*256, 139264*256
123};
124static const uint32_t max_pic_size_av1[ AV1_LEVEL_NUM ] =
125{
126 147456, 278784, 665856, 1065024, 2359296, 2359296,
127 8912896, 8912896, 8912896, 8912896, 35651584, 35651584, 35651584, 35651584
128};
129
130static const uint32_t max_cpb_second_h265[ HEVC_LEVEL_NUM ] =
131{
132 350000, 1500000, 3000000, 6000000, 10000000, 12000000, 20000000,
133 25000000, 40000000, 60000000, 60000000, 120000000, 240000000
134};
135static const uint32_t max_cpb_hightier_second_h265[ HEVC_LEVEL_NUM ] =
136{
137 350000, 1500000, 3000000, 6000000, 10000000, 30000000, 50000000,
138 100000000, 160000000, 240000000, 240000000, 480000000, 800000000
139};
140static const uint32_t max_cpb_second_h264[ H264_LEVEL_NUM ] =
141{
142 175000, 350000, 500000, 1000000, 2000000, 2000000, 4000000, 4000000,
143 10000000, 14000000, 20000000, 25000000, 62500000,
144 62500000, 135000000, 240000000, 240000000,
145 240000000, 480000000, 800000000
146};
147static const uint32_t max_cpb_second_av1[ AV1_LEVEL_NUM ] =
148{
149 1500000, 3000000, 6000000, 10000000, 12000000, 20000000,
150 30000000, 40000000, 60000000, 60000000, 60000000, 100000000, 160000000, 160000000
151};
152static const uint32_t max_cpb_hightier_second_av1[ AV1_LEVEL_NUM ] =
153{
154 0, 0, 0, 0, 30000000, 50000000,
155 100000000, 160000000, 240000000, 240000000, 240000000, 480000000, 800000000, 800000000
156};
157static const uint32_t max_bitrate_h264[ H264_LEVEL_NUM ] =
158{
159 64000, 128000, 192000, 384000, 768000, 2000000, 4000000, 4000000,
160 10000000, 14000000, 20000000, 20000000, 50000000,
161 50000000, 135000000, 240000000, 240000000,
162 240000000, 480000000, 800000000
163};
164
165#define MAGIC_P2P_VALUE "p2p"
166#define AI_MODEL_TYPE_HVSPLUS_FILTER 3
167#define AI_MODEL_TYPE_USM_FILTER 4
168
174
175typedef enum
176{
177 OPT_1 = 1, // is a combination of OPT_3 and OPT_2 in that order
178 OPT_2 = 2, // returns NI_RETCODE_FAILURE after NI_XCODER_FAILURES_MAX attempts, and LRETURNs for failures
179 OPT_3 = 3 // queries session statistics
181
182// Preset configuration lookup table
192
193static const PresetConfig preset_configs[] = {
194 [NI_VQ_VERYFAST] = {1, 0, GOP_PRESET_IDX_SP, 1000, 1, 0.0f, -1.0f},
195 [NI_VQ_FASTER] = {2, 0, GOP_PRESET_IDX_SP, 1000, 1, 0.0f, -1.0f},
196 [NI_VQ_FAST] = {3, 0, GOP_PRESET_IDX_SP, 1000, 1, 0.0f, -1.0f},
197 [NI_VQ_MEDIUM] = {1, 16, GOP_PRESET_IDX_DEFAULT, 3000, 0, 0.0f, 0.0f},
198 [NI_VQ_SLOW] = {2, 16, GOP_PRESET_IDX_DEFAULT, 3000, 0, 0.0f, 0.0f},
199 [NI_VQ_SLOWER] = {3, 16, GOP_PRESET_IDX_DEFAULT, 3000, 0, 0.0f, 0.0f},
200 [NI_VQ_VERYSLOW] = {3, 40, GOP_PRESET_IDX_DEFAULT, 3000, 0, 0.0f, 0.0f}
201};
202
203static uint8_t g_itu_t_t35_cc_sei_hdr_hevc[NI_CC_SEI_HDR_HEVC_LEN] = {
204 0x00, 0x00, 0x00, 0x01, // NAL start code 00 00 00 01
205 0x4e,
206 0x01, // nal_unit_header() {forbidden bit=0 nal_unit_type=39,
207 // nuh_layer_id=0 nuh_temporal_id_plus1=1)
208 0x04, // payloadType= 4 (user_data_registered_itu_t_t35)
209 0 + 11, // payLoadSize= ui16Len + 11; to be set (index 7)
210 0xb5, // itu_t_t35_country_code =181 (North America)
211 0x00,
212 0x31, // itu_t_t35_provider_code = 49
213 0x47, 0x41, 0x39,
214 0x34, // ATSC_user_identifier = "GA94"
215 0x03, // ATSC1_data_user_data_type_code=3
216 0 | 0xc0, // (ui16Len/3) | 0xc0 (to be set; index 16) (each CC character
217 //is 3 bytes)
218 0xFF // em_data = 255
219};
220
221static uint8_t g_itu_t_t35_hdr10p_sei_hdr_hevc[NI_HDR10P_SEI_HDR_HEVC_LEN] = {
222 0x00, 0x00, 0x00, 0x01, // NAL start code 00 00 00 01
223 0x4e,
224 0x01, // nal_unit_header() {forbidden bit=0 nal_unit_type=39,
225 // nuh_layer_id=0 nuh_temporal_id_plus1=1)
226 0x04, // payloadType= 4 (user_data_registered_itu_t_t35)
227 0x00, // payLoadSize; to be set (index 7)
228 0xb5, // u8 itu_t_t35_country_code =181 (North America)
229 //0x00,
230 //0x3c, // u16 itu_t_t35_provider_code = 0x003c
231 //0x00,
232 //0x01, // u16 itu_t_t35_provider_oriented_code = 0x0001
233 // payLoadSize count starts from itu_t_t35_provider_code and goes until
234 // and including trailer
235};
236
237static uint8_t g_itu_t_t35_cc_sei_hdr_h264[NI_CC_SEI_HDR_H264_LEN] = {
238 0x00, 0x00, 0x00, 0x01, // NAL start code 00 00 00 01
239 0x06, // nal_unit_header() {forbidden bit=0 nal_ref_idc=0, nal_unit_type=6
240 0x04, // payloadType= 4 (user_data_registered_itu_t_t35)
241 0 + 11, // payLoadSize= ui16Len + 11; to be set (index 6)
242 0xb5, // itu_t_t35_country_code =181 (North America)
243 0x00,
244 0x31, // itu_t_t35_provider_code = 49
245 0x47, 0x41, 0x39,
246 0x34, // ATSC_user_identifier = "GA94"
247 0x03, // ATSC1_data_user_data_type_code=3
248 0 | 0xc0, // (ui16Len/3) | 0xc0 (to be set; index 15) (each CC character
249 //is 3 bytes)
250 0xFF // em_data = 255
251};
252
253static uint8_t g_itu_t_t35_hdr10p_sei_hdr_h264[NI_HDR10P_SEI_HDR_H264_LEN] = {
254 0x00, 0x00, 0x00, 0x01, // NAL start code 00 00 00 01
255 0x06, // nal_unit_header() {forbidden bit=0 nal_ref_idc=0, nal_unit_type=6
256 0x04, // payloadType= 4 (user_data_registered_itu_t_t35)
257 0x00, // payLoadSize; to be set (index 6)
258 0xb5, // itu_t_t35_country_code =181 (North America)
259 //0x00,
260 //0x3c, // u16 itu_t_t35_provider_code = 0x003c
261 //0x00,
262 //0x01, // u16 itu_t_t35_provider_oriented_code = 0x0001
263 // payLoadSize count starts from itu_t_t35_provider_code and goes until
264 // and including trailer
265};
266
267static uint8_t g_sei_trailer[NI_CC_SEI_TRAILER_LEN] = {
268 0xFF, // marker_bits = 255
269 0x80 // RBSP trailing bits - rbsp_stop_one_bit and 7 rbsp_alignment_zero_bit
270};
271
272#define NI_XCODER_FAILURES_MAX 25
273#define DP_IPC_PASSTHRU 0xFFFFFFFF
274
275#ifdef _WIN32
276#ifdef XCODER_SELF_KILL_ERR
277#undef XCODER_SELF_KILL_ERR
278#endif
279#endif
280
281#ifdef PRINT_FW_LOGS
282ni_retcode_t ni_device_get_and_print_firmware_logs(ni_session_context_t *p_ctx);
283#endif
284
285void SwapSWBytes(uint8_t *buf, uint32_t bytes)
286{
287 uint32_t i;
288 for (i = 0; i < bytes; i += 2)
289 {
290 uint8_t val = buf[i];
291 buf[i] = buf[i + 1];
292 buf[i + 1] = val;
293 }
294}
295
296void SwapSW16(uint16_t *buf, uint32_t bytes)
297{
298 uint32_t i, words = (bytes + 1) / 2;
299
300 for (i = 0; i < words; i += 2)
301 {
302 uint16_t val = buf[i];
303 buf[i] = buf[i + 1];
304 buf[i + 1] = val;
305 }
306}
307
308void SwapSW32(uint32_t *buf, uint32_t bytes)
309{
310 uint32_t i, words = (bytes + 3) / 4;
311 for (i = 0; i < words; i += 2)
312 {
313 uint32_t val = buf[i];
314 buf[i] = buf[i + 1];
315 buf[i + 1] = val;
316 }
317}
318
319void SwapSW64(uint64_t *buf, uint64_t bytes)
320{
321 uint64_t i, words = (bytes + 7) / 8;
322 for (i = 0; i < words; i += 2)
323 {
324 uint64_t val = buf[i];
325 buf[i] = buf[i + 1];
326 buf[i + 1] = val;
327 }
328}
329
330static void memcpyToPelByBits (uint8_t *dst_u8, uint8_t *src, int width, int height, int dst_stride, int src_stride, int srcValidBitsDepth)
331{
332 int i, j;
333 uint8_t bitsDepth = srcValidBitsDepth;
334 uint32_t mask = (1<<bitsDepth)-1;
335 uint16_t *dst = (uint16_t *)dst_u8;
336
337 //fast for byte write
338 if (bitsDepth == 8)
339 {
340 for (j = 0; j < height; j ++)
341 {
342 for (i = 0; i< width; i ++)
343 dst_u8[i] = src[i] & 0xff;
344
345 src += src_stride;
346 dst_u8 += dst_stride;
347 }
348 return;
349 }
350
351 //for arbitrary bits
352 for (j = 0; j < height; j ++)
353 {
354 uint8_t *src_line = src;
355 uint32_t cache = 0, cache_bits = 0;
356 for (i = 0; i< width; i ++)
357 {
358 while(cache_bits < bitsDepth)
359 {
360 cache |= ((*src_line++) << cache_bits);
361 cache_bits += 8;
362 }
363
364 if (cache_bits >= bitsDepth)
365 {
366 dst[i] = cache & mask;
367 cache >>= bitsDepth;
368 cache_bits -= bitsDepth;
369 }
370 }
371
372 src += src_stride;
373 dst += dst_stride;
374 }
375}
376
377/*
378static void write_(FILE *fp, uint8_t *data, int32_t width, int32_t height, int32_t stripe)
379{
380 int32_t i;
381
382 for (i = 0; i < height; i++)
383 {
384 if (fwrite(data, sizeof(uint8_t ), width, fp) < (size_t)width)
385 {
386 return;
387 }
388 data += stripe;
389 }
390}
391*/
392
393static void trace_recon_tile2raster_y(FILE *fRecon, uint8_t *mem, int width, int height,
394 int leftOffset, int topOffset,
395 int src_stride, int pixDepth, uint8_t *luma_mem_temp)
396{
397 int i;
398 int write_data_len = 0;
399 int bytesPerPix = (pixDepth == 8 ? 1 : 2);
400 uint8_t *tmp_mem = (uint8_t *)malloc(bytesPerPix*src_stride);
401 int num_tiles = (leftOffset + width + 3) / 4 - leftOffset/4;
402 if(tmp_mem == NULL)
403 return;
404 mem += topOffset/4*4*src_stride + leftOffset/4*16*pixDepth/8;
405 for(i = topOffset/4*4; i < topOffset + height; i += 4) {
406 memcpyToPelByBits(tmp_mem, mem, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
407 if(i >= topOffset && i < topOffset + height){
408 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
409 memcpy(luma_mem_temp + write_data_len, tmp_mem + (leftOffset & 3) * bytesPerPix, width * bytesPerPix);
410 write_data_len += width * bytesPerPix;
411 }
412 memcpyToPelByBits(tmp_mem, mem+4*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
413 if(i+1 >= topOffset && i+1 < topOffset + height)
414 {
415 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
416 memcpy(luma_mem_temp + write_data_len, tmp_mem + (leftOffset & 3) * bytesPerPix, width * bytesPerPix);
417 write_data_len += width * bytesPerPix;
418 }
419 memcpyToPelByBits(tmp_mem, mem+8*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
420 if(i+2 >= topOffset && i+2 < topOffset + height)
421 {
422 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
423 memcpy(luma_mem_temp + write_data_len, tmp_mem + (leftOffset & 3) * bytesPerPix, width * bytesPerPix);
424 write_data_len += width * bytesPerPix;
425 }
426 memcpyToPelByBits(tmp_mem, mem+12*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
427 if(i+3 >= topOffset && i+3 < topOffset + height)
428 {
429 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
430 memcpy(luma_mem_temp + write_data_len, tmp_mem + (leftOffset & 3) * bytesPerPix, width * bytesPerPix);
431 write_data_len += width * bytesPerPix;
432 }
433 mem += 4*src_stride;
434 }
435 free(tmp_mem);
436}
437
438static void trace_recon_tile2raster_uv(FILE *fRecon, uint8_t *mem_uv, int width, int height,
439 int leftOffset, int topOffset,
440 int src_stride, int pixDepth, uint8_t *ch_mem_temp)
441{
442 int i, j, k;
443 int bytesPerPix = (pixDepth == 8 ? 1 : 2);
444 uint8_t *tmp_mem = (uint8_t *)malloc(bytesPerPix*src_stride*2);
445 int num_tiles = 2*((leftOffset + width + 3) / 4 - leftOffset/4);
446 if(tmp_mem == NULL)
447 return;
448 uint8_t *mem;
449 int uv;
450 int write_data_len = 0;
451 memset(tmp_mem, 0x00, bytesPerPix * src_stride * 2);
452 for(uv = 0; uv <= 1; uv ++) {
453 mem = mem_uv + topOffset/4*8*src_stride + leftOffset/4*32*pixDepth/8;
454 for(i = topOffset/4*4; i < topOffset + height; i += 4) {
455 if(i >= topOffset && i < topOffset + height) {
456 memcpyToPelByBits(tmp_mem, mem, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
457 for(j = uv, k = 0; j < 4 * num_tiles; j += 2, k++) {
458 if(bytesPerPix == 1)
459 tmp_mem[k] = tmp_mem[j];
460 else
461 ((uint16_t*)tmp_mem)[k] = ((uint16_t*)tmp_mem)[j];
462 }
463 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
464 memcpy(ch_mem_temp + write_data_len, tmp_mem + (leftOffset & 3) * bytesPerPix, width * bytesPerPix);
465 write_data_len += width * bytesPerPix;
466 }
467 if(i+1 >= topOffset && i+1 < topOffset + height) {
468 memcpyToPelByBits(tmp_mem, mem+4*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
469 for(j = uv, k = 0; j < 4 * num_tiles; j += 2, k++) {
470 if(bytesPerPix == 1)
471 tmp_mem[k] = tmp_mem[j];
472 else
473 ((uint16_t*)tmp_mem)[k] = ((uint16_t*)tmp_mem)[j];
474 }
475 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
476 memcpy(ch_mem_temp + write_data_len, tmp_mem + (leftOffset & 3) * bytesPerPix, width * bytesPerPix);
477 write_data_len += width * bytesPerPix;
478 }
479 if(i+2 >= topOffset && i+2 < topOffset + height) {
480 memcpyToPelByBits(tmp_mem, mem+8*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
481 for(j = uv, k = 0; j < 4 * num_tiles; j += 2, k++) {
482 if(bytesPerPix == 1)
483 tmp_mem[k] = tmp_mem[j];
484 else
485 ((uint16_t*)tmp_mem)[k] = ((uint16_t*)tmp_mem)[j];
486 }
487 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
488 memcpy(ch_mem_temp + write_data_len, tmp_mem + (leftOffset & 3) * bytesPerPix, width * bytesPerPix);
489 write_data_len += width * bytesPerPix;
490 }
491 memcpyToPelByBits(tmp_mem, mem+12*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
492 if(i+3 >= topOffset && i+3 < topOffset + height) {
493 for(j = uv, k = 0; j < 4 * num_tiles; j += 2, k++) {
494 if(bytesPerPix == 1)
495 tmp_mem[k] = tmp_mem[j];
496 else
497 ((uint16_t*)tmp_mem)[k] = ((uint16_t*)tmp_mem)[j];
498 }
499 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
500 memcpy(ch_mem_temp + write_data_len, tmp_mem + (leftOffset & 3) * bytesPerPix, width * bytesPerPix);
501 write_data_len += width * bytesPerPix;
502 }
503 mem += 8*src_stride;
504 }
505 }
506 free(tmp_mem);
507}
508
509static double calc_noise(uint8_t *p1, uint8_t *p2, int size)
510{
511 double sum;
512 double diff;
513 int i;
514
515 sum = 0;
516 for (i = 0; i < size; i++)
517 {
518 diff = p1[i] - p2[i];
519 sum += diff * diff;
520 }
521
522 return sum;
523}
524
525/*!*****************************************************************************
526 * \brief Download hw frames by HwDesc.
527 *
528 * \param
529 *
530 * \return 0 if successful, < 0 otherwise
531 ******************************************************************************/
532static int hwdl_frame(ni_session_context_t *p_ctx,
533 ni_session_data_io_t *p_session_data, ni_frame_t *p_src_frame,
534 int pixel_format)
535{
536 niFrameSurface1_t *src_surf = (niFrameSurface1_t *)(p_src_frame->p_data[3]);
537 int ret = 0;
538
539 ret = ni_frame_buffer_alloc_dl(&(p_session_data->data.frame),
540 src_surf->ui16width, src_surf->ui16height,
541 pixel_format);
542
543 if (ret != NI_RETCODE_SUCCESS)
544 {
546 }
547
548 p_ctx->is_auto_dl = false;
549 ret = ni_device_session_hwdl(p_ctx, p_session_data, src_surf);
550 if (ret <= 0)
551 {
552 ni_frame_buffer_free(&p_session_data->data.frame);
553 return ret;
554 }
555 return ret;
556}
557
559{
560 // char dump_file_tile[256];
561 // char dump_file_raster[256];
562 //FILE *fout_tile = NULL;
563 FILE *fout_raster = NULL;
564 // snprintf(dump_file_tile, sizeof(dump_file_tile), "output-%04ld-tile.yuv", (long)p_ctx->pkt_num - 1);
565 // snprintf(dump_file_raster, sizeof(dump_file_raster), "output-%04ld-raster.yuv", (long)p_ctx->pkt_num - 1);
566 // fout_tile = fopen(dump_file_tile, "wb");
567 // fout_raster = fopen(dump_file_raster, "wb");
568 // FILE *f_out = fopen("out.yuv", "a");
569 int bit_depth = (p_ctx->pixel_format == NI_PIX_FMT_YUV420P10LE || p_ctx->pixel_format == NI_PIX_FMT_P010LE) ? 10 : 8;
570
572
573 // only h.265 psnr_y is supported by HW
574 p_ctx->psnr_y = p_packet->psnr_y = (float)(p_meta->ui16psnr_y / 1000.0);
575
576 if (((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode != 3 &&
577 (p_meta->reconLumaSize != 0 || p_meta->reconChromaSize != 0))
578 {
579 uint32_t lum_sz = 0;
580 uint32_t chr_sz = 0;
581 uint8_t *luma_mem_temp = NULL;
582 uint8_t *ch_mem_temp = NULL;
583 int width = p_ctx->actual_video_width;
584 int height = p_ctx->active_video_height;//p_meta->reconLumaSize / p_meta->reconLumaWidth;
585
586 uint8_t *luma_mem = (uint8_t *)p_packet->p_data + p_packet->data_len - p_meta->reconChromaSize - p_meta->reconLumaSize;
587 uint8_t *ch_mem = (uint8_t *)p_packet->p_data + p_packet->data_len - p_meta->reconChromaSize;
588
589 int bit_scale = (p_ctx->pixel_format == NI_PIX_FMT_YUV420P10LE || p_ctx->pixel_format == NI_PIX_FMT_P010LE) ? 5 : 4;
590 lum_sz = (2 * p_meta->frameCropTopOffset + height + 3) / 4 * p_meta->reconLumaWidth * bit_scale;
591 chr_sz = (p_meta->frameCropTopOffset + height / 2 + 1) / 2 * p_meta->reconChromaWidth * bit_scale;
592 if (p_meta->reconLumaSize)
593 {
594 uint32_t luma_size = (bit_depth == 8) ? p_meta->reconLumaSize : p_meta->reconLumaSize * 2;
595 luma_mem_temp = (uint8_t *)malloc(luma_size);
596 memset(luma_mem_temp, 0x00, luma_size);
597 }
598 if (p_meta->reconChromaSize)
599 {
600 uint32_t ch_size = (bit_depth == 8) ? p_meta->reconChromaSize : p_meta->reconChromaSize * 2;
601 ch_mem_temp = (uint8_t *)malloc(ch_size);
602 memset(ch_mem_temp, 0x00, ch_size);
603 }
607 if (p_meta->reconLumaSize != 0)
608 {
609 SwapSWBytes(luma_mem, lum_sz);
610 SwapSW16((uint16_t *)luma_mem, lum_sz);
611 SwapSW32((uint32_t *)luma_mem, lum_sz);
612 SwapSW64((uint64_t *)luma_mem, lum_sz);
613 trace_recon_tile2raster_y (fout_raster, luma_mem, width, height,
614 2 * p_meta->frameCropLeftOffset, 2 * p_meta->frameCropTopOffset,
615 p_meta->reconLumaWidth, bit_depth, luma_mem_temp);
616 ni_log2(p_ctx, NI_LOG_DEBUG, "lum_sz %d reconLumaSize %d width %d reconLumaWidth %d\n",
617 lum_sz, p_meta->reconLumaSize, width, p_meta->reconLumaWidth);
618 // fflush(fout_raster);
619 }
620
621 if (p_meta->reconChromaSize != 0)
622 {
623 SwapSWBytes(ch_mem, chr_sz);
624 SwapSW16((uint16_t *)ch_mem, chr_sz);
625 SwapSW32((uint32_t *)ch_mem, chr_sz);
626 SwapSW64((uint64_t *)ch_mem, chr_sz);
627 trace_recon_tile2raster_uv(fout_raster, ch_mem, width / 2, height / 2,
629 p_meta->reconChromaWidth, bit_depth, ch_mem_temp);
630 ni_log2(p_ctx, NI_LOG_DEBUG, "chr_sz %d reconChromaSize %d reconChromaWidth %d\n",
631 chr_sz, p_meta->reconChromaSize, p_meta->reconChromaWidth);
632 // fflush(fout_raster);
633 }
634
635 // fwrite((uint8_t *)p_packet->p_data + sizeof(ni_metadata_enc_bstream_t) + (p_packet->data_len - p_meta->reconLumaSize - p_meta->reconChromaSize),
636 // p_meta->reconLumaSize + p_meta->reconChromaSize, 1, fout_tile);
637
641 if (((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode < 3)
642 {
643 do
644 {
645 int max;
646 double noise_y = 0.0, noise_u = 0.0, noise_v = 0.0, noise_yuv = 0.0;
647 double power_y = 0.0, power_u = 0.0, power_v = 0.0, power_yuv = 0.0;
648 double psnr_y = 0.0, psnr_u = 0.0, psnr_v = 0.0, psnr_yuv = 0.0;
649
651 // FILE *f_out_raster = (FILE *)fopen(dump_file_raster, "rb");
652 // fread(luma_mem_temp, width * height , 1, f_out_raster);
653 // fread(ch_mem_temp, width * height / 2, 1, f_out_raster);
654 // fflush(f_out_raster);
655 // fclose(f_out_raster);
656
657 max = (1 << 8) - 1;
658 power_y = 1.0 * max * max * width * height;
659 power_u = power_y / 4.0;
660 power_v = power_y / 4.0;
661 power_yuv = power_y * 3.0 / 2.0;
662
663 uint8_t *p_y_src_buf = NULL;
664 uint8_t *p_u_src_buf = NULL;
665 uint8_t *p_v_src_buf = NULL;
666 for (int i = 0; i < 120; i++)
667 {
668 if (p_ctx->input_frame_fifo[i].p_input_buffer != NULL &&
669 p_ctx->input_frame_fifo[i].pts == p_meta->frame_tstamp)
670 {
671 p_y_src_buf = p_ctx->input_frame_fifo[i].p_input_buffer;
672 p_u_src_buf = p_y_src_buf + p_ctx->input_frame_fifo[i].video_width * p_ctx->input_frame_fifo[i].video_height;
673 p_v_src_buf = p_u_src_buf + (p_ctx->input_frame_fifo[i].video_width / 2) * (p_ctx->input_frame_fifo[i].video_height / 2);
674
675 p_ctx->input_frame_fifo[i].usable = 1;
676 ni_log2(p_ctx, NI_LOG_DEBUG, "%s %d i %d pkt_num %ld frame_num %ld frame_tstamp %lld\n",
677 __FUNCTION__, __LINE__, i, p_ctx->pkt_num, p_ctx->frame_num, p_meta->frame_tstamp);
678 break;
679 }
680 }
681 if (p_y_src_buf != NULL)
682 {
683 if (p_meta->reconLumaSize != 0)
684 {
685 noise_y = calc_noise(p_y_src_buf, luma_mem_temp, width * height);
686 }
687 else if (p_meta->ui16psnr_y != 0)
688 {
689 noise_y = power_y / pow(10, p_ctx->psnr_y / 10); // This is used for calculation noise_yuv for psnr_yuv
690 }
691
692 if (p_meta->reconChromaSize != 0)
693 {
694 noise_u = calc_noise(p_u_src_buf, ch_mem_temp, (width / 2) * (height / 2));
695 noise_v = calc_noise(p_v_src_buf, ch_mem_temp + (width / 2) * (height / 2), (width / 2) * (height / 2));
696 }
697 noise_yuv = noise_y + noise_u + noise_v;
698
699 //This is for the case when encoding some very simple picture
700 //this case the quality is very good. sometimes the noise_y may be zero
701 noise_y = noise_y < 1 ? 1 : noise_y;
702 noise_u = noise_u < 1 ? 1 : noise_u;
703 noise_v = noise_v < 1 ? 1 : noise_v;
704 noise_yuv = noise_yuv < 1 ? 1 : noise_yuv;
705
706 if (p_meta->reconLumaSize != 0)
707 {
708 psnr_y = 10 * log10(power_y / noise_y);
709 }
710 else if (p_meta->ui16psnr_y != 0)
711 {
712 psnr_y = p_ctx->psnr_y;
713 }
714
715 if (p_meta->reconChromaSize != 0)
716 {
717 psnr_u = 10 * log10(power_u / noise_u);
718 psnr_v = 10 * log10(power_v / noise_v);
719 }
720 psnr_yuv = 10 * log10(power_yuv / noise_yuv);
721 p_ctx->psnr_y = p_packet->psnr_y = psnr_y;
722 p_ctx->psnr_u = p_packet->psnr_u = psnr_u;
723 p_ctx->psnr_v = p_packet->psnr_v = psnr_v;
724 p_ctx->average_psnr = p_packet->average_psnr = psnr_yuv;
725 }
726 } while(0);
727 }
728 else
729 {
730 // get recontructed frame here
731 // int h = 0;
732 // luma
733 // for (h = 0; h < height; h++)
734 // {
735 // fwrite(luma_mem_temp + (width * h), 1, width, f_out);
736 // }
737 //chroma
738 // for (h = 0; h < height; h++)
739 // {
740 // fwrite(ch_mem_temp + ((width / 2) * h), 1, width / 2, f_out);
741 // }
742 // fclose(f_out);
743 }
744
745 if (luma_mem_temp)
746 {
747 free(luma_mem_temp);
748 luma_mem_temp = NULL;
749 }
750 if (ch_mem_temp)
751 {
752 free(ch_mem_temp);
753 ch_mem_temp = NULL;
754 }
755 // fflush(fout_tile);
756 // fclose(fout_tile);
757 // fflush(fout_raster);
758 // fclose(fout_raster);
759 //}
760 }
761
762 if(p_meta->reconChromaSize == 0)
763 {
764 p_ctx->psnr_u = p_ctx->psnr_v = 0;
765 p_ctx->average_psnr = p_ctx->psnr_y;
766 }
767 if (p_meta->reconLumaSize == 0 && p_meta->ui16psnr_y == 0)
768 {
769 p_ctx->psnr_y = 0;
770 p_ctx->average_psnr = (p_ctx->psnr_u + p_ctx->psnr_v) / 2;
771 }
772
773
774 ni_log2(p_ctx, NI_LOG_DEBUG, "pkt_num %d psnr_y %.4f psnr_u %.4f psnr_v %.4f psnr_yuv %.4f reconLumaWidth %d width %d height %d reconLumaSize 0x%x reconChromaSize 0x%x\n",
775 p_ctx->pkt_num, p_ctx->psnr_y, p_ctx->psnr_u, p_ctx->psnr_v, p_ctx->average_psnr, p_meta->reconLumaWidth,p_ctx->actual_video_width, p_ctx->active_video_height, p_meta->reconLumaSize, p_meta->reconChromaSize);
776
777 p_packet->data_len -= p_meta->reconLumaSize + p_meta->reconChromaSize;
778}
779
780/* Macro to read 2 consecutive bytes from buffer starting at byte_offset and combine them into a uint32_t (little-endian) */
781#define READ_U32_FROM_BUF_2BYTES(buf, byte_offset) \
782 ((uint32_t)(buf)[(byte_offset)] | \
783 ((uint32_t)(buf)[(byte_offset)+1] << 8))
784
785/* Macro to read 4 consecutive bytes from buffer starting at byte_offset and combine them into a uint32_t (little-endian) */
786#define READ_U32_FROM_BUF(buf, byte_offset) \
787 ((uint32_t)(buf)[(byte_offset)] | \
788 ((uint32_t)(buf)[(byte_offset)+1] << 8) | \
789 ((uint32_t)(buf)[(byte_offset)+2] << 16) | \
790 ((uint32_t)(buf)[(byte_offset)+3] << 24))
791
792static void parse_cu_info(ni_session_context_t *p_ctx, uint8_t *cuInfoBuf, ni_encoder_cu_info *pEncCuInfo)
793{
794 uint32_t data;
795
796 if (!p_ctx || !cuInfoBuf || !pEncCuInfo)
797 {
798 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n",
799 __func__);
800 return;
801 }
802
803 // AVC
805 {
806 pEncCuInfo->cuSize = 16;
807 pEncCuInfo->cuMode = (cuInfoBuf[AVC_MB_MODE_BYTE_OFFSET] >> AVC_MB_MODE_BIT_POSITION) & ((1 << AVC_MB_MODE_BITS) - 1);
808 data = READ_U32_FROM_BUF(cuInfoBuf, AVC_RDCOST_BYTE_OFFSET);
809 pEncCuInfo->cost = (data >> AVC_RDCOST_BIT_POSITION) & ((1 << AVC_RDCOST_BITS) - 1);
810 if (pEncCuInfo->cuMode == 1) // intra
812 else
814 }
815 // HEVC & AV1
816 else
817 {
818 uint8_t cuSizeId = ((cuInfoBuf[CU_SIZE_BYTE_OFFSET] >> CU_SIZE_BIT_POSITION) & ((1 << CU_SIZE_BITS) - 1));
819 pEncCuInfo->cuSize = 8 * (1 << (cuSizeId + 3));
820 pEncCuInfo->cuMode = (cuInfoBuf[CU_MODE_BYTE_OFFSET] >> CU_MODE_BIT_POSITION) & ((1 << CU_MODE_BITS) - 1);
821 data = READ_U32_FROM_BUF(cuInfoBuf, RDCOST_BYTE_OFFSET);
822 pEncCuInfo->cost = (data >> RDCOST_BIT_POSITION) & ((1 << RDCOST_BITS) - 1);
823 if (pEncCuInfo->cuMode == 1) // intra
825 else
827 }
828
829 // COMMON
831 pEncCuInfo->costOfOtherMode = (data >> RDCOST_OTHER_BIT_POSITION) & ((1 << RDCOST_OTHER_BITS) - 1);
832 data = READ_U32_FROM_BUF(cuInfoBuf, INTRACOST_BYTE_OFFSET);
833 pEncCuInfo->costIntraSatd = (data >> INTRACOST_BIT_POSITION) & ((1 << INTRACOST_BITS) - 1);
834 data = READ_U32_FROM_BUF(cuInfoBuf, INTERCOST_BYTE_OFFSET);
835 pEncCuInfo->costInterSatd = (data >> INTERCOST_BIT_POSITION) & ((1 << INTERCOST_BITS) - 1);
836 data = READ_U32_FROM_BUF_2BYTES(cuInfoBuf, QP_BYTE_OFFSET);
837 pEncCuInfo->qp = (data >> QP_BIT_POSITION) & ((1 << QP_BITS) - 1);
838}
839
840
841static void get_bitstream_features_from_cu_info(ni_session_context_t *p_ctx, ni_packet_t *p_packet)
842{
843 if (!p_ctx || !p_packet)
844 {
845 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n",
846 __func__);
847 return;
848 }
849
851 if (p_meta->cuInfoSize != 0)
852 {
853 // bitstream features related parameters
854 uint8_t max_qp = 0;
855 int total_cu_count = 0;
856 int analyzed_mbs = 0; // intra 16x16, intra 8x8, intra 4x4 and inter blocks
857 int num_intra_block_blocks = 0; // intra 4x4 and 8x8 blocks (counted in 4x4)
858 int num_intra_plane_blocks = 0; // intra 16x16 blocks (counted in 4x4)
859 uint64_t qp_sum = 0;
860 uint64_t inter_pred_L0_qp_sum = 0;
861 uint64_t intra_plane_qp_sum = 0;
862 uint64_t intra_block_qp_sum = 0;
863 int inter_pred_L0_count = 0;
864 //int inter_pred_L1_count = 0;
865 //int inter_pred_BI_count = 0;
866 ni_bitstream_features_t *bitstream_features = &p_packet->bitstream_features;
867
868 // CU info related parameters
869 ni_encoder_cu_info cuInfo = {0};
870 uint8_t *ctuOffset = (uint8_t *)p_packet->p_data + p_packet->data_len - p_meta->cuInfoSize;
871 uint8_t *cuData = ctuOffset + p_meta->cuInfoTableSize + p_meta->aqInfoSize;
872 uint32_t *ctuTable = (uint32_t *)ctuOffset;
873 uint8_t *cuInfoBuf;
874 int width = p_ctx->actual_video_width;
875 int height = p_ctx->active_video_height;
876 int ctu_per_row;
877 int ctu_per_column;
878 int iCtuX, iCtuY, nCu, iCu;
879 int iCtu = 0;
880
881 // AVC
883 {
884 ctu_per_row = (width + 16 - 1) / 16;
885 ctu_per_column = (height + 16 - 1) / 16;
886 }
887 // HEVC & AV1
888 else
889 {
890 ctu_per_row = (width + 64 - 1) / 64;
891 ctu_per_column = (height + 64 - 1) / 64;
892 }
893
894 // check encoding pass CU info
895 for (iCtuY = 0; iCtuY < ctu_per_column; iCtuY++)
896 {
897 for (iCtuX = 0; iCtuX < ctu_per_row; iCtuX++)
898 {
899 // get number of CUs in CTU
901 {
902 nCu = 1;
903 // set CU info buffer pointer to this MB
904 cuInfoBuf = cuData + iCtu * CU_INFO_OUTPUT_SIZE_V1;
905 }
906 else
907 {
908 nCu = ctuTable[iCtu];
909 if (iCtu)
910 nCu -= ctuTable[iCtu - 1];
911 // set CU info buffer pointer to this CTU
912 cuInfoBuf = cuData + (iCtu ? ctuTable[iCtu - 1] : 0) * CU_INFO_OUTPUT_SIZE_V1;
913 }
914
915 // check each inter CU's MV
916 for (iCu = 0; iCu < nCu; iCu++)
917 {
918 parse_cu_info(p_ctx, cuInfoBuf, &cuInfo);
919
920 total_cu_count++;
921 qp_sum += cuInfo.qp;
922 max_qp = cuInfo.qp > max_qp ? cuInfo.qp : max_qp;
923 //ni_log2(p_ctx, NI_LOG_TRACE, "mb %d (%d, %d) mb_qp %u\n", iCtuY * ctu_per_row + iCtuX, iCtuX, iCtuY, cuInfo.qp);
924
925 if (cuInfo.cuMode == 1) // intra
926 {
927 if (cuInfo.intraPartMode == 0) // Intra_2Nx2N (or 16x16 for AVC)
928 {
929 analyzed_mbs++;
930 num_intra_plane_blocks += (cuInfo.cuSize / 4) * (cuInfo.cuSize / 4);
931 intra_plane_qp_sum += 16ULL * cuInfo.qp;
932 }
933 else // Intra_NxN (or 8x8, 4x4 for AVC)
934 {
935 analyzed_mbs += 16;
936 num_intra_block_blocks += (cuInfo.cuSize / 4) * (cuInfo.cuSize / 4);
937 intra_block_qp_sum += 16ULL * cuInfo.qp;
938 }
939 //ni_log2(p_ctx, NI_LOG_TRACE, "pkt_num %d cu %d cost %d costOfOtherMode %d costIntraSatd %d costInterSatd %d intraPartMode %d analyzed_mbs %d\n",
940 // p_ctx->pkt_num, total_cu_count, cuInfo.cost, cuInfo.costOfOtherMode, cuInfo.costIntraSatd, cuInfo.costInterSatd, cuInfo.intraPartMode, analyzed_mbs);
941 }
942 else // inter
943 {
944 analyzed_mbs++;
945 if (cuInfo.interPredIdc == 0) // Inter_L0
946 {
947 inter_pred_L0_count += 16;
948 inter_pred_L0_qp_sum += 16ULL * cuInfo.qp;
949 }
950 else if (cuInfo.interPredIdc == 1) // Inter_L1
951 {
952 // backward prediction blocks not stored in bitstream_features
953 //inter_pred_L1_count += 16;
954 }
955 else // Inter_BI
956 {
957 // bi-prediction blocks not stored in bitstream_features
958 //inter_pred_BI_count += 16;
959 if (p_ctx->p_session_config)
960 {
962 int32_t gop_preset_index = api_param->cfg_enc_params.gop_preset_index;
963 // for low delay gop patterns, bi-prediction blocks are also forward prediction blocks
964 if (gop_preset_index == 3 || gop_preset_index == 7)
965 {
966 inter_pred_L0_count += 16;
967 inter_pred_L0_qp_sum += 16ULL * cuInfo.qp;
968 }
969 }
970 else
971 {
972 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_session_config is null!\n",
973 __func__);
974 }
975 }
976 }
977
978 cuInfoBuf+=CU_INFO_OUTPUT_SIZE_V1;
979 }
980 // move forward CU info offset
981 iCtu++;
982 }
983 }
984
985 bitstream_features->average_qp = (float)qp_sum / total_cu_count;
986 bitstream_features->initial_qp = p_meta->ppsInitQp;
987 bitstream_features->max_qp = max_qp;
988 bitstream_features->avg_forward_pred_block_qp = inter_pred_L0_count > 0 ? (float)inter_pred_L0_qp_sum / inter_pred_L0_count : max_qp;
989 bitstream_features->analyzed_mbs = analyzed_mbs;
990 bitstream_features->avg_intra_block_qp = num_intra_block_blocks > 0 ? (float)intra_block_qp_sum / num_intra_block_blocks : max_qp;
991 bitstream_features->avg_intra_plane_qp = num_intra_plane_blocks > 0 ? (float)intra_plane_qp_sum / num_intra_plane_blocks : max_qp;
992 bitstream_features->num_intra_block_blocks = num_intra_block_blocks;
993 bitstream_features->num_intra_plane_blocks = num_intra_plane_blocks;
994 bitstream_features->num_skip_blocks = p_meta->skipCu8Num * 4;
995 bitstream_features->num_forward_pred_blocks = inter_pred_L0_count - bitstream_features->num_skip_blocks;
996 //ni_log2(p_ctx, NI_LOG_TRACE, "total_qp %llu mb_cnt %d av_qp %.2f\n",
997 // qp_sum, total_cu_count, p_packet->average_qp);
998 }
999}
1000
1001// Check for critical failures.
1002// Invalid parameters or resource busy do not account for failures that cause error count to be incremented so they can be retried indefinitely
1003static ni_retcode_t check_err_rc(
1004 ni_session_context_t* ctx, ni_retcode_t rc, ni_session_statistic_t *stat_full, int opcode, uint32_t type, int hw_id, uint32_t *inst_id, int opt, const char* func, int line)
1005{
1006 ni_retcode_t retval = rc;
1007 ni_session_stats_t stat = {0};
1008 uint16_t ui16ErrorCount = 0;
1009 uint32_t ui32LastErrorStatus = 0;
1010
1011 if(opt == OPT_1 || opt == OPT_3)
1012 {
1013 retval = ni_query_session_stats(ctx, type, &stat, rc, opcode);
1014 ui16ErrorCount = stat.ui16ErrorCount;
1015 ui32LastErrorStatus = stat.ui32LastErrorStatus;
1016 }
1017
1018 if (retval != NI_RETCODE_SUCCESS)
1019 {
1020 ni_log2(ctx, NI_LOG_ERROR, "Query for statistics failed with %d!\n", retval);
1021#ifdef PRINT_FW_LOGS
1022 ni_device_get_and_print_firmware_logs(ctx);
1023#endif
1024 return NI_RETCODE_FAILURE;
1025 }
1026
1027 if(opt == OPT_1)
1028 {
1029 retval = ni_nvme_check_error_code(stat.ui32LastTransactionCompletionStatus, opcode, type, hw_id, inst_id);
1030
1031 if(!retval)
1032 retval = ni_nvme_check_error_code(ui32LastErrorStatus, opcode, type, hw_id, inst_id);
1033 }
1034 else if(opt == OPT_2){
1035 if(!stat_full){
1036 ni_log2(ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n", __func__);
1037#ifdef PRINT_FW_LOGS
1038 ni_device_get_and_print_firmware_logs(ctx);
1039#endif
1041 }
1042 retval = ni_nvme_check_error_code(stat_full->ui32LastTransactionCompletionStatus, opcode, type, hw_id, inst_id);
1043 ui16ErrorCount = stat_full->ui16ErrorCount;
1044 ui32LastErrorStatus = stat_full->ui32LastErrorStatus;
1045 /* re-query error status for transactionId 0xFFFF */
1046 if(stat_full->ui32LastErrorTransactionId == 0xFFFF &&
1047 ui16ErrorCount > 0 && !retval &&
1048 type == NI_DEVICE_TYPE_DECODER)
1049 {
1050 retval = ni_nvme_check_error_code(ui32LastErrorStatus, opcode, type, hw_id, inst_id);
1051 }
1052 }
1053 else if(opt == OPT_3)
1054 {
1055 retval = ni_nvme_check_error_code(stat.ui32LastTransactionCompletionStatus, opcode, type, hw_id, inst_id);
1056 }
1057
1058 if (retval)
1059 {
1060 ni_log2(ctx,
1062 "Persistent failures detected, %s() line-%d: session_no 0x%x "
1063 "sess_err_count %u inst_err_no %u\n",
1064 func, line, *(inst_id), ui16ErrorCount,
1065 ui32LastErrorStatus);
1066#ifdef PRINT_FW_LOGS
1067 ni_device_get_and_print_firmware_logs(ctx);
1068#endif
1069#ifdef XCODER_SELF_KILL_ERR
1070 if(opt != OPT_3)
1071 {
1072 kill(getpid(), SIGTERM);
1073 }
1074#endif
1075 }
1076
1077 return retval;
1078}
1079
1080//Following macros will only check for critical failures.
1081//After the macro runs, rc should contain the status of the last command sent
1082//For non-critical failures, it is assumed in the code that eventually after enough retries, a command will succeed.
1083//Invalid parameters or resource busy do not account for failures that cause error count to be incremented so they can be retried indefinitely
1084#define CHECK_ERR_RC(ctx, rc, info, opcode, type, hw_id, inst_id, opt) \
1085 { \
1086 (rc) = check_err_rc(ctx, rc, info, opcode, type, hw_id, inst_id, opt, __func__, __LINE__); \
1087 if((rc) && ((opt) != OPT_3)) LRETURN; \
1088 }
1089
1090#define CHECK_VPU_RECOVERY(ret) \
1091 { \
1092 if (NI_RETCODE_NVME_SC_VPU_RECOVERY == (ret)) \
1093 { \
1094 ni_log(NI_LOG_ERROR, "Error, vpu reset.\n"); \
1095 (ret) = NI_RETCODE_ERROR_VPU_RECOVERY; \
1096 LRETURN; \
1097 } \
1098 }
1099
1100// ctx->decoder_low_delay is used as condition wait timeout for both decoder
1101// and encoder send/recv multi-thread in low delay mode.
1102static void low_delay_wait(ni_session_context_t* p_ctx)
1103{
1104 const char *name = p_ctx->device_type == NI_DEVICE_TYPE_DECODER ? \
1105 "decoder" : "encoder";
1106 if (p_ctx->async_mode && p_ctx->decoder_low_delay > 0)
1107 {
1108 int ret;
1109 uint64_t abs_time_ns;
1110 struct timespec ts;
1111
1112 ni_log2(p_ctx, NI_LOG_DEBUG, "%s waiting for %s recv thread\n", __FUNCTION__, name);
1113
1114 abs_time_ns = ni_gettime_ns();
1115 abs_time_ns += p_ctx->decoder_low_delay * 1000000LL;
1116 ts.tv_sec = abs_time_ns / 1000000000LL;
1117 ts.tv_nsec = abs_time_ns % 1000000000LL;
1118
1120 while (p_ctx->low_delay_sync_flag)
1121 {
1122 // In case of dead lock on waiting for notification from recv thread.
1125 &p_ctx->low_delay_sync_mutex, &ts);
1127 if (ret == ETIMEDOUT)
1128 {
1129 p_ctx->low_delay_sync_flag = 0;
1130 }
1131 }
1133 }
1134}
1135
1136static void low_delay_signal(ni_session_context_t* p_ctx)
1137{
1138 const char *name = p_ctx->device_type == NI_DEVICE_TYPE_DECODER ? \
1139 "decoder" : "encoder";
1140 if (p_ctx->async_mode && p_ctx->decoder_low_delay > 0)
1141 {
1142 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: wake up %s send thread\n", __FUNCTION__, name);
1144 p_ctx->low_delay_sync_flag = 0;
1147 }
1148}
1149
1150static void query_sleep(ni_session_context_t* p_ctx)
1151{
1152 if (p_ctx->async_mode)
1153 {
1154 // To avoid IO spam on NP core from queries and high volumens on latency.
1158 }
1159}
1160
1161// create folder bearing the card name (nvmeX) if not existing
1162// start working inside this folder: nvmeX
1163// find the earliest saved and/or non-existing stream folder and use it as
1164// the pkt saving destination; at most 128 such folders to be checked/created;
1165// folder name is in the format of: streamY, where Y is [1, 128]
1166static void decoder_dump_dir_open(ni_session_context_t *p_ctx)
1167{
1168#ifdef _WIN32
1169#elif __linux__ || __APPLE__
1170 FILE *fp = NULL;
1171 char dir_name[128] = {0};
1172 char file_name[512] = {0};
1173 ni_device_context_t *p_device_context;
1174 DIR *dir;
1175 struct dirent *stream_folder;
1176 int curr_stream_idx = 0;
1177 int earliest_stream_idx = 0;
1178 int max_exist_idx = 0;
1179 time_t earliest_time = 0;
1180 struct stat file_stat;
1181
1182 p_device_context =
1184 if (!p_device_context)
1185 {
1186 ni_log2(p_ctx, NI_LOG_ERROR, "Error retrieve device context for decoder guid %d\n",
1187 p_ctx->hw_id);
1188 return;
1189 }
1190
1191 flock(p_device_context->lock, LOCK_EX);
1192
1193 ni_strcpy(dir_name, sizeof(dir_name), &p_ctx->dev_xcoder_name[5]);
1194 if (0 != access(dir_name, F_OK))
1195 {
1196 if (0 != mkdir(dir_name, S_IRWXU | S_IRWXG | S_IRWXO))
1197 {
1198 ni_log2(p_ctx, NI_LOG_ERROR, "Error create folder %s, errno %d\n", dir_name,
1199 NI_ERRNO);
1200 } else
1201 {
1202 ni_log2(p_ctx, NI_LOG_DEBUG, "Created pkt folder for: %s\n", dir_name);
1203 }
1204 }
1205
1206 if (NULL == (dir = opendir(dir_name)))
1207 {
1208 ni_log2(p_ctx, NI_LOG_ERROR, "Error %d: failed to open directory %s\n",
1209 NI_ERRNO, dir_name);
1210 } else
1211 {
1212 // have a quick first pass of streamY folders, and if existing Y < 128,
1213 // create a new folder Y+1 directly without checking existing ones'
1214 // content
1215 while ((stream_folder = readdir(dir)))
1216 {
1217 if (!strncmp(stream_folder->d_name, "stream", strlen("stream")))
1218 {
1219 curr_stream_idx =
1220 atoi(&(stream_folder->d_name[strlen("stream")]));
1221 if (curr_stream_idx > 0)
1222 {
1223 if (curr_stream_idx > max_exist_idx)
1224 {
1225 max_exist_idx = curr_stream_idx;
1226 }
1227 if (NI_MAX_CONTEXTS_PER_HW_INSTANCE == curr_stream_idx)
1228 {
1229 break;
1230 }
1231 }
1232 }
1233 }
1234
1235 // if less than 128 streams created then create a new one, otherwise have
1236 // to pick the stream folder that has the earliest modified file which
1237 // is most likely done by finished session.
1238 if (max_exist_idx < NI_MAX_CONTEXTS_PER_HW_INSTANCE)
1239 {
1240 curr_stream_idx = max_exist_idx + 1;
1241 } else
1242 {
1243 rewinddir(dir);
1244 while ((stream_folder = readdir(dir)))
1245 {
1246 // go through each of these streamY folders and get modified
1247 // time of the first pkt-* file to simplify the searching
1248 if (!strncmp(stream_folder->d_name, "stream", strlen("stream")))
1249 {
1250 snprintf(file_name, sizeof(file_name), "%s/%s/pkt-0001.bin",
1251 dir_name, stream_folder->d_name);
1252
1253 curr_stream_idx =
1254 atoi(&(stream_folder->d_name[strlen("stream")]));
1255
1256 if (curr_stream_idx > 0 && 0 == access(file_name, F_OK))
1257 {
1258 // just take pkt-0001 file timestamp to simplify search
1259 if (stat(file_name, &file_stat))
1260 {
1261 ni_log2(p_ctx, NI_LOG_ERROR, "Error %d: failed to stat file %s\n",
1262 NI_ERRNO,
1263 file_name);
1264 } else
1265 {
1266 if (0 == earliest_stream_idx ||
1267 file_stat.st_mtime < earliest_time)
1268 {
1269 earliest_stream_idx = curr_stream_idx;
1270 earliest_time = file_stat.st_mtime;
1271 }
1272 }
1273 } // check first file in streamX
1274 } // go through each streamX folder
1275 } // read all files in nvmeY
1276
1277 curr_stream_idx = earliest_stream_idx;
1278
1279 // set the access/modified time of chosen pkt file to NOW so its
1280 // stream folder won't be taken by other sessions.
1281 snprintf(file_name, sizeof(file_name), "%s/stream%03d/pkt-0001.bin",
1282 dir_name, curr_stream_idx);
1283 if (utime(file_name, NULL))
1284 {
1285 ni_log2(p_ctx, NI_LOG_ERROR, "Error utime %s\n", file_name);
1286 }
1287 } // 128 streams in nvmeY already
1288 closedir(dir);
1289 }
1290
1291 snprintf(p_ctx->stream_dir_name, sizeof(p_ctx->stream_dir_name),
1292 "%s/stream%03d", dir_name, curr_stream_idx);
1293
1294 if (0 != access(p_ctx->stream_dir_name, F_OK))
1295 {
1296 if (0 != mkdir(p_ctx->stream_dir_name, S_IRWXU | S_IRWXG | S_IRWXO))
1297 {
1298 ni_log2(p_ctx, NI_LOG_ERROR, "Error create stream folder %s, errno %d\n",
1299 p_ctx->stream_dir_name, NI_ERRNO);
1300 } else
1301 {
1302 ni_log2(p_ctx, NI_LOG_DEBUG, "Created stream sub folder: %s\n",
1303 p_ctx->stream_dir_name);
1304 }
1305 } else
1306 {
1307 ni_log2(p_ctx, NI_LOG_DEBUG, "Reusing stream sub folder: %s\n",
1308 p_ctx->stream_dir_name);
1309 }
1310
1311 flock(p_device_context->lock, LOCK_UN);
1312 ni_rsrc_free_device_context(p_device_context);
1313
1314 snprintf(file_name, sizeof(file_name), "%s/process_session_id.txt",
1315 p_ctx->stream_dir_name);
1316
1317 ni_fopen(&fp, file_name, "wb");
1318 if (fp)
1319 {
1320 char number[64] = {'\0'};
1321 ni_log2(p_ctx, NI_LOG_DEBUG, "Decoder pkt dump log created: %s\n", file_name);
1322 snprintf(number, sizeof(number), "proc id: %ld\nsession id: %u\n",
1323 (long)getpid(), p_ctx->session_id);
1324 fwrite(number, strlen(number), 1, fp);
1325 fclose(fp);
1326 } else
1327 {
1328 ni_log2(p_ctx, NI_LOG_ERROR, "Error create decoder pkt dump log: %s\n", file_name);
1329 }
1330#endif
1331}
1332
1333#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OPEN_HARMONY__) && !defined(_ANDROID)
1334#define MAX_BDF_LEN 16
1335
1336// dev_name pattern: nvmeXnY
1337// pci_addr pattern: dddd:bb:dd.f
1338static int find_pci_address(const char *dev_name, char *pci_addr) {
1339 char sys_block_path[256];
1340
1341 snprintf(sys_block_path, sizeof(sys_block_path), "/sys/class/block/%s/device", dev_name);
1342
1343 char *real_sysfs_path = realpath(sys_block_path, NULL);
1344 if (!real_sysfs_path) {
1345 perror("realpath failed");
1346 return -1;
1347 }
1348
1349 // Walk backward in the resolved path to find a segment that matches PCI BDF format
1350 char *p = real_sysfs_path + strlen(real_sysfs_path);
1351
1352 while (p > real_sysfs_path) {
1353 p = strrchr(real_sysfs_path, '/');
1354 if (!p) break;
1355
1356 char segment[MAX_BDF_LEN];
1357 ni_strncpy(segment, MAX_BDF_LEN, p + 1, (MAX_BDF_LEN-1));
1358 segment[MAX_BDF_LEN - 1] = '\0';
1359
1360 unsigned domain, bus, dev, func;
1361 if (sscanf(segment, "%x:%x:%x.%x", &domain, &bus, &dev, &func) == 4) {
1362 ni_strncpy(pci_addr, MAX_BDF_LEN, segment, MAX_BDF_LEN - 1);
1363 pci_addr[MAX_BDF_LEN - 1] = '\0';
1364 free(real_sysfs_path);
1365 return 0;
1366 }
1367
1368 *p = '\0'; // truncate path to move to the previous segment
1369 }
1370
1371 free(real_sysfs_path);
1372 return -1;
1373}
1374
1375// open netint p2p driver and fill the pcie address to p_ctx
1376static ni_retcode_t p2p_fill_pcie_address(ni_session_context_t *p_ctx)
1377{
1378#if defined(_WIN32) || defined(__APPLE__) || defined(__OPEN_HARMONY__)
1379 (void)p_ctx;
1380 return NI_RETCODE_FAILURE;
1381#else
1382 int ret = 0;
1383 char pci_addr[16];
1384 struct stat bstat;
1385 char *p_dev;
1386 char *dom, *bus, *dev, *fnc;
1387#ifdef _ANDROID
1388 char syspath[256];
1389 FILE *fp;
1390#endif
1391
1392 if(!p_ctx)
1393 {
1394 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() parameter is NULL\n",__func__);
1395 return NI_RETCODE_FAILURE;
1396 }
1397
1398 p_ctx->netint_fd = open("/dev/netint", O_RDWR);
1399 if (p_ctx->netint_fd < 0)
1400 {
1401 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Can't open device /dev/netint\n");
1402 return NI_RETCODE_FAILURE;
1403 }
1404
1405 p_dev = &p_ctx->dev_xcoder_name[0];
1406 if (stat(p_dev, &bstat) < 0)
1407 {
1408 ni_log2(p_ctx, NI_LOG_ERROR, "failed to get stat of file %s\n", p_dev);
1409 return NI_RETCODE_FAILURE;
1410 }
1411
1412 if ((bstat.st_mode & S_IFMT) != S_IFBLK)
1413 {
1414 ni_log2(p_ctx, NI_LOG_ERROR, "%s is not a block device\n", p_dev);
1415 return NI_RETCODE_FAILURE;
1416 }
1417
1418#ifdef _ANDROID
1419 ret = snprintf(syspath, sizeof(syspath) - 1,
1420 "/sys/block/%s/device/address",
1421 p_dev + 5);
1422 syspath[ret] = '\0';
1423
1424 FILE *fp = NULL;
1425 ni_fopen(&fp, syspath, "r");
1426 if (fp == NULL)
1427 {
1428 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read address\n");
1429 return NI_RETCODE_FAILURE;
1430 }
1431
1432 if (fgets(pci_addr, sizeof(pci_addr), fp) == NULL)
1433 {
1434 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read line from address\n");
1435 fclose(fp);
1436 return NI_RETCODE_FAILURE;
1437 }
1438
1439 fclose(fp);
1440#else
1441 ret = find_pci_address(p_dev + 5, pci_addr);
1442 if (ret != 0)
1443 {
1444 return NI_RETCODE_FAILURE;
1445 }
1446#endif
1447
1448 // pci_addr pattern: 0000:04:00.0
1449 ni_log2(p_ctx, NI_LOG_INFO, "PCI address string = %12.12s\n", pci_addr);
1450
1451 errno = 0;
1452 p_ctx->domain = strtoul(pci_addr, &dom, 16);
1453 if (errno < 0)
1454 {
1455 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read PCI domain\n");
1456 return NI_RETCODE_FAILURE;
1457 }
1458
1459 errno = 0;
1460 p_ctx->bus = strtoul(dom + 1, &bus, 16);
1461 if (errno < 0)
1462 {
1463 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read PCI bus\n");
1464 return NI_RETCODE_FAILURE;
1465 }
1466
1467 errno = 0;
1468 p_ctx->dev = strtoul(bus + 1, &dev, 16);
1469
1470 if (errno < 0)
1471 {
1472 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read PCI device\n");
1473 return NI_RETCODE_FAILURE;
1474 }
1475
1476 errno = 0;
1477 p_ctx->fn = strtoul(dev + 1, &fnc, 16);
1478
1479 if (errno < 0)
1480 {
1481 ni_log2(p_ctx, NI_LOG_ERROR, "Falied to read PCI function\n");
1482 return NI_RETCODE_FAILURE;
1483 }
1484
1485 ni_log2(p_ctx, NI_LOG_DEBUG, "PCI address parsed = %04x:%02x:%02x.%x\n",
1486 p_ctx->domain, p_ctx->bus, p_ctx->dev, p_ctx->fn);
1487
1488 return NI_RETCODE_SUCCESS;
1489#endif
1490}
1491#endif
1492
1493#if __linux__ || __APPLE__
1494#if !defined(_ANDROID) && !defined(__OPENHARMONY__)
1495#ifndef DISABLE_BACKTRACE_PRINT
1496void ni_print_backtrace() {
1497 void* callstack[128];
1498 int frames = backtrace(callstack, 128);
1499 char** strs = backtrace_symbols(callstack, frames);
1500
1501 ni_log(NI_LOG_ERROR, "Call stack:\n");
1502 for (int i = 0; i < frames; ++i) {
1503 ni_log(NI_LOG_ERROR, "%s\n", strs[i]);
1504 }
1505
1506 free(strs);
1507}
1508#endif
1509#endif
1510#endif
1511
1512/*!******************************************************************************
1513 * \brief Open a xcoder decoder instance
1514 *
1515 * \param
1516 *
1517 * \return
1518*******************************************************************************/
1520{
1522 ni_xcoder_params_t *p_param = NULL;
1523 void* p_buffer = NULL;
1524 uint32_t ui32LBA = 0;
1525 char fmt_fw_api_ver1[5], fmt_fw_api_ver2[5];
1526
1527 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
1528
1529 if (!p_ctx)
1530 {
1531 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n",
1532 __func__);
1533 retval = NI_RETCODE_INVALID_PARAM;
1534 LRETURN;
1535 }
1536
1537 if (p_ctx->p_session_config)
1538 {
1539 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
1540 ni_params_print(p_param);
1541
1542 // Select the CPU based on the NUMA node.
1543 if (p_param->enableCpuAffinity)
1544 {
1545#if defined(__linux__) && defined(XCODER_ENABLE_CPU_AFFINITY)
1546 retval = ni_set_cpu_affinity(p_ctx);
1547 if (NI_RETCODE_SUCCESS != retval)
1548 {
1549 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ni_set_cpu_affinity failed, ret=%d\n",
1550 __func__, retval);
1551 LRETURN;
1552 }
1553#else
1554 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): not support enableCpuAffinity parameter, "
1555 "enable with [./build.sh -c] on linux\n", __func__);
1556#endif
1557 }
1558 }
1559
1560 //Create the session if the create session flag is set
1561 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
1562 {
1564 p_ctx->pts_table = NULL;
1565 p_ctx->dts_queue = NULL;
1566 p_ctx->p_leftover = NULL;
1567 p_ctx->buffer_pool = NULL;
1568 p_ctx->dec_fme_buf_pool = NULL;
1569 p_ctx->prev_size = 0;
1570 p_ctx->sent_size = 0;
1571 p_ctx->status = 0;
1572 p_ctx->key_frame_type = 0;
1573 p_ctx->ready_to_close = 0;
1574 p_ctx->max_retry_fail_count[0] = p_ctx->max_retry_fail_count[1] = 0;
1575 p_ctx->rc_error_count = 0;
1576 p_ctx->frame_num = 0;
1577 p_ctx->pkt_num = 0;
1578 p_ctx->pkt_index = 0;
1579 p_ctx->session_timestamp = 0;
1580 p_ctx->is_dec_pkt_512_aligned = 0;
1581 p_ctx->p_all_zero_buf = NULL;
1582 p_ctx->last_pkt_pos = 0;
1583 p_ctx->last_frame_offset = 0;
1584 p_ctx->last_frame_dropped = 0;
1586 memset(p_ctx->pkt_custom_sei_set, 0, NI_FIFO_SZ * sizeof(ni_custom_sei_set_t *));
1587
1588 //malloc zero data buffer
1589 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
1591 {
1592 ni_log2(p_ctx, NI_LOG_ERROR,
1593 "ERROR %d: %s() alloc decoder all zero buffer failed\n",
1594 NI_ERRNO, __func__);
1596 LRETURN;
1597 }
1598 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
1599
1600 //malloc data buffer
1601 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
1602 {
1603 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
1604 NI_ERRNO, __func__);
1607 LRETURN;
1608 }
1609 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
1610
1611 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
1612 //In case we can open sesison, the session id would become valid.
1613 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
1614 (uint16_t)NI_INVALID_SESSION_ID;
1615
1616 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
1617 ui32LBA = OPEN_SESSION_CODEC(NI_DEVICE_TYPE_DECODER, ni_htonl(p_ctx->codec_format), p_ctx->hw_action);
1618 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
1619 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
1620 if (retval != NI_RETCODE_SUCCESS)
1621 {
1622 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR ni_nvme_send_read_cmd\n");
1623 LRETURN;
1624 }
1625 //Open will return a session status structure with a valid session id if it worked.
1626 //Otherwise the invalid session id set before the open command will stay
1627 p_ctx->session_id = ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
1628 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
1629 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
1630 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
1631 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
1632 {
1633 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_ctx->device_handle=0x%" PRIx64 ", "
1634 "p_ctx->hw_id=%d, p_ctx->session_id=%d\n", __func__,
1635 (int64_t)p_ctx->device_handle, p_ctx->hw_id, p_ctx->session_id);
1637 LRETURN;
1638 }
1639 ni_log2(p_ctx, NI_LOG_DEBUG, "Decoder open session ID:0x%x, timestamp:%" PRIu64 "\n",
1640 p_ctx->session_id, p_ctx->session_timestamp);
1641
1642 //Send keep alive timeout Info
1643 uint64_t keep_alive_timeout =
1644 p_ctx->keep_alive_timeout * 1000000; //send us to FW
1645 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
1646 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
1647 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
1648 keep_alive_timeout);
1650 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
1651 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
1653 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
1654 CHECK_VPU_RECOVERY(retval);
1655
1656 if (NI_RETCODE_SUCCESS != retval)
1657 {
1658 ni_log2(p_ctx, NI_LOG_ERROR,
1659 "ERROR %s(): nvme write keep_alive_timeout command "
1660 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
1661 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
1663 LRETURN;
1664 }
1665
1666 // Send SW version to FW if FW API version is >= 6.2
1668 "62") >= 0)
1669 {
1670 // Send SW version to session manager
1671 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
1672 memcpy(p_buffer, NI_XCODER_REVISION, sizeof(uint64_t));
1674 ni_fmt_fw_api_ver_str((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], &fmt_fw_api_ver2[0]);
1675 ni_log2(p_ctx, NI_LOG_DEBUG, "%s libxcoder FW API ver %s, FW FW API ver %s\n",
1676 __func__, fmt_fw_api_ver1, fmt_fw_api_ver2);
1677 ui32LBA = CONFIG_SESSION_SWVersion_W(p_ctx->session_id);
1678 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
1679 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
1680 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
1681 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
1682 CHECK_VPU_RECOVERY(retval);
1683
1684 if (NI_RETCODE_SUCCESS != retval)
1685 {
1686 ni_log2(p_ctx, NI_LOG_ERROR,
1687 "ERROR %s(): nvme write sw_version command "
1688 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
1689 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
1691 LRETURN;
1692 }
1693 }
1694
1695 //VP9 requires a scaler session to be opened internally and attached as
1696 //well
1697 if(p_ctx->codec_format == NI_CODEC_FORMAT_VP9)
1698 {
1699 ni_log2(p_ctx, NI_LOG_DEBUG, "Adding scaling session to Vp9 decoder\n");
1700 ui32LBA = OPEN_ADD_CODEC(NI_DEVICE_TYPE_SCALER, ni_htonl(NI_SCALER_OPCODE_SCALE), ni_htons(p_ctx->session_id));
1701 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
1702 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
1703
1704 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_open,
1705 p_ctx->device_type, p_ctx->hw_id,
1706 &(p_ctx->session_id), OPT_1);
1707 if (NI_RETCODE_SUCCESS != retval)
1708 {
1709 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR couldn't add vp9 scaler to decoding session\n");
1710 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s():p_ctx->device_handle=0x%" PRIx64 ", "
1711 "p_ctx->hw_id=%d, p_ctx->session_id=%d\n", __func__,
1712 (int64_t)p_ctx->device_handle,p_ctx->hw_id, p_ctx->session_id);
1713 ni_decoder_session_close(p_ctx, 0);
1714 LRETURN;
1715 }
1716 }
1717
1718 ni_log2(p_ctx, NI_LOG_DEBUG,
1719 "%s(): p_ctx->device_handle=0x%" PRIx64 ", p_ctx->hw_id=%d, "
1720 "p_ctx->session_id=%d\n",
1721 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
1722 p_ctx->session_id);
1723 }
1724
1725 //start dec config
1726 retval = ni_config_instance_set_decoder_params(p_ctx, 0);
1727 if (NI_RETCODE_SUCCESS != retval)
1728 {
1729 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: calling ni_config_instance_set_decoder_params(): p_ctx->device_handle=%" PRIx64 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n", (int64_t)p_ctx->device_handle, p_ctx->hw_id, p_ctx->session_id);
1730 //ni_decoder_session_close(p_ctx, 0); //close happens on above
1732 LRETURN;
1733 }
1734 //end dec config
1735
1736 // init for frame pts calculation
1737 p_ctx->is_first_frame = 1;
1738 p_ctx->last_pts = NI_NOPTS_VALUE;
1739 p_ctx->last_dts = NI_NOPTS_VALUE;
1740 p_ctx->last_dts_interval = 0;
1741 p_ctx->last_pts_interval = 0;
1742 p_ctx->pts_correction_last_dts = INT64_MIN;
1743 p_ctx->pts_correction_last_pts = INT64_MIN;
1744
1745 //p_ctx->p_leftover = malloc(NI_MAX_PACKET_SZ * 2);
1746 p_ctx->p_leftover = malloc(p_ctx->max_nvme_io_size * 2);
1747 if (!p_ctx->p_leftover)
1748 {
1749 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Cannot allocate leftover buffer.\n",
1750 __func__);
1752 //ni_decoder_session_close(p_ctx, 0);
1753 LRETURN;
1754 }
1755
1756 ni_timestamp_init(p_ctx, &p_ctx->pts_table, "dec_pts");
1757 ni_timestamp_init(p_ctx, &p_ctx->dts_queue, "dec_dts");
1758
1759 if (p_param && p_param->ddr_priority_mode > NI_DDR_PRIORITY_NONE)
1760 {
1761 retval = ni_device_set_ddr_configuration(p_ctx, p_param->ddr_priority_mode);
1762 if (NI_RETCODE_SUCCESS != retval)
1763 {
1764 char errmsg[NI_ERRNO_LEN] = {0};
1766 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ddr priority setting failure for %s\n",
1767 __func__, errmsg);
1768 LRETURN;
1769 }
1770 }
1771
1772 if (p_ctx->force_low_delay)
1773 {
1776 "6r3") < 0)
1777 {
1778 p_ctx->force_low_delay = false; // forceLowDelay not available for fw < 6r3
1779 ni_log2(p_ctx, NI_LOG_INFO, "Warn %s(): forceLowDelay is not available for fw < 6r3\n",
1780 __func__);
1781 }
1782 }
1783
1784 p_ctx->active_video_width = 0;
1785 p_ctx->active_video_height = 0;
1786 p_ctx->actual_video_width = 0;
1787 p_ctx->pixel_format_changed = 0;
1788
1789 ni_log2(p_ctx, NI_LOG_DEBUG,
1790 "%s(): p_ctx->device_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
1791 "p_ctx->session_id=%d\n",
1792 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
1793 p_ctx->session_id);
1794
1795 if (p_param && p_param->dec_input_params.nb_save_pkt)
1796 {
1797 decoder_dump_dir_open(p_ctx);
1798 }
1799
1800#ifdef XCODER_DUMP_DATA
1801 char dir_name[256] = {0};
1802
1803 snprintf(dir_name, sizeof(dir_name), "%ld-%u-dec-fme", (long)getpid(),
1804 p_ctx->session_id);
1805 DIR *dir = opendir(dir_name);
1806 if (!dir && ENOENT == NI_ERRNO)
1807 {
1808 mkdir(dir_name, S_IRWXU | S_IRWXG | S_IRWXO);
1809 ni_log2(p_ctx, NI_LOG_DEBUG, "Decoder frame dump dir created: %s\n", dir_name);
1810 }
1811 if(dir){
1812 closedir(dir);
1813 }
1814#endif
1815
1816END:
1817
1818 ni_aligned_free(p_buffer);
1819 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
1820
1821 return retval;
1822}
1823
1824/*!******************************************************************************
1825 * \brief send a keep alive message to firmware
1826 *
1827 * \param
1828 *
1829 * \return
1830 *******************************************************************************/
1831ni_retcode_t ni_send_session_keep_alive(uint32_t session_id, ni_device_handle_t device_handle, ni_event_handle_t event_handle, void *p_data)
1832{
1833 ni_retcode_t retval;
1834 uint32_t ui32LBA = 0;
1835
1836 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
1837 if (NI_INVALID_SESSION_ID == session_id)
1838 {
1839 ni_log(NI_LOG_ERROR, "ERROR: %s(): Invalid session ID!, return\n",
1840 __func__);
1842 LRETURN;
1843 }
1844
1845 if (NI_INVALID_DEVICE_HANDLE == device_handle)
1846 {
1847 ni_log(NI_LOG_ERROR, "ERROR: %s(): xcoder instance id < 0, return\n",
1848 __func__);
1849 retval = NI_RETCODE_INVALID_PARAM;
1850 LRETURN;
1851 }
1852
1853 ui32LBA = CONFIG_SESSION_KeepAlive_W(session_id);
1854 if (ni_nvme_send_write_cmd(device_handle, event_handle, p_data,
1855 NI_DATA_BUFFER_LEN, ui32LBA) < 0)
1856 {
1857 ni_log(NI_LOG_ERROR, "ERROR: %s(): device_handle=%" PRIx64 " , "
1858 "session_id=%d\n", __func__, (int64_t)device_handle, session_id);
1859 retval = NI_RETCODE_FAILURE;
1860 }
1861 else
1862 {
1864 "SUCCESS %s(): device_handle=%" PRIx64 " , "
1865 "session_id=%d\n", __func__, (int64_t)device_handle, session_id);
1866 retval = NI_RETCODE_SUCCESS;
1867 }
1868
1869END:
1870
1871 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
1872
1873 return retval;
1874}
1875
1876/*!******************************************************************************
1877 * \brief Send end of stream signal to the decoder
1878 *
1879 * \param
1880 *
1881 * \return
1882 *******************************************************************************/
1884{
1885 ni_retcode_t retval;
1886 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
1887 if (!p_ctx)
1888 {
1889 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
1890 __func__);
1891 retval = NI_RETCODE_INVALID_PARAM;
1892 LRETURN;
1893 }
1894
1895 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
1896 {
1897 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
1898 __func__);
1900 LRETURN;
1901 }
1902
1905 p_ctx->device_type, p_ctx->hw_id,
1906 &(p_ctx->session_id), OPT_1);
1907 CHECK_VPU_RECOVERY(retval);
1908
1909END:
1910
1911 if (NI_RETCODE_SUCCESS != retval)
1912 {
1913 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): %d, return\n", __func__, retval);
1914 }
1915
1916 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
1917
1918 return retval;
1919}
1920
1921/*!******************************************************************************
1922 * \brief Flush decoder output
1923 *
1924 * \param
1925 *
1926 * \return
1927 *******************************************************************************/
1929{
1930 ni_retcode_t retval;
1931 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
1932
1933 if (!p_ctx)
1934 {
1935 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): passed parameters are null!, return\n",
1936 __func__);
1937 retval = NI_RETCODE_INVALID_PARAM;
1938 LRETURN;
1939 }
1940
1941 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
1942 {
1943 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): xcoder instance id < 0, return\n",
1944 __func__);
1946 LRETURN;
1947 }
1948
1951 p_ctx->device_type, p_ctx->hw_id,
1952 &(p_ctx->session_id), OPT_1);
1953
1954END:
1955
1956 if (NI_RETCODE_SUCCESS != retval)
1957 {
1958 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): %d, return\n", __func__, retval);
1959 }
1960
1961 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
1962
1963 return retval;
1964}
1965
1966/*!******************************************************************************
1967 * \brief Close a xcoder decoder instance
1968 *
1969 * \param
1970 *
1971 * \return
1972 *******************************************************************************/
1974{
1976 void* p_buffer = NULL;
1977 uint32_t ui32LBA = 0;
1978 int i;
1979 ni_xcoder_params_t *p_param = NULL;
1980
1981 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
1982
1983 if (!p_ctx)
1984 {
1985 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
1986 __func__);
1988 }
1989
1991
1992 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
1993 {
1994 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): Invalid session ID, return.\n", __func__);
1995 retval = NI_RETCODE_SUCCESS;
1996 LRETURN;
1997 }
1998
1999 if (NI_CODEC_HW_ENABLE == p_ctx->hw_action)
2000 {
2001 ni_session_statistic_t sessionStatistic = {0};
2003 }
2004
2006 (char *) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rg") >= 0)
2007 {
2008 ni_log2(p_ctx, NI_LOG_INFO,
2009 "Decoder_complete_info:session_id 0x%x, total frames input:%u "
2010 "buffered: %u completed: %u output: %u dropped: %u error: %u corrupted: %u\n",
2018 } else
2019 {
2020 ni_log2(p_ctx, NI_LOG_INFO,
2021 "Decoder_complete_info:session_id 0x%x, total frames input:%u "
2022 "buffered: %u completed: %u output: %u dropped: %u error: %u\n",
2029 }
2030
2031 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
2032 {
2033 ni_log2(p_ctx, NI_LOG_ERROR, "%s: Invalid session ID, return.\n", __func__);
2034 retval = NI_RETCODE_SUCCESS;
2035 LRETURN;
2036 }
2037
2038 //malloc data buffer
2039 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
2040 {
2041 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: malloc decoder close data buffer failed\n", NI_ERRNO);
2043 LRETURN;
2044 }
2045
2046 if (p_ctx->p_session_config)
2047 {
2048 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
2050 {
2052 if (NI_RETCODE_SUCCESS != retval)
2053 {
2054 char errmsg[NI_ERRNO_LEN] = {0};
2056 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ddr priority setting failure for %s\n",
2057 __func__, errmsg);
2058 LRETURN;
2059 }
2060 }
2061 }
2062
2063 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
2064
2066
2067 int retry = 0;
2068 while (retry < NI_SESSION_CLOSE_RETRY_MAX)
2069 {
2070 ni_log2(p_ctx, NI_LOG_DEBUG,
2071 "%s(): p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
2072 "p_ctx->session_id=%d, close_mode=1\n",
2073 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
2074 p_ctx->session_id);
2075
2077 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
2078 {
2079 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): command failed!\n", __func__);
2082 break;
2083 } else
2084 {
2085 //Close should always succeed
2086 retval = NI_RETCODE_SUCCESS;
2088 break;
2089 }
2090 /*
2091 else if (*((ni_retcode_t *)p_buffer) == RETCODE_SUCCESS)
2092 {
2093 retval = NI_RETCODE_SUCCESS;
2094 p_ctx->session_id = NI_INVALID_SESSION_ID;
2095 break;
2096 }
2097 else
2098 {
2099 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): wait for close\n", __func__);
2100 ni_usleep(NI_SESSION_CLOSE_RETRY_INTERVAL_US);
2101 retval = NI_RETCODE_ERROR_NVME_CMD_FAILED;
2102 }
2103 */
2104 retry++;
2105 }
2106
2107END:
2108
2109 ni_aligned_free(p_buffer);
2111 ni_memfree(p_ctx->p_leftover);
2112
2113 if (p_ctx->pts_table)
2114 {
2115 ni_queue_free(&p_ctx->pts_table->list, p_ctx->buffer_pool);
2116 ni_memfree(p_ctx->pts_table);
2117 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_timestamp_done: success\n");
2118 }
2119
2120 if (p_ctx->dts_queue)
2121 {
2122 ni_queue_free(&p_ctx->dts_queue->list, p_ctx->buffer_pool);
2123 ni_memfree(p_ctx->dts_queue);
2124 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_timestamp_done: success\n");
2125 }
2126
2129 p_ctx->buffer_pool = NULL;
2130 p_ctx->dec_fme_buf_pool = NULL;
2131
2132 for (i = 0; i < NI_FIFO_SZ; i++)
2133 {
2134 ni_memfree(p_ctx->pkt_custom_sei_set[i]);
2135 }
2136
2137 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): CTX[Card:%" PRIx64 " / HW:%d / INST:%d]\n",
2138 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
2139 p_ctx->session_id);
2140
2141 low_delay_signal(p_ctx);
2143
2144 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
2145
2146 return retval;
2147}
2148
2149/*!******************************************************************************
2150 * \brief Send a video p_packet to decoder
2151 *
2152 * \param
2153 *
2154 * \return
2155 *******************************************************************************/
2157{
2158 uint32_t sent_size = 0;
2159 uint32_t packet_size = 0;
2160 int current_pkt_size;
2161 int retval = NI_RETCODE_SUCCESS;
2162 ni_xcoder_params_t *p_param;
2163 ni_instance_buf_info_t buf_info = { 0 };
2164 ni_session_statistic_t sessionStatistic = {0};
2165 int query_retry = 0;
2166 uint32_t ui32LBA = 0;
2167
2168 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
2169
2170 if ((!p_ctx) || (!p_packet))
2171 {
2172 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
2173 __func__);
2175 }
2176
2178
2179 if ((NI_INVALID_SESSION_ID == p_ctx->session_id))
2180 {
2181 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
2182 __func__);
2184 LRETURN;
2185 }
2186
2187 low_delay_wait(p_ctx);
2188
2189#ifdef MEASURE_LATENCY
2190 if ((p_packet->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
2191 {
2192 uint64_t abs_time_ns = ni_gettime_ns();
2194 abs_time_ns, p_packet->dts);
2195 }
2196#endif
2197
2198 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
2199 packet_size = p_packet->data_len;
2200 current_pkt_size = packet_size;
2201
2202#ifdef XCODER_311
2203 int max_retry = 200; // 20ms
2204 if (p_packet->video_width * p_packet->video_height >= NI_NUM_OF_PIXELS_1440P)
2205 {
2206 max_retry = NI_MAX_TX_RETRIES; // 100ms
2207 }
2208#endif
2209
2210 for (;;)
2211 {
2212 query_sleep(p_ctx);
2213
2214 query_retry++;
2215
2216
2218 "65") >= 0)
2219 {
2221 &sessionStatistic);
2222 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
2224 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
2225 CHECK_VPU_RECOVERY(retval);
2226
2227 buf_info.buf_avail_size = sessionStatistic.ui32WrBufAvailSize;
2228 } else
2229 {
2231 NI_DEVICE_TYPE_DECODER, &buf_info);
2232 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
2233 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
2234 CHECK_VPU_RECOVERY(retval);
2235 }
2236
2237 if (buf_info.buf_avail_size == DP_IPC_PASSTHRU)
2238 {
2239 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Bad available buffer size %u\n", __FUNCTION__, buf_info.buf_avail_size);
2240 retval = NI_RETCODE_FAILURE;
2241 LRETURN;
2242 }
2243
2245 {
2247 }
2248 if (p_ctx->biggest_bitstream_buffer_allocated < packet_size)
2249 {
2252 {
2253 // Reallocate decoder bitstream buffers to accomodate
2255 "66") >= 0)
2256 {
2257 retval = ni_config_instance_set_write_len(p_ctx,
2259 // packet buffer aligned to NI_MAX_PACKET_SZ(128k)
2260 (packet_size / NI_MAX_PACKET_SZ + 1) * NI_MAX_PACKET_SZ);
2262 p_ctx->device_type, p_ctx->hw_id,
2263 &(p_ctx->session_id), OPT_3);
2264 CHECK_VPU_RECOVERY(retval);
2265 }
2266 else
2267 {
2268 retval = ni_config_instance_set_decoder_params(p_ctx, packet_size);
2269 }
2270 if (NI_RETCODE_SUCCESS != retval)
2271 {
2272 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): failed to reallocate bitstream\n", __FUNCTION__);
2273 LRETURN;
2274 }
2276 query_retry--;
2277 continue;
2278 }
2279 }
2280
2281 if (NI_RETCODE_SUCCESS != retval ||
2282 buf_info.buf_avail_size < packet_size)
2283 {
2284 ni_log2(p_ctx, NI_LOG_TRACE,
2285 "Warning: dec write query fail rc %d or available buf size %u < "
2286 "pkt size %u , retry: %d max_retry_fail_count %d\n",
2287 retval, buf_info.buf_avail_size, packet_size, query_retry, p_ctx->max_retry_fail_count[0]);
2288#ifdef XCODER_311
2289 if (query_retry > max_retry ||
2290 (sessionStatistic.ui32RdBufAvailSize > 0 && !p_ctx->required_buf_size))
2291#else
2292 if (query_retry > NI_MAX_TX_RETRIES ||
2293 (sessionStatistic.ui32RdBufAvailSize > 0 && !p_ctx->required_buf_size))
2294#endif
2295 {
2297#ifdef XCODER_311
2298 if (query_retry > max_retry)
2299#else
2300 if (query_retry > NI_MAX_TX_RETRIES)
2301#endif
2302 {
2303 p_ctx->max_retry_fail_count[0]++;
2304 }
2305 p_ctx->required_buf_size = packet_size;
2307 LRETURN;
2308 }
2312 }
2313 else
2314 {
2315 p_ctx->max_retry_fail_count[0] = 0;
2316 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec write query success, available buf "
2317 "size %u >= pkt size %u !\n",
2318 buf_info.buf_avail_size, packet_size);
2319 break;
2320 }
2321 }
2322
2323 //Configure write size for the buffer
2325 packet_size);
2327 p_ctx->device_type, p_ctx->hw_id,
2328 &(p_ctx->session_id), OPT_1);
2329 CHECK_VPU_RECOVERY(retval);
2330 if (retval < 0)
2331 {
2332 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): config pkt size command failed\n",
2333 __func__);
2335 LRETURN;
2336 }
2337
2339
2340 //check for start of stream flag
2341 if (p_packet->start_of_stream)
2342 {
2345 p_ctx->device_type, p_ctx->hw_id,
2346 &(p_ctx->session_id), OPT_1);
2347 CHECK_VPU_RECOVERY(retval);
2348 if (NI_RETCODE_SUCCESS != retval)
2349 {
2350 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Failed to send SOS.\n", __func__);
2351 LRETURN;
2352 }
2353
2354 p_packet->start_of_stream = 0;
2355 }
2356
2357 if (p_packet->p_data)
2358 {
2359 ni_log2(p_ctx, NI_LOG_DEBUG,
2360 "%s() had data to send: packet_size=%u, "
2361 "p_packet->sent_size=%d, p_packet->data_len=%u, "
2362 "p_packet->start_of_stream=%u, p_packet->end_of_stream=%u, "
2363 "p_packet->video_width=%u, p_packet->video_height=%u\n",
2364 __func__, packet_size, p_packet->sent_size, p_packet->data_len,
2365 p_packet->start_of_stream, p_packet->end_of_stream,
2366 p_packet->video_width, p_packet->video_height);
2367
2368 uint8_t *p_data = (uint8_t *)p_packet->p_data;
2369 // Note: session status is NOT reset but tracked between send
2370 // and recv to catch and recover from a loop condition
2371 // p_ctx->status = 0;
2372
2373 if (packet_size % NI_MEM_PAGE_ALIGNMENT) //packet size, already aligned
2374 {
2375 packet_size = ( (packet_size / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
2376 }
2377
2378 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
2379 p_data, packet_size, ui32LBA);
2380 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write,
2381 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
2382 CHECK_VPU_RECOVERY(retval);
2383 if (retval < 0)
2384 {
2385 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
2387 LRETURN;
2388 }
2389
2390 // reset session status after successful send
2391 p_ctx->status = 0;
2392 p_ctx->required_buf_size = 0;
2393
2394 sent_size = p_packet->data_len;
2395 p_packet->data_len = 0;
2396
2397 if (p_param->dec_input_params.nb_save_pkt)
2398 {
2399 char dump_file[512] = {0};
2400 long curr_pkt_num =
2401 ((long)p_ctx->pkt_num % p_param->dec_input_params.nb_save_pkt) + 1;
2402 snprintf(dump_file, sizeof(dump_file), "%s/pkt-%04ld.bin",
2403 p_ctx->stream_dir_name, curr_pkt_num);
2404
2405 FILE *f = NULL;
2406 ni_fopen(&f, dump_file, "wb");
2407 if (f)
2408 {
2409 fwrite(p_packet->p_data, sent_size, 1, f);
2410 fflush(f);
2411 fclose(f);
2412 }
2413 }
2414
2415 p_ctx->pkt_num++;
2416 p_ctx->low_delay_sync_flag = 1;
2417 }
2418
2419 //Handle end of stream flag
2420 if (p_packet->end_of_stream)
2421 {
2424 p_ctx->device_type, p_ctx->hw_id,
2425 &(p_ctx->session_id), OPT_1);
2426 CHECK_VPU_RECOVERY(retval);
2427
2428 if (NI_RETCODE_SUCCESS != retval)
2429 {
2430 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Failed to send EOS.\n", __func__);
2431 LRETURN;
2432 }
2433
2434 p_packet->end_of_stream = 0;
2435 p_ctx->ready_to_close = 1;
2436 }
2437
2438 {
2439 p_ctx->pts_offsets[p_ctx->pkt_index % NI_FIFO_SZ] = p_packet->pts;
2440 p_ctx->flags_array[p_ctx->pkt_index % NI_FIFO_SZ] = p_packet->flags;
2441 p_ctx->pkt_pos[p_ctx->pkt_index % NI_FIFO_SZ] = p_packet->pkt_pos;
2442 if (p_ctx->pkt_index == 0)
2443 {
2444 p_ctx->pkt_offsets_index_min[p_ctx->pkt_index % NI_FIFO_SZ] = 0;
2445 /* minus 1 here. ffmpeg parses the msb 0 of long start code as the last packet's payload for hevc bitstream (hevc_parse).
2446 * move 1 byte forward on all the pkt_offset so that frame_offset coming from fw can fall into the correct range. */
2447 //p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ] = current_pkt_size - 1;
2448 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ] = current_pkt_size;
2449 ni_log2(p_ctx, NI_LOG_DEBUG,
2450 "%s: (first packet) pkt_index %d i %u "
2451 "pkt_offsets_index_min %" PRIu64 " pkt_offsets_index %" PRIu64
2452 " pts_offsets %" PRId64 "\n",
2453 __func__, p_ctx->pkt_index, p_ctx->pkt_index % NI_FIFO_SZ,
2455 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ],
2456 p_ctx->pts_offsets[p_ctx->pkt_index % NI_FIFO_SZ]);
2457 }
2458 else
2459 {
2460 // cumulate sizes to correspond to FW offsets
2461 p_ctx->pkt_offsets_index_min[p_ctx->pkt_index % NI_FIFO_SZ] = p_ctx->pkt_offsets_index[(p_ctx->pkt_index - 1) % NI_FIFO_SZ];
2462 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ] = p_ctx->pkt_offsets_index[(p_ctx->pkt_index - 1) % NI_FIFO_SZ] + current_pkt_size;
2463 ni_log2(p_ctx, NI_LOG_DEBUG,
2464 "%s: pkt_index %d i %u pkt_offsets_index_min "
2465 "%" PRIu64 " pkt_offsets_index %" PRIu64 " pts_offsets %" PRId64
2466 "\n",
2467 __func__, p_ctx->pkt_index, p_ctx->pkt_index % NI_FIFO_SZ,
2469 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ],
2470 p_ctx->pts_offsets[p_ctx->pkt_index % NI_FIFO_SZ]);
2471
2472 //Wrapping 32 bits since FW send u32 wrapped values
2473 if (p_ctx->pkt_offsets_index_min[p_ctx->pkt_index % NI_FIFO_SZ] > 0xFFFFFFFF)
2474 {
2475 p_ctx->pkt_offsets_index_min[p_ctx->pkt_index % NI_FIFO_SZ] = p_ctx->pkt_offsets_index_min[p_ctx->pkt_index % NI_FIFO_SZ] - (0x100000000);
2476 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ] = p_ctx->pkt_offsets_index_min[p_ctx->pkt_index % NI_FIFO_SZ] + current_pkt_size;
2477 ni_log2(p_ctx, NI_LOG_DEBUG,
2478 "%s: (wrap) pkt_index %d i %u "
2479 "pkt_offsets_index_min %" PRIu64 " pkt_offsets_index %" PRIu64
2480 " pts_offsets %" PRId64 "\n",
2481 __func__, p_ctx->pkt_index, p_ctx->pkt_index % NI_FIFO_SZ,
2483 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ],
2484 p_ctx->pts_offsets[p_ctx->pkt_index % NI_FIFO_SZ]);
2485 }
2486 }
2487
2488 /* if this wrap-around pkt_offset_index spot is about to be overwritten, free the previous one. */
2489 free(p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ]);
2490
2491 if (p_packet->p_custom_sei_set)
2492 {
2493 p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ] = malloc(sizeof(ni_custom_sei_set_t));
2494 if (p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ])
2495 {
2496 ni_custom_sei_set_t *p_custom_sei_set = p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ];
2497 memcpy(p_custom_sei_set, p_packet->p_custom_sei_set, sizeof(ni_custom_sei_set_t));
2498 }
2499 else
2500 {
2501 /* warn and lose the sei data. */
2502 ni_log2(p_ctx, NI_LOG_ERROR,
2503 "Error %s: failed to allocate custom SEI buffer for pkt.\n",
2504 __func__);
2505 }
2506 }
2507 else
2508 {
2509 p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ] = NULL;
2510 }
2511
2512 p_ctx->pkt_index++;
2513 }
2514
2515 retval = ni_timestamp_register(p_ctx->buffer_pool, p_ctx->dts_queue, p_packet->dts, 0);
2516 if (NI_RETCODE_SUCCESS != retval)
2517 {
2518 ni_log2(p_ctx, NI_LOG_ERROR,
2519 "ERROR %s(): ni_timestamp_register() for dts returned %d\n",
2520 __func__, retval);
2521 }
2522END:
2523
2525
2526 if (NI_RETCODE_SUCCESS == retval)
2527 {
2528 ni_log2(p_ctx, NI_LOG_TRACE,
2529 "%s(): exit: packets: %" PRIu64 " offset %" PRIx64 ""
2530 " sent_size = %u, status=%d\n",
2531 __func__, p_ctx->pkt_num, (uint64_t)p_packet->pos, sent_size,
2532 p_ctx->status);
2533 return sent_size;
2534 } else
2535 {
2536 ni_log2(p_ctx, NI_LOG_ERROR,
2537 "ERROR %s(): exit: returnErr: %d, p_ctx->status: %d\n", __func__,
2538 retval, p_ctx->status);
2539 return retval;
2540 }
2541}
2542
2543static int64_t guess_correct_pts(ni_session_context_t* p_ctx, int64_t reordered_pts, int64_t dts)
2544{
2545 int64_t pts = NI_NOPTS_VALUE;
2546 if (dts != NI_NOPTS_VALUE)
2547 {
2549 p_ctx->pts_correction_last_dts = dts;
2550 ni_log2(p_ctx, NI_LOG_DEBUG,
2551 "%s: pts_correction_last_dts %" PRId64 " "
2552 "pts_correction_num_faulty_dts %d\n",
2553 __func__, p_ctx->pts_correction_last_dts,
2555 }
2556 else if (reordered_pts != NI_NOPTS_VALUE)
2557 {
2558 p_ctx->pts_correction_last_dts = reordered_pts;
2559 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: pts_correction_last_dts %" PRId64 "\n", __func__,
2561 }
2562 if (reordered_pts != NI_NOPTS_VALUE)
2563 {
2564 p_ctx->pts_correction_num_faulty_pts += reordered_pts <= p_ctx->pts_correction_last_pts;
2565 p_ctx->pts_correction_last_pts = reordered_pts;
2566 ni_log2(p_ctx, NI_LOG_DEBUG,
2567 "%s: pts_correction_last_pts %" PRId64 " "
2568 "pts_correction_num_faulty_pts %d\n",
2569 __func__, p_ctx->pts_correction_last_pts,
2571 }
2572 else if (dts != NI_NOPTS_VALUE)
2573 {
2574 p_ctx->pts_correction_last_pts = dts;
2575 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: pts_correction_last_pts %" PRId64 "\n", __func__,
2577 }
2579 && reordered_pts != NI_NOPTS_VALUE)
2580 {
2581 pts = reordered_pts;
2582 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: (reordered_pts) pts %" PRId64 "\n", __func__,
2583 pts);
2584 }
2585 else
2586 {
2587 if ((NI_NOPTS_VALUE == reordered_pts) ||
2588 (NI_NOPTS_VALUE == p_ctx->last_pts) || (dts >= p_ctx->last_pts))
2589 {
2590 pts = dts;
2591 } else
2592 {
2593 pts = reordered_pts;
2594 }
2595
2596 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: (dts) pts %" PRId64 "\n", __func__, pts);
2597 }
2598 return pts;
2599}
2600
2601static int rotated_array_binary_search(uint64_t *lefts, uint64_t *rights,
2602 int32_t size, uint64_t target)
2603{
2604 int lo = 0;
2605 int hi = size - 1;
2606 while (lo <= hi)
2607 {
2608 int mid = lo + (hi - lo) / 2;
2609 if (lefts[mid] <= target && target < rights[mid])
2610 {
2611 return mid;
2612 }
2613
2614 if (rights[mid] == 0)
2615 {
2616 // empty in (mid, hi)
2617 hi = mid - 1;
2618 continue;
2619 }
2620
2621 if (rights[lo] <= rights[mid])
2622 {
2623 if (lefts[lo] <= target && target < lefts[mid])
2624 {
2625 // Elements are all monotonous in (lo, mid)
2626 hi = mid - 1;
2627 } else
2628 {
2629 // Rotation in (mid, hi)
2630 lo = mid + 1;
2631 }
2632 } else
2633 {
2634 if (rights[mid] <= target && target < rights[hi])
2635 {
2636 // Elements are all monotonous in (mid, hi)
2637 lo = mid + 1;
2638 } else
2639 {
2640 // Rotation in (lo, mid)
2641 hi = mid - 1;
2642 }
2643 }
2644 }
2645
2646 return -1;
2647}
2648
2649/*!******************************************************************************
2650 * \brief Retrieve a YUV p_frame from decoder
2651 *
2652 * \param
2653 *
2654 * \return
2655 *******************************************************************************/
2657{
2658 ni_instance_mgr_stream_info_t data = { 0 };
2659 int rx_size = 0;
2660 uint64_t frame_offset = 0;
2661 uint32_t frame_dropped = 0;
2662 uint8_t *p_data_buffer = NULL;
2663 uint32_t i = 0;
2664 int is_planar;
2665 int retval = NI_RETCODE_SUCCESS;
2666 int metadata_hdr_size = NI_FW_META_DATA_SZ - NI_MAX_NUM_OF_DECODER_OUTPUTS * sizeof(niFrameSurface1_t);
2667 int sei_size = 0;
2668 uint32_t total_bytes_to_read = 0;
2669 uint32_t read_size_bytes = 0;
2670 ni_instance_buf_info_t buf_info = { 0 };
2671 ni_session_statistic_t sessionStatistic = {0};
2672 ni_xcoder_params_t *p_param;
2673
2674 int query_retry = 0;
2675 uint32_t ui32LBA = 0;
2676 unsigned int bytes_read_so_far = 0;
2677 int query_type = INST_BUF_INFO_RW_READ;
2678 int low_delay_notify = 0;
2679 uint32_t frames_dropped = 0;
2680 uint8_t get_first_metadata = 0;
2681 uint8_t sequence_change = 0;
2682
2683 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
2684
2685 if ((!p_ctx) || (!p_frame))
2686 {
2687 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
2689 }
2690
2692
2693start:
2694 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
2695 {
2696 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): xcoder instance id < 0, return\n",
2697 __func__);
2699 LRETURN;
2700 }
2701
2702 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
2703 p_data_buffer = (uint8_t *)p_frame->p_buffer;
2704
2705 // p_frame->p_data[] can be NULL before actual resolution is returned by
2706 // decoder and buffer pool is allocated, so no checking here.
2707 total_bytes_to_read = p_frame->data_len[0] + p_frame->data_len[1] +
2708 p_frame->data_len[2] + metadata_hdr_size;
2709 ni_log2(p_ctx, NI_LOG_DEBUG, "Total bytes to read %u, low_delay %u\n",
2710 total_bytes_to_read, p_ctx->decoder_low_delay);
2711
2712 if (p_ctx->decoder_low_delay > 0 && !p_ctx->ready_to_close)
2713 {
2714 ni_log2(p_ctx, NI_LOG_DEBUG, "frame_num = %" PRIu64 ", pkt_num = %" PRIu64 "\n",
2715 p_ctx->frame_num, p_ctx->pkt_num);
2716 frames_dropped = p_ctx->session_statistic.ui32FramesDropped;
2717 if (p_ctx->force_low_delay && (p_ctx->force_low_delay_cnt < frames_dropped)) {
2718 p_ctx->force_low_delay_cnt = frames_dropped;
2719 }
2720 if (p_ctx->frame_num + p_ctx->force_low_delay_cnt >= p_ctx->pkt_num)
2721 {
2722 //nothing to query, leave
2723 retval = NI_RETCODE_SUCCESS;
2724 LRETURN;
2725 }
2726 query_type = INST_BUF_INFO_RW_READ_BUSY;
2727 }
2728 for (;;)
2729 {
2730 query_sleep(p_ctx);
2731
2732 query_retry++;
2733
2735 "65") >= 0)
2736 {
2738 &sessionStatistic);
2739 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
2741 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
2742 CHECK_VPU_RECOVERY(retval);
2743
2744 buf_info.buf_avail_size = sessionStatistic.ui32RdBufAvailSize;
2745 } else
2746 {
2747 retval = ni_query_instance_buf_info(p_ctx, query_type,
2748 NI_DEVICE_TYPE_DECODER, &buf_info);
2749 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
2750 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
2751 CHECK_VPU_RECOVERY(retval);
2752 }
2753
2754 ni_log2(p_ctx, NI_LOG_TRACE, "Info query buf_info.size = %u\n",
2755 buf_info.buf_avail_size);
2756
2757 if (NI_RETCODE_SUCCESS != retval)
2758 {
2759 ni_log2(p_ctx, NI_LOG_TRACE, "Warning: dec read query fail rc %d retry %d max_retry_fail_count %d\n",
2760 retval, query_retry, p_ctx->max_retry_fail_count[1]);
2761
2762 if (query_retry >= 1000)
2763 {
2764 p_ctx->max_retry_fail_count[1]++;
2765 low_delay_notify = 1;
2767 LRETURN;
2768 }
2772 }
2773 else if (buf_info.buf_avail_size == DP_IPC_PASSTHRU)
2774 {
2775 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Bad available buffer size %u\n", __FUNCTION__, buf_info.buf_avail_size);
2776 retval = NI_RETCODE_FAILURE;
2777 LRETURN;
2778 }
2779 else if (buf_info.buf_avail_size == metadata_hdr_size)
2780 {
2781 ni_log2(p_ctx, NI_LOG_DEBUG, "Info only metadata hdr is available, seq change?\n");
2782 total_bytes_to_read = metadata_hdr_size;
2783 sequence_change = 1;
2784 break;
2785 }
2786 else if (0 == buf_info.buf_avail_size)
2787 {
2788 // query to see if it is eos now, if we have sent it
2789 if (p_ctx->ready_to_close)
2790 {
2791 ni_log2(p_ctx, NI_LOG_TRACE, "Info dec query, ready_to_close %u, query eos\n",
2792 p_ctx->ready_to_close);
2793 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_DECODER, &data);
2794 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
2795 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
2796 CHECK_VPU_RECOVERY(retval);
2797
2798 if (data.is_flushed ||
2799 query_retry >=
2801 {
2802 if (query_retry >=
2804 {
2805 ni_log2(p_ctx, NI_LOG_ERROR,
2806 "WARNING: Dec eos reached but also exceeded max dec read query "
2807 "retries. is_flushed=%u try=%d.\n",
2808 data.is_flushed, query_retry);
2809 } else
2810 {
2811 ni_log2(p_ctx, NI_LOG_DEBUG,
2812 "Dec eos reached. is_flushed=%u try=%d.\n",
2813 data.is_flushed, query_retry);
2814 }
2815 p_frame->end_of_stream = 1;
2816 low_delay_notify = 1;
2817 retval = NI_RETCODE_SUCCESS;
2818 LRETURN;
2819 } else
2820 {
2821 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read available buf size == 0, query try %d,"
2822 " retrying ..\n", query_retry);
2826 continue;
2827 }
2828 }
2829
2830 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read available buf size == 0. retry=%d, eos=%d"
2831 "\n", query_retry, p_frame->end_of_stream);
2833 (p_ctx->decoder_low_delay > 0 &&
2834 ((p_ctx->frame_num + p_ctx->force_low_delay_cnt)
2835 < p_ctx->pkt_num))) &&
2836 query_retry < 1000 / 2)
2837 {
2838 if (p_ctx->decoder_low_delay && p_ctx->force_low_delay) {
2839 if (p_ctx->session_statistic.ui32FramesDropped > frames_dropped) {
2840 // last pkt sent to decoder marked as dropped, no output,
2841 // so just stop query and return
2842 p_ctx->force_low_delay_cnt++;
2843 low_delay_signal(p_ctx);
2844 retval = NI_RETCODE_SUCCESS;
2845 LRETURN;
2846 }
2847 } else if (NI_RETCODE_NVME_SC_WRITE_BUFFER_FULL == p_ctx->status &&
2848 sessionStatistic.ui32WrBufAvailSize > p_ctx->required_buf_size)
2849 {
2850 ni_log2(p_ctx, NI_LOG_TRACE, "Info dec write buffer is enough, available buf "
2851 "size %u >= required size %u !\n",
2852 sessionStatistic.ui32WrBufAvailSize, p_ctx->required_buf_size);
2853 p_ctx->status = 0;
2854 p_ctx->required_buf_size = 0;
2855 retval = NI_RETCODE_SUCCESS;
2856 LRETURN;
2857 }
2859 ni_usleep(25);
2861 continue;
2862 } else
2863 {
2864 if(p_ctx->decoder_low_delay > 0)
2865 {
2866 if (p_ctx->force_low_delay) {
2867 p_ctx->force_low_delay_cnt++;
2868 low_delay_signal(p_ctx);
2869 } else {
2870 ni_log2(p_ctx, NI_LOG_ERROR,
2871 "Warning: ceased using low delay decoding mode after "
2872 "excessively long decoder read query.\n");
2873 // Here it should be the last signal to release the send thread
2874 // holding the low delay mutex.
2875 low_delay_signal(p_ctx);
2876 p_ctx->decoder_low_delay = 0;
2877 }
2878 }
2879
2880 if ((p_param->dec_input_params.min_packets_delay && p_ctx->pkt_delay_cnt))
2881 {
2882 if(p_ctx->pkt_num >= (p_ctx->frame_num + p_ctx->pkt_delay_cnt +
2884 {
2885 if(query_retry <= 2000)
2886 {
2888 ni_usleep(25);
2890 continue;
2891 } else {
2892 p_ctx->pkt_delay_cnt++;
2893 ni_log2(p_ctx, NI_LOG_ERROR,
2894 "Warning: decoder pkt_num %u frame_num %u "
2895 "timeout, increasing pkt_delay_cnt to %u\n",
2896 p_ctx->pkt_num, p_ctx->frame_num,
2897 p_ctx->pkt_delay_cnt);
2898 }
2899 }
2900 }
2901
2902 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: dec read failed %d retries. rc=%d; eos=%d\n",
2903 query_retry, p_ctx->status, p_frame->end_of_stream);
2904 }
2905 retval = NI_RETCODE_SUCCESS;
2906 LRETURN;
2907 }
2908 else
2909 {
2910 // We have to ensure there are adequate number of DTS for picture
2911 // reorder delay otherwise wait for more packets to be sent to decoder.
2912 ni_timestamp_table_t *p_dts_queue = p_ctx->dts_queue;
2913 if ((int)p_dts_queue->list.count < p_ctx->pic_reorder_delay + 1 &&
2914 !p_ctx->ready_to_close &&
2916 {
2917 retval = NI_RETCODE_SUCCESS;
2918 ni_log2(p_ctx, NI_LOG_DEBUG,
2919 "At least %d packets should be sent before reading the "
2920 "first frame!\n",
2921 p_ctx->pic_reorder_delay + 1);
2922 LRETURN;
2923 }
2924 p_ctx->max_retry_fail_count[1] = 0;
2925
2926 // get actual YUV transfer size if this is the stream's very first read
2927 if (0 == p_ctx->active_video_width || 0 == p_ctx->active_video_height)
2928 {
2929 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_DECODER, &data);
2930 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
2931 p_ctx->device_type, p_ctx->hw_id,
2932 &(p_ctx->session_id), OPT_1);
2933 CHECK_VPU_RECOVERY(retval);
2934
2935 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec YUV query, pic size %ux%u xfer frame size "
2936 "%ux%u frame-rate %u is_flushed %u\n",
2937 data.picture_width, data.picture_height,
2939 data.frame_rate, data.is_flushed);
2942 p_ctx->actual_video_width = data.picture_width;
2943 p_ctx->pixel_format = data.pix_format;
2944 is_planar = (p_ctx->pixel_format == NI_PIX_FMT_YUV420P) ||
2947 //p_ctx->bit_depth_factor = data.transfer_frame_stride / data.picture_width;
2948 p_ctx->is_first_frame = 1;
2949 p_ctx->pixel_format_changed = 0;
2950
2951 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec YUV, adjust frame size from %ux%u to "
2952 "%ux%u format = %d\n", p_frame->video_width, p_frame->video_height,
2953 p_ctx->active_video_width, p_ctx->active_video_height, p_ctx->pixel_format);
2954
2956
2957 // set up decoder YUV frame buffer pool
2960 p_ctx->active_video_height,
2962 p_ctx->bit_depth_factor))
2963 {
2964 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Cannot allocate fme buf pool.\n",
2965 __func__);
2967
2969 ni_decoder_session_close(p_ctx, 0);
2970#ifdef XCODER_SELF_KILL_ERR
2971 // if need to terminate at such occasion when continuing is not
2972 // possible, trigger a codec closure
2973 ni_log2(p_ctx, NI_LOG_ERROR, "Terminating due to unable to allocate fme buf "
2974 "pool.\n");
2975 kill(getpid(), SIGTERM);
2976#endif
2978 LRETURN;
2979 }
2980
2982 p_ctx->dec_fme_buf_pool, p_frame, 1, // get mem buffer
2985 p_ctx->bit_depth_factor, is_planar);
2986
2987 if (NI_RETCODE_SUCCESS != retval)
2988 {
2989 LRETURN;
2990 }
2991 total_bytes_to_read = p_frame->data_len[0] + p_frame->data_len[1] +
2992 p_frame->data_len[2] + metadata_hdr_size;
2993 p_data_buffer = (uint8_t*) p_frame->p_buffer;
2994
2995 // make sure we don't read more than available
2996 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec buf size: %u YUV frame + meta-hdr size: %u "
2997 "available: %u\n", p_frame->buffer_size,
2998 total_bytes_to_read, buf_info.buf_avail_size);
2999 }
3000 break;
3001 }
3002 }
3003
3004 ni_log2(p_ctx, NI_LOG_DEBUG, "total_bytes_to_read %u max_nvme_io_size %u ylen %u cr len "
3005 "%u cb len %u hdr %d\n",
3006 total_bytes_to_read, p_ctx->max_nvme_io_size,
3007 p_frame->data_len[0], p_frame->data_len[1],
3008 p_frame->data_len[2], metadata_hdr_size);
3009
3010 if (buf_info.buf_avail_size < total_bytes_to_read)
3011 {
3013 ni_log2(p_ctx, NI_LOG_ERROR,
3014 "ERROR %s() avaliable size(%u)"
3015 "less than needed (%u)\n",
3016 __func__, buf_info.buf_avail_size, total_bytes_to_read);
3017 abort();
3018 }
3019
3020 if (buf_info.buf_avail_size == metadata_hdr_size && (!p_ctx->frame_num || !p_data_buffer))
3021 {
3024 "6rE") >= 0)
3025 {
3026 // allocate p_data_buffer to read the first metadata
3027 void *p_metadata_buffer = NULL;
3028 int buffer_size = ((metadata_hdr_size + (NI_MEM_PAGE_ALIGNMENT - 1)) /
3030 if (ni_posix_memalign(&p_metadata_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3031 {
3032 ni_log2(p_ctx, NI_LOG_ERROR,
3033 "ERROR %d: %s() Cannot allocate metadata buffer.\n",
3034 NI_ERRNO, __func__);
3036 LRETURN;
3037 }
3038 p_data_buffer = (uint8_t *)p_metadata_buffer;
3039 get_first_metadata = 1;
3040 if (!p_ctx->frame_num)
3041 sequence_change = 0;
3042 }
3043 }
3044
3045 if (!p_data_buffer)
3046 {
3047 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: data buffer is null!, return\n");
3048 retval = NI_RETCODE_INVALID_PARAM;
3049 LRETURN;
3050 }
3051
3052 read_size_bytes = buf_info.buf_avail_size;
3054 if (read_size_bytes % NI_MEM_PAGE_ALIGNMENT)
3055 {
3056 read_size_bytes = ((read_size_bytes / NI_MEM_PAGE_ALIGNMENT) *
3059 }
3060
3061 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
3062 p_data_buffer, read_size_bytes, ui32LBA);
3063 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
3064 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
3065 CHECK_VPU_RECOVERY(retval);
3066 if (retval < 0)
3067 {
3068 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
3070 LRETURN;
3071 } else if (get_first_metadata) {
3072 // got first metadata alone
3073 ni_metadata_dec_frame_t *p_meta =
3074 (ni_metadata_dec_frame_t *)((uint8_t *)p_data_buffer);
3075 ni_log2(p_ctx, NI_LOG_DEBUG, "Got first pkt_delay_cnt %u\n",
3077 if (p_ctx->pkt_delay_cnt < p_meta->metadata_common.pkt_delay_cnt)
3079 get_first_metadata = 0;
3080 ni_aligned_free(p_data_buffer);
3081 goto start;
3082 } else {
3083 // command issued successfully, now exit
3085 p_meta =
3086 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
3087 p_frame->data_len[0] +
3088 p_frame->data_len[1] +
3089 p_frame->data_len[2]);
3090
3091 if (buf_info.buf_avail_size != metadata_hdr_size)
3092 {
3093 low_delay_notify = 1;
3094 sei_size = p_meta->sei_size;
3095 } else if (ni_cmp_fw_api_ver(
3097 "6rE") >= 0)
3098 {
3099 p_meta =
3100 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer);
3101 ni_log2(p_ctx, NI_LOG_DEBUG, "Got pkt_delay_cnt %u\n",
3103 if (p_ctx->pkt_delay_cnt < p_meta->metadata_common.pkt_delay_cnt)
3105 }
3106 total_bytes_to_read = total_bytes_to_read + sei_size;
3107 ni_log2(p_ctx, NI_LOG_DEBUG, "decoder read success, size %d total_bytes_to_read "
3108 "include sei %u sei_size %d\n",
3109 retval, total_bytes_to_read, sei_size);
3110 }
3111
3112 bytes_read_so_far = total_bytes_to_read ;
3113 // Note: session status is NOT reset but tracked between send
3114 // and recv to catch and recover from a loop condition
3115
3117 "6sP") >= 0)
3118 {
3119 rx_size = ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, &frame_dropped, false);
3120 }
3121 else
3122 {
3123 rx_size = ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, 0, false);
3124 }
3125 p_ctx->frame_pkt_offset = frame_offset;
3126 if (p_ctx->decoder_low_delay > 0 && buf_info.buf_avail_size == metadata_hdr_size &&
3128 {
3129 ni_log2(p_ctx, NI_LOG_TRACE, "Low delay mode amd check header if has b frame\n");
3130
3131 ni_metadata_dec_frame_t *p_meta =
3132 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
3133 p_frame->data_len[0] +
3134 p_frame->data_len[1] +
3135 p_frame->data_len[2]);
3136 if (p_meta->metadata_common.has_b_frame == 1)
3137 {
3138 ni_log2(p_ctx, NI_LOG_ERROR,"Warning: session 0x%x decoder lowDelay mode "
3139 "is cancelled due to has_b_frames, frame_num %u\n",
3140 p_ctx->session_id, p_ctx->frame_num);
3141 p_ctx->decoder_low_delay = 0;
3142 }
3143 }
3144
3145 if (rx_size > 0)
3146 {
3147 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): s-state %d first_frame %d\n", __func__,
3148 p_ctx->session_run_state, p_ctx->is_first_frame);
3149
3150 int64_t tmp_dts, prev_dts = INT64_MIN, ts_diff = 0;
3151 int nb_diff = 0;
3152
3154 "6sP") >= 0)
3155 {
3156 if(p_ctx->last_frame_dropped + frame_dropped != p_ctx->session_statistic.ui32FramesDropped)
3157 {
3158 ni_log2(p_ctx, NI_LOG_DEBUG,
3159 "### %s(): Warning: ui32FramesDropped %u should be %u + %u\n",
3160 __func__, p_ctx->session_statistic.ui32FramesDropped,
3161 p_ctx->last_frame_dropped, frame_dropped);
3162
3163 p_ctx->session_statistic.ui32FramesDropped = p_ctx->last_frame_dropped + frame_dropped;
3164 }
3165
3167 }
3168
3169 // at stream start, if there are already frames dropped at decoding, drop
3170 // equal number of dts from dts queue to try to align with the first
3171 // returned frame, and calculate the average of dts difference to be used
3172 // for locating the first frame's dts
3173 if (p_ctx->is_first_frame)
3174 {
3175 ni_log2(p_ctx, NI_LOG_DEBUG,
3176 "%s(): First frame : session_id 0x%x, pic_reorder_delay: %d "
3177 "total frames input:%u buffered: %u completed: %u output: %u "
3178 "dropped: %u (%u %u) error: %u\n",
3179 __func__, p_ctx->session_id, p_ctx->pic_reorder_delay,
3185 p_ctx->last_frame_dropped, frame_dropped,
3187
3188 if (p_ctx->session_statistic.ui32FramesDropped > 0)
3189 {
3190 for (i = 0; i < p_ctx->session_statistic.ui32FramesDropped; i++)
3191 {
3193 p_ctx->dts_queue, 0, &tmp_dts,
3196 {
3197 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): FramesDropped pop "
3198 "decoder dts queue %d %ld failed !\n",
3199 __func__, i, tmp_dts);
3200 break;
3201 } else
3202 {
3203 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop "
3204 "decoder dts queue %d %ld success !\n",
3205 __func__, i, tmp_dts);
3206 if (prev_dts != INT64_MIN) {
3207 ts_diff += llabs(tmp_dts - prev_dts);
3208 nb_diff++;
3209 }
3210 prev_dts = tmp_dts;
3211 }
3212 }
3213 if (nb_diff > 1)
3214 {
3215 ts_diff = ts_diff / nb_diff;
3216 }
3218 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop dts "
3219 "average diff: %ld\n", __func__, ts_diff);
3220 }
3221 }
3222 else
3223 {
3225 {
3226 for(i = p_ctx->decoder_last_drop_frame_num; i < p_ctx->session_statistic.ui32FramesDropped; i++)
3227 {
3229 p_ctx->dts_queue, 0, &tmp_dts,
3232 {
3233 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): FramesDropped pop "
3234 "decoder dts queue %d %ld failed !\n",
3235 __func__, i, tmp_dts);
3236 break;
3237 }
3238 }
3240 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop dts %d\n", __func__, p_ctx->decoder_last_drop_frame_num);
3241 }
3242 }
3243
3245 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
3248 {
3249 if (p_ctx->last_dts != NI_NOPTS_VALUE && !p_ctx->ready_to_close)
3250 {
3251 p_ctx->pic_reorder_delay++;
3252 p_frame->dts = p_ctx->last_dts + p_ctx->last_dts_interval;
3253 ni_log2(p_ctx, NI_LOG_DEBUG, "Padding DTS: %" PRId64 "\n", p_frame->dts);
3254 } else
3255 {
3256 p_frame->dts = NI_NOPTS_VALUE;
3257 }
3258 }
3259
3260 if (p_ctx->is_first_frame)
3261 {
3262 for (i = 0; (int)i < p_ctx->pic_reorder_delay; i++)
3263 {
3264 if (p_ctx->last_pts == NI_NOPTS_VALUE &&
3265 p_ctx->last_dts == NI_NOPTS_VALUE)
3266 {
3267 // If the p_frame->pts is unknown in the very beginning we assume
3268 // p_frame->pts == 0 as well as DTS less than PTS by 1000 * 1/timebase
3269 if (p_frame->pts >= p_frame->dts &&
3270 p_frame->pts - p_frame->dts < 1000)
3271 {
3272 break;
3273 }
3274 }
3275
3277 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
3279 p_ctx->frame_num % 500 == 0,
3281 {
3282 p_frame->dts = NI_NOPTS_VALUE;
3283 } else
3284 {
3285 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): pic_reorder_delay pop "
3286 "decoder dts queue %d %ld success !\n",
3287 __func__, i, p_frame->dts);
3288 }
3289 }
3290 // Reset for DTS padding counting
3291 p_ctx->pic_reorder_delay = 0;
3292 }
3293 if (p_ctx->codec_format == NI_CODEC_FORMAT_JPEG)//fw won't save frameoffset when decoding jpeg.
3294 {
3295 if (p_ctx->is_first_frame)
3296 {
3297 p_ctx->is_first_frame = 0;
3298 }
3299 p_frame->pts = p_ctx->pts_offsets[p_ctx->frame_num % NI_FIFO_SZ];
3300 p_frame->flags = p_ctx->flags_array[p_ctx->frame_num % NI_FIFO_SZ];
3301 p_frame->pkt_pos = p_ctx->pkt_pos[p_ctx->frame_num % NI_FIFO_SZ];
3302 ni_log2(p_ctx, NI_LOG_DEBUG, "p_frame->pts = %u, frame_num = %d, p_frame->dts = %u\n",
3303 p_frame->pts, p_ctx->frame_num, p_frame->dts);
3304 }
3305 else
3306 {
3307 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: frame_offset %" PRIu64 "\n", __func__,
3308 frame_offset);
3309
3310 // search for the pkt_offsets of received frame according to frame_offset.
3311 // here we get the index(i) which promises (p_ctx->pkt_offsets_index_min[i] <= frame_offset && p_ctx->pkt_offsets_index[i] > frame_offset)
3312 // i = -1 if not found
3313 int j = 0;
3314 j = rotated_array_binary_search(p_ctx->pkt_offsets_index_min,
3316 frame_offset);
3317 if (j >= 0)
3318 {
3319 p_frame->pts = p_ctx->pts_offsets[j];
3320 p_frame->flags = p_ctx->flags_array[j];
3321 p_frame->pkt_pos = p_ctx->pkt_pos[j];
3322 ni_log2(p_ctx, NI_LOG_DEBUG,
3323 "%s: (found pts) dts %" PRId64 " pts "
3324 "%" PRId64 " frame_offset %" PRIu64 " j %d "
3325 "pkt_offsets_index_min %" PRIu64 " pkt_offsets_index "
3326 "%" PRIu64 " pkt_pos %" PRIu64 " \n",
3327 __func__, p_frame->dts, p_frame->pts, frame_offset, j,
3328 p_ctx->pkt_offsets_index_min[j],
3329 p_ctx->pkt_offsets_index[j],
3330 p_ctx->pkt_pos[j]);
3331
3332 if (p_ctx->is_first_frame)
3333 {
3334 // if the first frame is I frame and there are dropped frames,
3335 // find the dts closest to its pts using the average of dts diff
3336 if (p_frame->dts != NI_NOPTS_VALUE &&
3337 p_frame->pts != NI_NOPTS_VALUE &&
3338 PIC_TYPE_I == p_frame->ni_pict_type &&
3340 ts_diff > 0)
3341 {
3342 while (p_frame->dts < p_frame->pts &&
3343 llabs(p_frame->pts - p_frame->dts) > ts_diff)
3344 {
3345 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: First I frame pts %lld "
3346 "dts %lld diff. %lld > ts_diff %lld\n",
3347 __func__, p_frame->pts, p_frame->dts,
3348 llabs(p_frame->pts - p_frame->dts), ts_diff);
3349
3351 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
3353 {
3354 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): First I frame "
3355 "pop decoder dts queue error.\n", __func__);
3356 break;
3357 }
3358 }
3359 }
3360 }
3361
3362 p_frame->p_custom_sei_set = p_ctx->pkt_custom_sei_set[j];
3363 p_ctx->pkt_custom_sei_set[j] = NULL;
3364 } else
3365 {
3366 // backup solution pts
3367 if (p_param->dec_input_params.skip_pts_guess && p_ctx->last_pts != NI_NOPTS_VALUE)
3368 {
3369 // if skip guess_correct_pts, use pts interval to get the correct pts
3370 p_frame->pts = p_ctx->last_pts + (p_ctx->last_pts_interval > 0 ? p_ctx->last_pts_interval : 1);
3371 }
3372 else
3373 {
3374 p_frame->pts = p_ctx->last_pts + (p_frame->dts - p_ctx->last_dts);
3375 }
3376 p_frame->pkt_pos = p_ctx->last_pkt_pos + (frame_offset - p_ctx->last_frame_offset);
3377 ni_log2(p_ctx, NI_LOG_ERROR,
3378 "ERROR: Frame pts %" PRId64 " not found for offset "
3379 "%" PRIu64 "\n", p_frame->pts, frame_offset);
3380 ni_log2(p_ctx, NI_LOG_DEBUG,
3381 "%s: (not found use default) dts %" PRId64 " pts %" PRId64
3382 "\n",
3383 __func__, p_frame->dts, p_frame->pts);
3384 }
3385
3386 if (p_ctx->is_first_frame)
3387 {
3388 p_ctx->is_first_frame = 0;
3389 }
3390 }
3391 p_frame->orignal_pts = p_frame->pts;
3392 p_ctx->last_pkt_pos = p_frame->pkt_pos;
3393 p_ctx->last_frame_offset = frame_offset;
3394 if (!p_param->dec_input_params.skip_pts_guess)
3395 p_frame->pts = guess_correct_pts(p_ctx, p_frame->pts, p_frame->dts);
3396 if (p_frame->pts != NI_NOPTS_VALUE && p_ctx->last_pts != NI_NOPTS_VALUE)
3397 p_ctx->last_pts_interval = p_frame->pts - p_ctx->last_pts;
3398 p_ctx->last_pts = p_frame->pts;
3399 if (p_frame->dts != NI_NOPTS_VALUE && p_ctx->last_dts != NI_NOPTS_VALUE)
3400 p_ctx->last_dts_interval = p_frame->dts - p_ctx->last_dts;
3401 p_ctx->last_dts = p_frame->dts;
3402 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: (best_effort_timestamp) pts %" PRId64 "\n",
3403 __func__, p_frame->pts);
3404 p_ctx->frame_num++;
3405
3407 if (p_frame->error_ratio > 0)
3408 {
3409 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: frame number = %d, error_ratio = %u\n",
3410 __func__, p_ctx->frame_num, p_frame->error_ratio);
3411 }
3412
3413#ifdef MEASURE_LATENCY
3414#ifndef XCODER_311
3415 ni_log2(p_ctx, NI_LOG_INFO, "DEC pkt_num %d, fme_num %d, latecy is %d\n",
3416 p_ctx->pkt_num, p_ctx->frame_num, p_ctx->pkt_num - p_ctx->frame_num);
3417#endif
3418#endif
3419
3420#ifdef XCODER_DUMP_DATA
3421 char dump_file[256];
3422 snprintf(dump_file, sizeof(dump_file), "%ld-%u-dec-fme/fme-%04ld.yuv",
3423 (long)getpid(), p_ctx->session_id, (long)p_ctx->frame_num);
3424 FILE *f = NULL;
3425 ni_fopen(&f, dump_file, "wb");
3426 fwrite(p_frame->p_buffer,
3427 p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2],
3428 1, f);
3429 fflush(f);
3430 fclose(f);
3431#endif
3432 }
3433
3434 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): received data: [0x%08x]\n", __func__, rx_size);
3435 ni_log2(p_ctx, NI_LOG_DEBUG,
3436 "%s(): p_frame->start_of_stream=%u, "
3437 "p_frame->end_of_stream=%u, p_frame->video_width=%u, "
3438 "p_frame->video_height=%u\n",
3439 __func__, p_frame->start_of_stream, p_frame->end_of_stream,
3440 p_frame->video_width, p_frame->video_height);
3441 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): p_frame->data_len[0/1/2]=%u/%u/%u\n", __func__,
3442 p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2]);
3443
3444 if (p_ctx->frame_num % 500 == 0)
3445 {
3446 ni_log2(p_ctx, NI_LOG_DEBUG,
3447 "Decoder pts queue size = %u dts queue size = %u\n\n",
3448 p_ctx->pts_table->list.count, p_ctx->dts_queue->list.count);
3449 // scan and clean up
3451 p_ctx->buffer_pool);
3452 }
3453
3454#ifdef MEASURE_LATENCY
3455 if ((p_frame->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
3456 {
3457 uint64_t abs_time_ns = ni_gettime_ns();
3459 ni_log2(p_ctx, NI_LOG_INFO, "DTS:%" PRId64 ",DELTA:%" PRId64 ",dLAT:%" PRIu64 ";\n",
3460 p_frame->dts, abs_time_ns - q->last_benchmark_time,
3461 ni_lat_meas_q_check_latency(q, abs_time_ns, p_frame->dts));
3462 q->last_benchmark_time = abs_time_ns;
3463 }
3464#endif
3465
3466END:
3467
3469
3470 if (get_first_metadata && p_data_buffer)
3471 ni_aligned_free(p_data_buffer);
3472 if (sequence_change && p_ctx->frame_num)
3473 {
3474 if (p_ctx->actual_video_width == p_frame->video_width &&
3475 p_ctx->active_video_height == p_frame->video_height)
3476 {
3477 p_ctx->pixel_format_changed = 1;
3478 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): format changed\n", __func__);
3479 }
3480 }
3481
3482 if (NI_RETCODE_SUCCESS != retval)
3483 {
3484 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): bad exit, retval = %d\n", __func__, retval);
3485 if (retval == NI_RETCODE_ERROR_VPU_RECOVERY)
3486 {
3487 low_delay_signal(p_ctx);
3488 }
3489 return retval;
3490 } else
3491 {
3492 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit, rx_size = %d\n", __func__, rx_size);
3493 if (low_delay_notify)
3494 {
3495 low_delay_signal(p_ctx);
3496 }
3497 return rx_size;
3498 }
3499}
3500
3501/*!******************************************************************************
3502 * \brief Query current xcoder status
3503 *
3504 * \param
3505 *
3506 * \return
3507 *******************************************************************************/
3509 ni_device_type_t device_type)
3510{
3512 int retval = NI_RETCODE_SUCCESS;
3513
3514 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): device_type %d:%s; enter\n", __func__,
3515 device_type, g_device_type_str[device_type]);
3516
3517 if (!p_ctx)
3518 {
3519 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
3520 __func__);
3521 retval = NI_RETCODE_INVALID_PARAM;
3522 LRETURN;
3523 }
3524
3525 retval = ni_query_general_status(p_ctx, device_type, &data);
3526 if (NI_RETCODE_SUCCESS == retval)
3527 {
3531 p_ctx->overall_load_query.admin_queried = (uint32_t)data.admin_nsid;
3532 p_ctx->load_query.current_load =
3533 (uint32_t)data.process_load_percent | (uint32_t)(data.process_load_percent_upper << 8);
3534 p_ctx->load_query.fw_model_load = (uint32_t)data.fw_model_load;
3535 p_ctx->load_query.fw_load = (uint32_t)data.fw_load;
3537
3538 switch (device_type)
3539 {
3543 if (p_ctx->load_query.fw_load == 1 &&
3545 {
3546 // ignore negligible non-video traffic
3547 p_ctx->load_query.fw_load -= 1;
3548 }
3549 break;
3550 default:
3551 break;
3552 }
3553 p_ctx->load_query.total_contexts = (uint32_t)data.active_sub_instances_cnt;
3554 p_ctx->load_query.fw_video_mem_usage = (uint32_t)data.fw_video_mem_usage;
3556 p_ctx->load_query.fw_share_mem_usage = (uint32_t)data.fw_share_mem_usage;
3557 p_ctx->load_query.fw_p2p_mem_usage = (uint32_t)data.fw_p2p_mem_usage;
3559 (uint32_t)data.active_hwupload_sub_inst_cnt;
3560 ni_log2(p_ctx, NI_LOG_DEBUG, "%s blk_dev %s blk_xcoder %s dev_xcoder %s current_load:%u model_load:%u fw_load:%u "
3561 "total_contexts:%u fw_video_mem_usage:%u "
3562 "fw_video_shared_mem_usage:%u fw_share_mem_usage:%u "
3563 "fw_p2p_mem_usage:%u active_hwuploaders:%u\n", __func__,
3564 p_ctx->blk_dev_name,
3565 p_ctx->blk_xcoder_name,
3566 p_ctx->dev_xcoder_name,
3567 p_ctx->load_query.current_load,
3569 p_ctx->load_query.fw_load,
3577 {
3578 ni_log2(p_ctx, NI_LOG_DEBUG,
3579 "Overall load %u, model load %u, instance count %u\n",
3583 }
3584 }
3585
3586END:
3587
3588 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
3589
3590 return retval;
3591}
3592
3593/*!******************************************************************************
3594 * \brief Query current xcoder status
3595 *
3596 * \param
3597 *
3598 * \return
3599 *******************************************************************************/
3601 ni_device_type_t device_type, void *detail_data, int ver)
3602{
3603 int retval = NI_RETCODE_SUCCESS;
3604
3605 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): device_type %d:%s; enter\n", __func__,
3606 device_type, g_device_type_str[device_type]);
3607
3608 if (!p_ctx)
3609 {
3610 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
3611 __func__);
3612 retval = NI_RETCODE_INVALID_PARAM;
3613 LRETURN;
3614 }
3615
3616 retval = ni_query_detail_status(p_ctx, device_type, detail_data, ver);
3617
3618END:
3619
3620 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
3621
3622 return retval;
3623}
3624
3625/*!******************************************************************************
3626 * \brief Open a xcoder encoder instance
3627 *
3628 * \param
3629 *
3630 * \return
3631 *******************************************************************************/
3632
3634{
3636 ni_xcoder_params_t *p_param;
3637 void *p_buffer = NULL;
3638 ni_instance_buf_info_t buf_info = {0};
3639 uint32_t ui32LBA = 0;
3640 uint32_t max_cu_size;
3641 uint32_t block_size;
3642 int32_t width, height;
3643 int m_threshold = 0;
3644 char fmt_fw_api_ver1[5], fmt_fw_api_ver2[5];
3645
3646 if (!p_ctx || !p_ctx->p_session_config)
3647 {
3648 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
3649 __func__);
3650 retval = NI_RETCODE_INVALID_PARAM;
3651 LRETURN;
3652 }
3653
3654 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
3655 bool isrgba = (p_ctx->pixel_format == NI_PIX_FMT_ABGR || p_ctx->pixel_format == NI_PIX_FMT_ARGB
3656 || p_ctx->pixel_format == NI_PIX_FMT_RGBA || p_ctx->pixel_format == NI_PIX_FMT_BGRA);
3657 if (isrgba)
3658 {
3660 || p_param->source_width < NI_MIN_WIDTH || p_param->source_height < NI_MIN_HEIGHT)
3661 {
3662 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() RGBA / BGRA / ARGB / AGBR resolution invalid, return\n",
3663 __func__);
3664 retval = NI_RETCODE_INVALID_PARAM;
3665 LRETURN;
3666 }
3667 }
3668
3669 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter hwframes = %d\n", __func__,
3670 p_param->hwframes);
3671
3672 // Select the CPU based on the NUMA node.
3673 if (p_param->enableCpuAffinity)
3674 {
3675#if defined(__linux__) && defined(XCODER_ENABLE_CPU_AFFINITY)
3676 retval = ni_set_cpu_affinity(p_ctx);
3677 if (NI_RETCODE_SUCCESS != retval)
3678 {
3679 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ni_set_cpu_affinity failed, ret=%d\n",
3680 __func__, retval);
3681 LRETURN;
3682 }
3683#else
3684 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): not support enableCpuAffinity parameter, "
3685 "enable with [./build.sh -c] on linux\n", __func__);
3686#endif
3687 }
3688
3689 // calculate encoder ROI map size: each QP info takes 8-bit, represent 8 x 8
3690 // pixel block
3691 max_cu_size = (NI_CODEC_FORMAT_H264 == p_ctx->codec_format) ? 16 : 64;
3692
3693 width = p_param->source_width;
3694 height = p_param->source_height;
3695 // AV1 non-8x8-aligned resolution is implicitly cropped due to Quadra HW limitation
3696 if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
3697 {
3698 width = (width / 8) * 8;
3699 height = (height / 8) * 8;
3700 }
3701
3702 block_size =
3703 ((width + max_cu_size - 1) & (~(max_cu_size - 1))) *
3704 ((height + max_cu_size - 1) & (~(max_cu_size - 1))) /
3705 (8 * 8);
3706 p_ctx->roi_len = ((block_size + 63) & (~63)); // align to 64 bytes
3707
3708 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): finish init\n", __func__);
3709
3710 //Check if there is an instance or we need a new one
3711 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
3712 {
3714 p_ctx->pts_table = NULL;
3715 p_ctx->dts_queue = NULL;
3716 p_ctx->buffer_pool = NULL;
3717 p_ctx->status = 0;
3718 p_ctx->key_frame_type = 0;
3719 p_ctx->keyframe_factor = 1;
3720 p_ctx->frame_num = 0;
3721 p_ctx->pkt_num = 0;
3722 p_ctx->av1_pkt_num = 0;
3723 p_ctx->rc_error_count = 0;
3724 p_ctx->force_frame_type = 0;
3725 p_ctx->ready_to_close = 0;
3726 p_ctx->auto_dl_handle = 0;
3727 //Sequence change tracking related stuff
3728 p_ctx->active_video_width = 0;
3729 p_ctx->active_video_height = 0;
3730 p_ctx->p_all_zero_buf = NULL;
3731 p_ctx->actual_video_width = 0;
3732 p_ctx->enc_pts_w_idx = 0;
3733 p_ctx->enc_pts_r_idx = 0;
3734 p_ctx->session_timestamp = 0;
3735 memset(p_ctx->pkt_custom_sei_set, 0, NI_FIFO_SZ * sizeof(ni_custom_sei_set_t *));
3736 memset(&(p_ctx->param_err_msg[0]), 0, sizeof(p_ctx->param_err_msg));
3738 {
3740 }
3741
3742 //malloc zero data buffer
3743 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
3745 {
3746 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc all zero buffer failed\n",
3747 NI_ERRNO, __func__);
3749 LRETURN;
3750 }
3751 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
3752
3753 //malloc data buffer
3754 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
3755 {
3756 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
3757 NI_ERRNO, __func__);
3760 LRETURN;
3761 }
3762 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
3763
3764 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
3765 //In case we can open sesison, the session id would become valid.
3766 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
3767 (uint16_t)NI_INVALID_SESSION_ID;
3768
3769 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
3771 ni_htonl(p_ctx->codec_format), 0);
3772 ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer,
3773 NI_DATA_BUFFER_LEN, ui32LBA);
3774 //Open will return a session status structure with a valid session id if it worked.
3775 //Otherwise the invalid session id set before the open command will stay
3776 p_ctx->session_id =
3777 ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
3778 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
3779 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
3780 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
3781 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
3782 {
3783 ni_log2(p_ctx, NI_LOG_ERROR,
3784 "ERROR %s(): p_ctx->device_handle=%" PRIx64 ", "
3785 "p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
3786 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
3787 p_ctx->session_id);
3788 ni_encoder_session_close(p_ctx, 0);
3790 LRETURN;
3791 }
3792 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder open session ID:0x%x timestamp:%" PRIu64 "\n",
3793 p_ctx->session_id, p_ctx->session_timestamp);
3794
3795 //Send keep alive timeout Info
3796 uint64_t keep_alive_timeout =
3797 p_ctx->keep_alive_timeout * 1000000; //send us to FW
3798 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
3799 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
3800 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
3801 keep_alive_timeout);
3803 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
3804 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
3805 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
3806 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
3807 CHECK_VPU_RECOVERY(retval);
3808
3809 if (NI_RETCODE_SUCCESS != retval)
3810 {
3811 ni_log2(p_ctx, NI_LOG_ERROR,
3812 "ERROR %s(): nvme write keep_alive_timeout command "
3813 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
3814 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
3816 LRETURN;
3817 }
3818
3819 // Send SW version to FW if FW API version is >= 6.2
3821 "62") >= 0)
3822 {
3823 // Send SW version to session manager
3824 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
3825 memcpy(p_buffer, NI_XCODER_REVISION, sizeof(uint64_t));
3827 ni_fmt_fw_api_ver_str((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], &fmt_fw_api_ver2[0]);
3828 ni_log2(p_ctx, NI_LOG_DEBUG, "%s libxcoder FW API ver %s, FW FW API ver %s\n",
3829 __func__, fmt_fw_api_ver1, fmt_fw_api_ver2);
3830 ui32LBA = CONFIG_SESSION_SWVersion_W(p_ctx->session_id);
3831 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
3832 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
3833 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
3834 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
3835 CHECK_VPU_RECOVERY(retval);
3836
3837 if (NI_RETCODE_SUCCESS != retval)
3838 {
3839 ni_log2(p_ctx, NI_LOG_ERROR,
3840 "ERROR %s(): nvme write sw_version command "
3841 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
3842 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
3844 LRETURN;
3845 }
3846
3847 if (ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sM") >= 0)
3848 {
3849 // For FW API ver 6sM or newer, initialize with the most current size
3850 p_ctx->meta_size = sizeof(ni_metadata_enc_bstream_t);
3851 }
3852 else if (ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rc") >= 0)
3853 {
3854 // For FW API ver 6rc or newer, initialize with the most current size
3856 }
3858 "6p") >= 0)
3859 // For FW API ver 6.p or newer, initialize with the most current size
3861 else
3862 // For FW API ver 6.2 or newer, initialize with the most current size
3864 }
3865 else
3866 {
3867 // For FW API ver 6.1 or older, initialize with metadata size 32
3869 }
3870
3871 // Open AI session for AI Enhance
3872 if(p_param->enable_ai_enhance)
3873 {
3874 // Check if the bit depth & resoultion
3875 if ((p_ctx->bit_depth_factor != 1) ||
3876 !((p_param->source_width == 1280 && p_param->source_height == 720) ||
3877 (p_param->source_width == 1920 && p_param->source_height == 1080) ||
3878 (p_param->source_width == 3840 && p_param->source_height == 2160) ||
3879 (p_param->source_width == 720 && p_param->source_height == 1280) ||
3880 (p_param->source_width == 768 && p_param->source_height == 1280) ||
3881 (p_param->source_width == 1080 && p_param->source_height == 1920) ||
3882 (p_param->source_width == 2496 && p_param->source_height == 1080)))
3883 {
3884 p_param->enable_ai_enhance = 0;
3885 ni_log2(p_ctx, NI_LOG_ERROR, "Resoultion=%dx%d,depth=%d\n",p_param->source_width,p_param->source_height,p_ctx->bit_depth_factor);
3886 ni_log2(p_ctx, NI_LOG_ERROR, "The bit depth or resoultion is not supported on ai enhance mode\n");
3887 }else{
3888 ni_log2(p_ctx, NI_LOG_DEBUG, "Adding ai enhance session to encoder\n");
3889 ui32LBA = OPEN_ADD_CODEC(NI_DEVICE_TYPE_AI, 0, ni_htons(p_ctx->session_id));
3890 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
3891 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
3892
3893 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_open,
3894 p_ctx->device_type, p_ctx->hw_id,
3895 &(p_ctx->session_id), OPT_1);
3896 if (NI_RETCODE_SUCCESS != retval)
3897 {
3898 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR couldn't add ai to encoder session\n");
3899 ni_log2(p_ctx, NI_LOG_ERROR,
3900 "ERROR %s(): p_ctx->device_handle=%" PRIx64 ", "
3901 "p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
3902 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
3903 p_ctx->session_id);
3904 ni_encoder_session_close(p_ctx, 0);
3905 LRETURN;
3906 }
3907 }
3908 }
3909
3911 {
3912 retval = ni_device_set_ddr_configuration(p_ctx, p_param->ddr_priority_mode);
3913 if (NI_RETCODE_SUCCESS != retval)
3914 {
3915 char errmsg[NI_ERRNO_LEN] = {0};
3917 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ddr priority setting failure for %s\n",
3918 __func__, errmsg);
3919 LRETURN;
3920 }
3921 }
3922
3923 ni_log2(p_ctx, NI_LOG_DEBUG, "Open session completed\n");
3924 }
3925
3926 /* Modify mmap_threshold and trim_threshold of malloc */
3927 // calculate the default threshold which equals to the resolution + padding size.
3928 // 64 is AV_INPUT_BUFFER_PADDING_SIZE
3929 m_threshold = p_param->source_width * p_param->source_height * 3 / 2 *
3930 p_ctx->bit_depth_factor + 64;
3931 m_threshold = ((m_threshold + (NI_MEM_PAGE_ALIGNMENT - 1)) /
3933
3934 // The upper limit is DEFAULT_MMAP_THRESHOLD_MAX: 512*1024 on 32-bit systems,
3935 // or 4*1024*1024*sizeof(long) on 64-bit systems.
3936 // This macro is not defined in header file.
3937 // So, assume that is running on 64-bit systems
3938 if (m_threshold > 4 * 1024 * 1024 * sizeof(long))
3939 {
3940 ni_log2(p_ctx, NI_LOG_INFO, "Warning: m_threshold (%d) is bigger than "
3941 "DEFAULT_MMAP_THRESHOLD_MAX, use default value (%d)\n",
3942 m_threshold, 4 * 1024 * 1024 * sizeof(long));
3943 m_threshold = 4 * 1024 * 1024 * sizeof(long);
3944 }
3945
3946 if (p_param->staticMmapThreshold) // Set Static Mmap Threshold
3947 {
3948#if defined(__linux__) && !defined(_ANDROID) && !defined(__OPENHARMONY__)
3949 // If the malloc buffer is larger than the threshold,
3950 // glibc will use mmap to malloc the memory, which is a low speed method.
3951 // So, set the M_MMAP_THRESHOLD >= 1 yuv buffer size here.
3952 if (mallopt(M_MMAP_THRESHOLD, m_threshold) == 0)
3953 {
3954 ni_log2(p_ctx, NI_LOG_ERROR, "Error: could not set M_MMAP_THRESHOLD to %d\n",
3955 m_threshold);
3957 LRETURN;
3958 }
3959
3960 // When the amount of contiguous free memory at the top of the heap
3961 // grows larger than M_TRIM_THRESHOLD,
3962 // free(3) employs sbrk(2) to release this memory back to the system.
3963 // So, set the M_TRIM_THRESHOLD to 3*m_threshold,
3964 // to avoid an inefficient case, frequently releasing and requesting physical memory.
3965 if (mallopt(M_TRIM_THRESHOLD, 3 * m_threshold) == 0)
3966 {
3967 ni_log2(p_ctx, NI_LOG_ERROR, "Error: could not set M_TRIM_THRESHOLD to %ds\n",
3968 3 * m_threshold);
3970 LRETURN;
3971 }
3972#else
3973 ni_log2(p_ctx, NI_LOG_INFO,
3974 "Warning: this platform does not support staticMmapThreshold\n");
3975#endif
3976 }
3977 else // default
3978 {
3979 // a way to dynamically trigger a pre-mature increase in mmap&trim threshold
3980 // make the mmap_threshold larger than frame size to avoid frequent page faults
3981 m_threshold = (int) (m_threshold * 1.25); // An experience value
3982 void *temp_buf = malloc((size_t) m_threshold);
3983 ni_log2(p_ctx, NI_LOG_TRACE, "trigger a pre-mature increase in mmap&trim threshold: 0x%p = malloc(%d)\n",
3984 temp_buf, m_threshold);
3985 free(temp_buf);
3986 }
3987
3988 if (p_ctx->hw_action == NI_CODEC_HW_ENABLE)
3989 {
3990 ni_device_capability_t sender_cap, receiver_cap;
3991 bool device_in_ctxt = true;
3992 retval = ni_device_capability_query2(p_ctx->sender_handle, &sender_cap, device_in_ctxt);
3993 if (retval != NI_RETCODE_SUCCESS)
3994 {
3995 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_device_capability_query2 returned %d\n",
3996 retval);
3997 LRETURN;
3998 }
3999 retval = ni_device_capability_query2(p_ctx->blk_io_handle, &receiver_cap, device_in_ctxt);
4000 if (retval != NI_RETCODE_SUCCESS)
4001 {
4002 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_device_capability_query2 returned %d\n",
4003 retval);
4004 LRETURN;
4005 }
4006
4007 for (uint8_t ui8Index = 0; ui8Index < 20; ui8Index++)
4008 {
4009 if (sender_cap.serial_number[ui8Index] !=
4010 receiver_cap.serial_number[ui8Index])
4011 {
4012 // QDFW-315 Autodownload
4013 p_ctx->auto_dl_handle = p_ctx->sender_handle;
4014 ni_log2(p_ctx, NI_LOG_DEBUG, "Autodownload device handle set %p!\n",
4015 p_ctx->auto_dl_handle);
4016 p_ctx->hw_action = NI_CODEC_HW_NONE;
4017 break;
4018 }
4019 else
4020 {
4022 "6m") >= 0)
4023 {
4024 ni_device_vf_ns_id_t sender_vf_ns_id = {0};
4025 ni_device_vf_ns_id_t curr_vf_ns_id = {0};
4026 retval = ni_query_vf_ns_id(p_ctx->sender_handle, &sender_vf_ns_id, p_ctx->fw_rev);
4027 if (retval != NI_RETCODE_SUCCESS)
4028 {
4029 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: calling ni_query_vf_ns_id(): "
4030 "p_ctx->sender_handle=%" PRIx64 ", p_ctx->hw_id=%d, p_ctx->session_id=%u\n",
4031 (int64_t)p_ctx->sender_handle, p_ctx->hw_id, p_ctx->session_id);
4032 ni_encoder_session_close(p_ctx, 0);
4033 LRETURN;
4034 }
4035 retval = ni_query_vf_ns_id(p_ctx->blk_io_handle, &curr_vf_ns_id, p_ctx->fw_rev);
4036 if (retval != NI_RETCODE_SUCCESS)
4037 {
4038 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: calling ni_query_vf_ns_id(): "
4039 "p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, p_ctx->session_id=%u\n",
4040 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
4041 ni_encoder_session_close(p_ctx, 0);
4042 LRETURN;
4043 }
4044
4045 if ((sender_vf_ns_id.ns_id != curr_vf_ns_id.ns_id) ||
4046 (sender_vf_ns_id.vf_id != curr_vf_ns_id.vf_id))
4047 {
4048 p_ctx->auto_dl_handle = p_ctx->sender_handle;
4049 ni_log2(p_ctx, NI_LOG_DEBUG, "Autodownload device handle set %p!\n",
4050 p_ctx->auto_dl_handle);
4051 p_ctx->hw_action = NI_CODEC_HW_NONE;
4052 break;
4053 }
4054 }
4055 }
4056 }
4057 }
4058
4060 if (NI_RETCODE_SUCCESS != retval)
4061 {
4062 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: calling ni_config_instance_set_encoder_params(): "
4063 "p_ctx->device_handle=%" PRIx64 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
4064 (int64_t)p_ctx->device_handle, p_ctx->hw_id, p_ctx->session_id);
4065 ni_encoder_session_close(p_ctx, 0);
4066 LRETURN;
4067 }
4068 if(p_param->enable_ai_enhance)
4069 {
4070 retval = ni_ai_query_network_ready(p_ctx);
4071 if(retval != NI_RETCODE_SUCCESS)
4072 {
4073 ni_log2(p_ctx, NI_LOG_ERROR,
4074 "ERROR: ni_ai_query_network_ready returned %d\n", retval);
4075 LRETURN;
4076 }
4077 }
4078
4079 ni_timestamp_init(p_ctx, &p_ctx->pts_table, "enc_pts");
4080 ni_timestamp_init(p_ctx, &p_ctx->dts_queue, "enc_dts");
4081
4082 // init close caption SEI header and trailer
4083 memcpy(p_ctx->itu_t_t35_cc_sei_hdr_hevc, g_itu_t_t35_cc_sei_hdr_hevc,
4085 memcpy(p_ctx->itu_t_t35_cc_sei_hdr_h264, g_itu_t_t35_cc_sei_hdr_h264,
4087 memcpy(p_ctx->sei_trailer, g_sei_trailer, NI_CC_SEI_TRAILER_LEN);
4088 // init hdr10+ SEI header
4089 memcpy(p_ctx->itu_t_t35_hdr10p_sei_hdr_hevc, g_itu_t_t35_hdr10p_sei_hdr_hevc,
4091 memcpy(p_ctx->itu_t_t35_hdr10p_sei_hdr_h264, g_itu_t_t35_hdr10p_sei_hdr_h264,
4093
4094 // query to check the final encoder config status
4095 for (;;)
4096 {
4098 NI_DEVICE_TYPE_ENCODER, &buf_info);
4099
4101 p_ctx->device_type, p_ctx->hw_id,
4102 &(p_ctx->session_id), OPT_1);
4103
4105 || NI_RETCODE_FAILURE == retval)
4106 {
4107 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() line-%d return %d\n", __func__, __LINE__, retval);
4108 LRETURN;
4109 }
4110 else if (buf_info.buf_avail_size > 0)
4111 {
4112 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): buf_avail_size %u\n", __func__,
4113 buf_info.buf_avail_size);
4114 break;
4115 }
4116 else
4117 {
4118 ni_usleep(1000);
4119 }
4120 }
4121
4122 ni_log2(p_ctx, NI_LOG_DEBUG,
4123 "%s(): p_ctx->device_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
4124 "p_ctx->session_id=%d\n",
4125 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
4126 p_ctx->session_id);
4127
4128#ifdef XCODER_DUMP_DATA
4129 char dir_name[256] = {0};
4130 snprintf(dir_name, sizeof(dir_name), "%ld-%u-enc-pkt", (long)getpid(),
4131 p_ctx->session_id);
4132 DIR *dir = opendir(dir_name);
4133 if (!dir && ENOENT == NI_ERRNO)
4134 {
4135 mkdir(dir_name, S_IRWXU | S_IRWXG | S_IRWXO);
4136 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder pkt dump dir created: %s\n", dir_name);
4137 }
4138
4139 if(dir){
4140 closedir(dir);
4141 }
4142
4143 snprintf(dir_name, sizeof(dir_name), "%ld-%u-enc-fme", (long)getpid(),
4144 p_ctx->session_id);
4145 dir = opendir(dir_name);
4146 if (!dir && ENOENT == NI_ERRNO)
4147 {
4148 mkdir(dir_name, S_IRWXU | S_IRWXG | S_IRWXO);
4149 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder frame dump dir created: %s\n", dir_name);
4150 }
4151 if(dir){
4152 closedir(dir);
4153 }
4154#endif
4155
4156END:
4157
4158 ni_aligned_free(p_buffer);
4159 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
4160
4161 return retval;
4162}
4163
4164/*!******************************************************************************
4165 * \brief Flush encoder output
4166 *
4167 * \param
4168 *
4169 * \return
4170 *******************************************************************************/
4172{
4173 ni_retcode_t retval;
4174 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
4175 if (!p_ctx)
4176 {
4177 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
4178 __func__);
4179 retval = NI_RETCODE_INVALID_PARAM;
4180 LRETURN;
4181 }
4182
4183 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
4184 {
4185 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
4186 __func__);
4188 LRETURN;
4189 }
4190
4193 p_ctx->device_type, p_ctx->hw_id,
4194 &(p_ctx->session_id), OPT_1);
4195 CHECK_VPU_RECOVERY(retval);
4196
4197END:
4198
4199 if (NI_RETCODE_SUCCESS != retval)
4200 {
4201 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): %d, return\n", __func__, retval);
4202 }
4203
4204 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
4205
4206 return retval;
4207}
4208
4209/*!******************************************************************************
4210 * \brief Close a xcoder encoder instance
4211 *
4212 * \param
4213 *
4214 * \return
4215 *******************************************************************************/
4217{
4219 void* p_buffer = NULL;
4220 uint32_t ui32LBA = 0;
4221 int i = 0;
4222 ni_xcoder_params_t *p_param = NULL;
4223
4224 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
4225
4226 if (!p_ctx)
4227 {
4228 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
4229 __func__);
4231 }
4232
4234
4235 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
4236 {
4237 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): Invalid session ID, return.\n", __func__);
4238 retval = NI_RETCODE_SUCCESS;
4239 LRETURN;
4240 }
4241
4242 if (p_ctx->device_type == NI_DEVICE_TYPE_ENCODER)
4243 {
4244 ni_log2(p_ctx, NI_LOG_INFO,
4245 "Encoder_complete_info:session_id 0x%x, total frames input:%u "
4246 "buffered: %u completed: %u output: %u dropped: %u error: %u\n",
4253 }
4254
4255 //malloc data buffer
4256 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
4257 {
4258 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
4259 NI_ERRNO, __func__);
4261 LRETURN;
4262 }
4263 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
4264
4265 if (p_ctx->p_session_config)
4266 {
4267 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
4269 {
4271 if (NI_RETCODE_SUCCESS != retval)
4272 {
4273 char errmsg[NI_ERRNO_LEN] = {0};
4275 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ddr priority setting failure for %s\n",
4276 __func__, errmsg);
4277 LRETURN;
4278 }
4279 }
4280 }
4281
4283
4284 int retry = 0;
4285 while (retry < NI_SESSION_CLOSE_RETRY_MAX)
4286 {
4287 ni_log2(p_ctx, NI_LOG_DEBUG,
4288 "%s(): p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
4289 "p_ctx->session_id=%d, close_mode=1\n",
4290 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
4291 p_ctx->session_id);
4292
4294 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
4295 {
4296 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): command failed\n", __func__);
4299 break;
4300 } else
4301 {
4302 //Close should always succeed
4303 retval = NI_RETCODE_SUCCESS;
4305 break;
4306 }
4307 /*
4308 else if(((ni_session_closed_status_t *)p_buffer)->session_closed)
4309 {
4310 retval = NI_RETCODE_SUCCESS;
4311 p_ctx->session_id = NI_INVALID_SESSION_ID;
4312 break;
4313 }
4314 else
4315 {
4316 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): wait for close\n");
4317 ni_usleep(NI_SESSION_CLOSE_RETRY_INTERVAL_US);
4318 retval = NI_RETCODE_ERROR_NVME_CMD_FAILED;
4319 }
4320 */
4321 retry++;
4322 }
4323
4324END:
4325
4326 ni_aligned_free(p_buffer);
4328
4329 //Sequence change related stuff cleanup here
4330 p_ctx->active_video_width = 0;
4331 p_ctx->active_video_height = 0;
4332 p_ctx->actual_video_width = 0;
4333 //End of sequence change related stuff cleanup
4334
4335 if (p_ctx->pts_table)
4336 {
4337 ni_queue_free(&p_ctx->pts_table->list, p_ctx->buffer_pool);
4338 ni_memfree(p_ctx->pts_table);
4339 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_timestamp_done: success\n");
4340 }
4341
4342 if (p_ctx->dts_queue)
4343 {
4344 ni_queue_free(&p_ctx->dts_queue->list, p_ctx->buffer_pool);
4345 ni_memfree(p_ctx->dts_queue);
4346 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_timestamp_done: success\n");
4347 }
4348
4350 p_ctx->buffer_pool = NULL;
4351
4352 for (i = 0; i < NI_FIFO_SZ; i++)
4353 {
4354 ni_memfree(p_ctx->pkt_custom_sei_set[i]);
4355 }
4356
4357 for (i = 0; i < 120 ; i++)
4358 {
4359 if (p_ctx->input_frame_fifo[i].p_input_buffer != NULL)
4360 {
4361 free(p_ctx->input_frame_fifo[i].p_input_buffer);
4362 p_ctx->input_frame_fifo[i].p_input_buffer = NULL;
4363 }
4364 }
4365
4366 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): CTX[Card:%" PRIx64 " / HW:%d / INST:%d]\n",
4367 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
4368 p_ctx->session_id);
4369 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
4370
4371 low_delay_signal(p_ctx);
4373
4374 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
4375
4376 return retval;
4377}
4378
4379
4380void enqueue_ni_frame(ni_session_context_t *p_ctx, ni_frame_t *ni_frame, int32_t source_width, int32_t source_height)
4381{
4382 int32_t width_stride[4] = {0};
4383 int32_t height_stride[4] = {0};
4384
4385 if (((ni_xcoder_params_t *)(p_ctx->p_session_config))->zerocopy_mode &&
4386 ((ni_xcoder_params_t *)(p_ctx->p_session_config))->luma_linesize != 0 &&
4387 ((ni_xcoder_params_t *)(p_ctx->p_session_config))->chroma_linesize != 0)
4388 {
4389 //zero copy happend
4390 width_stride[0] = ((ni_xcoder_params_t *)(p_ctx->p_session_config))->luma_linesize;
4391 width_stride[1] = width_stride[2] = ((ni_xcoder_params_t *)(p_ctx->p_session_config))->chroma_linesize;
4392 }
4393 else
4394 {
4395 int is_semiplanar = !ni_get_planar_from_pixfmt(p_ctx->pixel_format);
4396 ni_get_hw_yuv420p_dim(ni_frame->video_width, ni_frame->video_height,
4397 p_ctx->bit_depth_factor, is_semiplanar,
4398 width_stride, height_stride);
4399 }
4400
4401 for (int i = 0; i < 120; i++)
4402 {
4403 // ni_log2(p_ctx, NI_LOG_ERROR, "%s %d i %d frame_num %d p_input_buffer %p data_len[0:2] %d %d %d p_data[0:2] %p %p %p video_width %d video_height %d\n",
4404 // __FUNCTION__, __LINE__, i, p_ctx->frame_num, p_ctx->input_frame_fifo[i].p_input_buffer,
4405 // ni_frame->data_len[0], ni_frame->data_len[1], ni_frame->data_len[2],
4406 // ni_frame->p_data[0], ni_frame->p_data[1], ni_frame->p_data[2],
4407 // ni_frame->video_width, ni_frame->video_height);
4408 if ((source_width != p_ctx->input_frame_fifo[i].video_width ||
4409 source_height != p_ctx->input_frame_fifo[i].video_height) &&
4410 p_ctx->input_frame_fifo[i].p_input_buffer != NULL &&
4411 p_ctx->input_frame_fifo[i].usable == 1)
4412 {
4413 free(p_ctx->input_frame_fifo[i].p_input_buffer);
4414 p_ctx->input_frame_fifo[i].p_input_buffer = NULL;
4415 p_ctx->input_frame_fifo[i].usable = -1;
4416 }
4417
4418 if (p_ctx->input_frame_fifo[i].p_input_buffer == NULL)
4419 {
4420 p_ctx->input_frame_fifo[i].p_input_buffer = (uint8_t *)malloc(source_width * p_ctx->bit_depth_factor * source_height * 3 / 2);
4421
4422 for (int j = 0; j < source_height; j++)
4423 {
4424 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + source_width * p_ctx->bit_depth_factor * j,
4425 ni_frame->p_data[0] + j * width_stride[0],
4426 source_width * p_ctx->bit_depth_factor);
4427 }
4428 for (int j = 0; j < (source_height + 1) / 2; j++)
4429 {
4430 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + source_width * p_ctx->bit_depth_factor * source_height + (source_width * p_ctx->bit_depth_factor / 2) * j,
4431 ni_frame->p_data[1] + j * width_stride[1],
4432 source_width / 2 * p_ctx->bit_depth_factor);
4433 }
4434 for (int j = 0; j < (source_height + 1) / 2; j++)
4435 {
4436 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + source_width * p_ctx->bit_depth_factor * source_height * 5 / 4 + (source_width * p_ctx->bit_depth_factor / 2) * j,
4437 ni_frame->p_data[2] + j * width_stride[2],
4438 source_width / 2 * p_ctx->bit_depth_factor);
4439 }
4440
4441 p_ctx->input_frame_fifo[i].video_width = source_width;
4442 p_ctx->input_frame_fifo[i].video_height = source_height;
4443
4444 p_ctx->input_frame_fifo[i].usable = -1;
4445 p_ctx->input_frame_fifo[i].pts = ni_frame->pts;
4446 // ni_log2(p_ctx, NI_LOG_DEBUG, "%s %d i %d frame_num %d buffer_size %d video_width %d video_height %d pts %lld\n",
4447 // __FUNCTION__, __LINE__, i, p_ctx->frame_num, ni_frame->buffer_size, ni_frame->video_width, ni_frame->video_height,
4448 // p_ctx->input_frame_fifo[i].pts);
4449 break;
4450 }
4451 else if (p_ctx->input_frame_fifo[i].usable == 1)
4452 {
4453 for (int j = 0; j < source_height; j++)
4454 {
4455 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + source_width * p_ctx->bit_depth_factor * j,
4456 ni_frame->p_data[0] + j * width_stride[0],
4457 source_width * p_ctx->bit_depth_factor);
4458 }
4459 for (int j = 0; j < (source_height + 1) / 2; j++)
4460 {
4461 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + source_width * p_ctx->bit_depth_factor * source_height + (source_width * p_ctx->bit_depth_factor / 2) * j,
4462 ni_frame->p_data[1] + j * width_stride[1],
4463 source_width / 2 * p_ctx->bit_depth_factor);
4464 }
4465 for (int j = 0; j < (source_height + 1) / 2; j++)
4466 {
4467 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + source_width * p_ctx->bit_depth_factor * source_height * 5 / 4 + (source_width * p_ctx->bit_depth_factor / 2) * j,
4468 ni_frame->p_data[2] + j * width_stride[2],
4469 source_width / 2 * p_ctx->bit_depth_factor);
4470 }
4471
4472 p_ctx->input_frame_fifo[i].video_width = source_width;
4473 p_ctx->input_frame_fifo[i].video_height = source_height;
4474
4475 p_ctx->input_frame_fifo[i].usable = -1;
4476 p_ctx->input_frame_fifo[i].pts = ni_frame->pts;
4477 break;
4478 }
4479 }
4480}
4481
4482/*!******************************************************************************
4483 * \brief Send a YUV p_frame to encoder
4484 *
4485 * \param
4486 *
4487 * \return
4488 *******************************************************************************/
4490{
4491 bool ishwframe = false;
4492 uint32_t size = 0;
4493 uint32_t send_count = 0;
4494 uint32_t i = 0;
4495 uint32_t sent_size = 0;
4496 uint32_t frame_size_bytes = 0;
4497 int retval = 0;
4498 ni_instance_buf_info_t buf_info = { 0 };
4499 ni_session_statistic_t sessionStatistic = {0};
4500
4501 if (!p_ctx || !p_frame)
4502 {
4503 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
4504 __func__);
4506 }
4507 ishwframe = p_ctx->hw_action & NI_CODEC_HW_ENABLE;
4508 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter hw=%d\n", __func__, ishwframe);
4509
4510 if (ishwframe && !p_frame->end_of_stream)
4511 {
4512 // check if the hw input frame is valid
4513 if (!p_frame->p_data[3])
4514 {
4515 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() hw input frame is null!, return\n",
4516 __func__);
4518 }
4519 uint16_t input_frame_idx = ((niFrameSurface1_t*)(p_frame->p_data[3]))->ui16FrameIdx;
4520 if (!((input_frame_idx > 0 &&
4521 input_frame_idx < NI_GET_MAX_HWDESC_FRAME_INDEX(p_ctx->ddr_config)) ||
4522 (input_frame_idx > NI_GET_MIN_HWDESC_P2P_BUF_ID(p_ctx->ddr_config) &&
4523 input_frame_idx <= NI_GET_MAX_HWDESC_P2P_BUF_ID(p_ctx->ddr_config))))
4524 {
4525 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): got invalid frameIdx [%u]\n",
4526 __func__, input_frame_idx);
4528 }
4529 }
4530
4532
4533 uint8_t separate_metadata = p_frame->separate_metadata;
4534
4535 uint8_t separate_start = (p_frame->separate_start && p_frame->total_start_len) ? 1 : 0;
4536
4537 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
4538 {
4539 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
4540 __func__);
4542 LRETURN;
4543 }
4544
4545 low_delay_wait(p_ctx);
4546
4547#ifdef MEASURE_LATENCY
4548 if ((p_frame->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
4549 {
4550 uint64_t abs_time_ns = ni_gettime_ns();
4551 ni_lat_meas_q_t *frame_time_q = (ni_lat_meas_q_t *)p_ctx->frame_time_q;
4552 ni_lat_meas_q_add_entry(frame_time_q, abs_time_ns, p_frame->dts);
4553 }
4554#endif
4555
4556 /*!********************************************************************/
4557 /*!************ Sequence Change related stuff *************************/
4558 //First check squence changed related stuff.
4559 //We need to record the current hight/width params if we didn't do it before:
4560
4561 if( p_frame->video_height)
4562 {
4563 p_ctx->active_video_width = p_frame->data_len[0] / p_frame->video_height;
4564 p_ctx->active_video_height = p_frame->video_height;
4565 }
4566 else if (p_frame->video_width)
4567 {
4568 ni_log2(p_ctx, NI_LOG_DEBUG, "WARNING: passed video_height is not valid!, return\n");
4569 p_ctx->active_video_height = p_frame->data_len[0] / p_frame->video_width;
4570 p_ctx->active_video_width = p_frame->video_width;
4571 }
4572 else
4573 {
4574 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: passed video_height and video_width are not valid!, return\n");
4576 LRETURN;
4577 }
4578 // record actual width (in pixels / without padding) for sequnce change detection
4579 p_ctx->actual_video_width = p_frame->video_width;
4580
4581 /*!************ Sequence Change related stuff end*************************/
4582 /*!********************************************************************/
4583
4584 frame_size_bytes = p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2] + p_frame->data_len[3] + p_frame->extra_data_len;
4585 ni_log2(p_ctx, NI_LOG_DEBUG,
4586 "%s: data_len[0] %u data_len[1] %u "
4587 "data_len[2] %u extra_data_len %u frame_size_bytes %u\n",
4588 __func__, p_frame->data_len[0], p_frame->data_len[1],
4589 p_frame->data_len[2], p_frame->extra_data_len, frame_size_bytes);
4590
4591 // skip query write buffer because we just send EOS
4592 if (!p_frame->end_of_stream)
4593 {
4594 for (;;)
4595 {
4596 query_sleep(p_ctx);
4597
4599 "65") >= 0)
4600 {
4602 p_ctx, NI_DEVICE_TYPE_ENCODER, &sessionStatistic);
4603 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
4605 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
4606 CHECK_VPU_RECOVERY(retval);
4607 buf_info.buf_avail_size = sessionStatistic.ui32WrBufAvailSize;
4608 } else
4609 {
4610 retval =
4612 NI_DEVICE_TYPE_ENCODER, &buf_info);
4613 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
4614 p_ctx->device_type, p_ctx->hw_id,
4615 &(p_ctx->session_id), OPT_1);
4616 CHECK_VPU_RECOVERY(retval);
4617 }
4618
4619 if (NI_RETCODE_FAILURE == retval)
4620 {
4621 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() line-%d retrun %d\n", __func__, __LINE__, retval);
4622 LRETURN;
4623 }
4624 else if (NI_RETCODE_SUCCESS != retval ||
4625 buf_info.buf_avail_size < frame_size_bytes)
4626 {
4627 ni_log2(p_ctx, NI_LOG_TRACE,
4628 "Enc write query retry %d. rc=%d. Available buf size %u < "
4629 "frame size %u\n", retval, send_count,
4630 buf_info.buf_avail_size, frame_size_bytes);
4631 if (send_count >= NI_MAX_ENCODER_QUERY_RETRIES)
4632 {
4633 int retval_backup = retval;
4637 {
4638 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
4639 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
4640 CHECK_VPU_RECOVERY(retval);
4641 }
4642 else
4643 retval = NI_RETCODE_SUCCESS;
4644
4645 ni_log2(p_ctx, NI_LOG_DEBUG,
4646 "Enc write query buf info exceeded max retries: "
4647 "%d, rc=%d. Available buf size %u < frame size %u\n",
4648 NI_MAX_ENCODER_QUERY_RETRIES, retval_backup,
4649 buf_info.buf_avail_size, frame_size_bytes);
4651
4652 LRETURN;
4653 }
4654 send_count++;
4658 } else
4659 {
4660 ni_log2(p_ctx, NI_LOG_DEBUG,
4661 "Info enc write query success, available buf "
4662 "size %u >= frame size %u !\n",
4663 buf_info.buf_avail_size, frame_size_bytes);
4664 break;
4665 }
4666 }
4667 }
4668
4669 // fill in metadata such as timestamp
4671 if (separate_metadata)
4672 {
4673 p_meta = (ni_metadata_enc_frame_t *)p_frame->p_metadata_buffer;
4674 } else
4675 {
4676 p_meta = (ni_metadata_enc_frame_t *)((uint8_t *)
4677 p_frame->p_data[2 + ishwframe] +
4678 p_frame->data_len[2 + ishwframe]);
4679 }
4680
4681 if (p_meta) //When hwframe xcoding reaches eos, frame looks like swframe but no allocation for p_meta
4682 {
4683 p_meta->metadata_common.ui64_data.frame_tstamp = (uint64_t)p_frame->pts;
4684
4685 p_meta->force_headers = 0; // p_frame->force_headers not implemented/used
4688 p_meta->use_long_term_ref = p_frame->use_long_term_ref;
4689
4690 ni_log2(p_ctx, NI_LOG_DEBUG,
4691 "%s: p_meta "
4692 "use_cur_src_as_long_term_pic %d use_long_term_ref %d\n",
4693 __func__, p_meta->use_cur_src_as_long_term_pic,
4694 p_meta->use_long_term_ref);
4695
4696 p_meta->frame_force_type_enable = p_meta->frame_force_type = 0;
4697 // frame type to be forced to is supposed to be set correctly
4698 // in p_frame->ni_pict_type
4699 if (1 == p_ctx->force_frame_type || p_frame->force_key_frame)
4700 {
4701 if (p_frame->ni_pict_type)
4702 {
4703 p_meta->frame_force_type_enable = 1;
4704 p_meta->frame_force_type = p_frame->ni_pict_type;
4705 }
4706 ni_log2(p_ctx, NI_LOG_DEBUG,
4707 "%s(): ctx->force_frame_type"
4708 " %d frame->force_key_frame %d force frame_num %" PRIu64 ""
4709 " type to %d\n",
4710 __func__, p_ctx->force_frame_type, p_frame->force_key_frame,
4711 p_ctx->frame_num, p_frame->ni_pict_type);
4712 }
4713
4714 // force pic qp if specified
4715 p_meta->force_pic_qp_enable = p_meta->force_pic_qp_i =
4716 p_meta->force_pic_qp_p = p_meta->force_pic_qp_b = 0;
4717 if (p_frame->force_pic_qp)
4718 {
4719 p_meta->force_pic_qp_enable = 1;
4720 p_meta->force_pic_qp_i = p_meta->force_pic_qp_p =
4721 p_meta->force_pic_qp_b = p_frame->force_pic_qp;
4722 }
4723 p_meta->frame_sei_data_size = p_frame->sei_total_len;
4724 p_meta->frame_roi_map_size = p_frame->roi_len;
4725 p_meta->frame_roi_avg_qp = p_ctx->roi_avg_qp;
4726 p_meta->enc_reconfig_data_size = p_frame->reconf_len;
4727 p_meta->hor_adjust_offset = p_frame->hor_adjust_offset / ((p_ctx->src_bit_depth == 10) ? 2 : 1);
4728 // Reset it for the next frame
4729 p_frame->hor_adjust_offset = 0;
4730 ni_log2(p_ctx, NI_LOG_DEBUG,
4731 "### %s(): p_meta->hor_adjust_offset %d src_bit_depth %d\n", __func__, p_meta->hor_adjust_offset, p_ctx->src_bit_depth);
4732
4734 "6Q") >= 0)
4735 {
4736 if (separate_start)
4737 {
4738 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
4739 p_meta->start_len[i] = p_frame->start_len[i];
4740 }
4741 else
4742 {
4743 memset(p_meta->start_len, 0, sizeof(p_meta->start_len));
4744 }
4746 }
4747
4748 if (p_ctx->frame_num % ((ni_xcoder_params_t *)(p_ctx->p_session_config))->interval_of_psnr == 0)
4749 p_meta->get_recon_frame_mode = ((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode;
4750 else
4751 p_meta->get_recon_frame_mode = 3;
4752
4753 ni_log2(p_ctx,
4755 "%s(): %d.%u p_ctx->frame_num=%" PRIu64 ", "
4756 "p_frame->start_of_stream=%u, p_frame->end_of_stream=%u, "
4757 "p_frame->video_width=%u, p_frame->video_height=%u, pts=0x%08x 0x%08x, "
4758 "dts=0x%08x 0x%08x, sei_len=%u, roi size=%u avg_qp=%u reconf_len=%u "
4759 "force_pic_qp=%u use_cur_src_as_long_term_pic %u use_long_term_ref "
4760 "%u start_len [%u,%u,%u] inconsecutive_transfer %u "
4761 "get_recon_frame_mode %u\n",
4762 __func__, p_ctx->hw_id, p_ctx->session_id, p_ctx->frame_num,
4763 p_frame->start_of_stream, p_frame->end_of_stream, p_frame->video_width,
4764 p_frame->video_height, (uint32_t)((p_frame->pts >> 32) & 0xFFFFFFFF),
4765 (uint32_t)(p_frame->pts & 0xFFFFFFFF),
4766 (uint32_t)((p_frame->dts >> 32) & 0xFFFFFFFF),
4767 (uint32_t)(p_frame->dts & 0xFFFFFFFF), p_meta->frame_sei_data_size,
4768 p_meta->frame_roi_map_size, p_meta->frame_roi_avg_qp,
4769 p_meta->enc_reconfig_data_size, p_meta->force_pic_qp_i,
4771 p_meta->start_len[0], p_meta->start_len[1], p_meta->start_len[2],
4772 p_meta->inconsecutive_transfer,
4773 p_meta->get_recon_frame_mode);
4774 }
4775 if (p_frame->start_of_stream)
4776 {
4777 //Send Start of stream p_config command here
4780 p_ctx->device_type, p_ctx->hw_id,
4781 &(p_ctx->session_id), OPT_1);
4782 CHECK_VPU_RECOVERY(retval);
4783 if (NI_RETCODE_SUCCESS != retval)
4784 {
4785 LRETURN;
4786 }
4787
4788 p_frame->start_of_stream = 0;
4789 }
4790
4791 // skip direct to send eos without sending the passed in p_frame as it's been sent already
4792 if (p_frame->end_of_stream)
4793 {
4796 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
4797 CHECK_VPU_RECOVERY(retval);
4798 if (NI_RETCODE_SUCCESS != retval)
4799 {
4800 LRETURN;
4801 }
4802
4803 p_frame->end_of_stream = 0;
4804 p_ctx->ready_to_close = 1;
4805 } else //handle regular frame sending
4806 {
4807 retval = ni_timestamp_register(p_ctx->buffer_pool, p_ctx->dts_queue,
4808 p_frame->dts, 0);
4809 if (NI_RETCODE_SUCCESS != retval)
4810 {
4811 ni_log2(p_ctx, NI_LOG_ERROR,
4812 "ERROR %s(): "
4813 "ni_timestamp_register() for dts returned: %d\n",
4814 __func__, retval);
4815 }
4816
4817 if (separate_metadata)
4818 {
4819 uint32_t ui32LBA_metadata =
4821 ni_log2(p_ctx, NI_LOG_DEBUG,
4822 "%s: p_metadata_buffer = %p, metadata_buffer_size "
4823 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
4824 __func__, p_frame->p_metadata_buffer,
4825 p_frame->metadata_buffer_size, p_ctx->frame_num,
4826 ui32LBA_metadata);
4827
4828 sent_size =
4830
4831 retval = ni_nvme_send_write_cmd(
4832 p_ctx->blk_io_handle, p_ctx->event_handle,
4833 p_frame->p_metadata_buffer, sent_size,
4834 ui32LBA_metadata);
4835 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
4836 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
4837 CHECK_VPU_RECOVERY(retval);
4838 if (retval < 0)
4839 {
4840 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n",
4841 __func__);
4843 LRETURN;
4844 }
4845 }
4846
4847 if (separate_start)
4848 {
4849 uint32_t ui32LBA =
4851 ni_log2(p_ctx, NI_LOG_DEBUG,
4852 "%s: p_start_buffer = %p, p_frame->start_buffer_size "
4853 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
4854 __func__, p_frame->p_start_buffer, p_frame->start_buffer_size, p_ctx->frame_num,
4855 ui32LBA);
4856
4857 sent_size =
4859
4860 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
4861 p_frame->p_start_buffer, sent_size, ui32LBA);
4862 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
4863 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
4864 CHECK_VPU_RECOVERY(retval);
4865 if (retval < 0)
4866 {
4867 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
4869 LRETURN;
4870 }
4871 }
4872
4873 if (p_frame->inconsecutive_transfer)
4874 {
4875 uint32_t ui32LBA =
4877
4878 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
4879 {
4880 ni_log2(p_ctx, NI_LOG_DEBUG,
4881 "%s: p_data = %p, p_frame->buffer_size "
4882 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
4883 __func__, p_frame->p_data, p_frame->buffer_size, p_ctx->frame_num,
4884 ui32LBA);
4885
4886 if (p_frame->data_len[i])
4887 {
4888 sent_size = p_frame->data_len[i];
4889 if (separate_start)
4890 sent_size -= p_frame->start_len[i];
4891
4892 sent_size =
4894
4895 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
4896 p_frame->p_data[i]+p_frame->start_len[i], sent_size, ui32LBA);
4897 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
4898 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
4899 CHECK_VPU_RECOVERY(retval);
4900 if (retval < 0)
4901 {
4902 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
4904 LRETURN;
4905 }
4906 }
4907 }
4908 }
4909 else
4910 {
4911 uint32_t ui32LBA =
4913 ni_log2(p_ctx, NI_LOG_DEBUG,
4914 "%s: p_data = %p, p_frame->buffer_size "
4915 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
4916 __func__, p_frame->p_data, p_frame->buffer_size, p_ctx->frame_num,
4917 ui32LBA);
4918
4919 sent_size = frame_size_bytes;
4920 if (separate_metadata)
4921 sent_size -= p_frame->extra_data_len;
4922 if (separate_start)
4923 sent_size -= p_frame->total_start_len;
4924
4925 sent_size =
4927
4928 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
4929 p_frame->p_buffer+p_frame->total_start_len, sent_size, ui32LBA);
4930 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
4931 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
4932 CHECK_VPU_RECOVERY(retval);
4933 if (retval < 0)
4934 {
4935 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
4937 LRETURN;
4938 }
4939 }
4940
4941 //Save input frame data used for calculate PSNR
4942 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rc") >= 0) &&
4943 (p_ctx->frame_num == 0 || ((p_ctx->frame_num % ((ni_xcoder_params_t *)(p_ctx->p_session_config))->interval_of_psnr) == 0)) &&
4944 (((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode < 3) &&
4945 (!(((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode == 2 && p_ctx->codec_format == NI_CODEC_FORMAT_H265)))
4946 {
4947 if (ishwframe && !p_frame->end_of_stream)
4948 {
4949 // uint16_t input_frame_idx = ((niFrameSurface1_t*)(p_frame->p_data[3]))->ui16FrameIdx;
4950 // use hwdownload to download hw frame, but donot recycle hwframe buffer
4951 ni_session_data_io_t hwdl_session_data = {0};
4952 // ni_log2(p_ctx, NI_LOG_ERROR, "pixel_format %d\n", p_ctx->pixel_format);
4953 int ret = hwdl_frame(p_ctx, &hwdl_session_data, p_frame,
4954 p_frame->pixel_format);
4955 if (ret <= 0)
4956 {
4957 ni_frame_buffer_free(&(hwdl_session_data.data.frame));
4958 return ret;
4959 }
4960
4961 hwdl_session_data.data.frame.pts = p_frame->pts;
4962 enqueue_ni_frame(p_ctx, &hwdl_session_data.data.frame, p_frame->video_width, p_frame->video_height);
4963 ni_frame_buffer_free(&hwdl_session_data.data.frame);
4964 }
4965 else
4966 {
4967 enqueue_ni_frame(p_ctx, p_frame, p_frame->video_width, p_frame->video_height);
4968 }
4969 }
4970
4971 if (ishwframe)
4972 {
4973 ni_log2(p_ctx, NI_LOG_DEBUG,
4974 "%s(): session=0x%x ui16FrameIdx=%u\n",
4975 __func__,
4976 p_ctx->session_id,
4977 ((niFrameSurface1_t*)(p_frame->p_data[3]))->ui16FrameIdx);
4978 }
4979
4980 p_ctx->status = 0;
4981 p_ctx->frame_num++;
4982 size = frame_size_bytes;
4983 p_ctx->low_delay_sync_flag = 1;
4984
4985#ifdef XCODER_DUMP_DATA
4986 char dump_file[256];
4987 snprintf(dump_file, sizeof(dump_file), "%ld-%u-enc-fme/fme-%04ld.yuv",
4988 (long)getpid(), p_ctx->session_id, (long)p_ctx->frame_num);
4989
4990 FILE *f = NULL;
4991 ni_fopen(&f, dump_file, "wb");
4992 fwrite(p_frame->p_buffer,
4993 p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2],
4994 1, f);
4995 fflush(f);
4996 fclose(f);
4997#endif
4998 }
4999
5000 retval = size;
5001
5002END:
5003
5005
5006 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
5007 return retval;
5008}
5009
5010// DEBUG
5011#if 0
5012// write bitstream features to log file
5013static void ni_write_bitstream_features_internal(ni_session_context_t *p_enc_ctx, ni_packet_t *p_out_pkt)
5014{
5016 int video_codec_id = VODEO_CODEC_ID_H264;
5017 int profile = H264_CODEC_PROFILE_MAIN;
5018
5019 if (!p_enc_ctx || !p_out_pkt || !p_enc_ctx->p_session_config ||
5020 !(((ni_xcoder_params_t *)(p_enc_ctx->p_session_config))->cfg_enc_params.getBitstreamFeatures))
5021 {
5022 return;
5023 }
5024
5026 (p_out_pkt->frame_type == NI_QUADRA_PREDICTED_FRAME) ? ITU_FRAME_TYPE_P :
5028
5029 video_codec_id = (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) ? VODEO_CODEC_ID_H264 :
5030 (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H265) ? VODEO_CODEC_ID_HEVC :
5031 (p_enc_ctx->codec_format == NI_CODEC_FORMAT_AV1) ? VODEO_CODEC_ID_AV1 : 0;
5032
5033 profile = ((ni_xcoder_params_t *)(p_enc_ctx->p_session_config))->cfg_enc_params.profile;
5034
5035 switch (video_codec_id)
5036 {
5042 break;
5044 profile = (profile == NI_QUADRA_HEVC_PROFILE_MAIN) ? HEVC_CODEC_PROFILE_MAIN :
5046 break;
5047 case VODEO_CODEC_ID_AV1:
5048 profile = (profile == NI_QUADRA_AV1_PROFILE_MAIN) ? AV1_CODEC_PROFILE_MAIN : 0;
5049 break;
5050 default:
5051 profile = 0;
5052 break;
5053 }
5054
5055
5056 int frame_size = (p_enc_ctx->pkt_num == 1) ? p_enc_ctx->headers_length + p_out_pkt->data_len - p_enc_ctx->meta_size : p_out_pkt->data_len - p_enc_ctx->meta_size;
5057 int quality_pixel_count = p_enc_ctx->actual_video_width * p_enc_ctx->active_video_height;
5058 ni_bitstream_features_t *bitstream_features = &p_out_pkt->bitstream_features;
5059
5060 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: pkt #%" PRId64 " Bitstream Features - "
5061 "Av_QP: f=%.6f FrameSize: i32=%d InitialQP: i32=%d max_QP: i32=%d MbQPs_1_: f=%.6f "
5062 "FrameType: i32=%d Sec_Codec: i32=%d Seq_Profile: i32=%d "
5063 "MbQPs_5_: f=%.6f MbQPs_6_: f=%.6f AnalyzedMBs: i32=%d "
5064 "MbTypes_5_: i32=%d MbTypes_6_: i32=%d MbTypes_0_: i32=%d MbTypes_1_: i32=%d "
5065 "quality_pixel_count: i32=%d\n",
5066 __func__, p_enc_ctx->pkt_num,
5067 bitstream_features->average_qp, frame_size,
5068 bitstream_features->initial_qp, bitstream_features->max_qp, bitstream_features->avg_forward_pred_block_qp,
5069 itu_frame_type, video_codec_id, profile,
5070 bitstream_features->avg_intra_block_qp, bitstream_features->avg_intra_plane_qp, bitstream_features->analyzed_mbs,
5071 bitstream_features->num_intra_block_blocks, bitstream_features->num_intra_plane_blocks, bitstream_features->num_skip_blocks, bitstream_features->num_forward_pred_blocks,
5072 quality_pixel_count);
5073}
5074#endif
5075
5077{
5078 ni_instance_mgr_stream_info_t data = { 0 };
5079 uint32_t actual_read_size = 0;
5080 uint32_t to_read_size = 0;
5081 int size = 0;
5082 static long long encq_count = 0LL;
5083 int retval = NI_RETCODE_SUCCESS;
5084 int query_retry = 0;
5085 int query_type = INST_BUF_INFO_RW_READ;
5086 uint32_t ui32LBA = 0;
5087 ni_metadata_enc_bstream_t *p_meta = NULL;
5088 ni_metadata_enc_bstream_rev61_t *p_meta_rev61 = NULL;
5089 ni_instance_buf_info_t buf_info = { 0 };
5090 ni_session_statistic_t sessionStatistic = {0};
5091 int low_delay_notify = 0;
5092 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
5093
5094 if (!p_ctx || !p_packet || !p_packet->p_data)
5095 {
5096 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
5097 __func__);
5098 retval = NI_RETCODE_INVALID_PARAM;
5099 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
5100
5101 return retval;
5102 }
5103
5105
5106 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
5107 {
5108 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
5109 __func__);
5111 LRETURN;
5112 }
5113
5114 ni_log2(p_ctx, NI_LOG_DEBUG, "frame_num=%" PRIu64 ", pkt_num=%" PRIu64 ", av1_pkt_num=%" PRIu64 "\n",
5115 p_ctx->frame_num, p_ctx->pkt_num, p_ctx->av1_pkt_num);
5116 if (((ni_xcoder_params_t *)p_ctx->p_session_config)->low_delay_mode)
5117 {
5118 query_type = INST_BUF_INFO_RW_READ_BUSY;
5119 if (!p_packet->end_of_stream && p_ctx->frame_num < p_ctx->pkt_num)
5120 {
5121 if (p_ctx->ready_to_close)
5122 {
5123 query_type = INST_BUF_INFO_RW_READ;
5124 } else
5125 { //nothing to query, leave
5126 retval = NI_RETCODE_SUCCESS;
5127 low_delay_notify = 1;
5128 LRETURN;
5129 }
5130 }
5131 }
5132 for (;;)
5133 {
5134 query_sleep(p_ctx);
5135
5136 query_retry++;
5137
5139 "65") >= 0)
5140 {
5142 p_ctx, NI_DEVICE_TYPE_ENCODER, &sessionStatistic);
5143 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
5145 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
5146 CHECK_VPU_RECOVERY(retval);
5147
5148 buf_info.buf_avail_size = sessionStatistic.ui32RdBufAvailSize;
5149
5150 if (((ni_xcoder_params_t *)p_ctx->p_session_config)->cfg_enc_params.lookAheadDepth)
5151 {
5153 "6rX") >= 0)
5154 {
5155 if (p_ctx->current_frame_delay < (int)sessionStatistic.ui8AdditionalFramesDelay + p_ctx->initial_frame_delay)
5156 {
5157 p_ctx->current_frame_delay = (int)sessionStatistic.ui8AdditionalFramesDelay + p_ctx->initial_frame_delay; // extend frames delay by FW estimated additional number of frames
5158 }
5159 if(query_retry == 0)
5160 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: initial_frame_delay %d max_frame_delay %d ui8AdditionalFramesDelay %u current_frame_delay %d\n",
5161 __FUNCTION__, p_ctx->initial_frame_delay, p_ctx->max_frame_delay, sessionStatistic.ui8AdditionalFramesDelay, p_ctx->current_frame_delay);
5162 }
5163 }
5164 } else
5165 {
5167 p_ctx, query_type, NI_DEVICE_TYPE_ENCODER, &buf_info);
5168 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
5169 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5170 CHECK_VPU_RECOVERY(retval);
5171 }
5172
5173 ni_log2(p_ctx, NI_LOG_TRACE,
5174 "Info enc read query rc %d, available buf size %u, "
5175 "frame_num=%" PRIu64 ", pkt_num=%" PRIu64 "\n",
5176 retval, buf_info.buf_avail_size, p_ctx->frame_num, p_ctx->pkt_num);
5177
5178 if (NI_RETCODE_SUCCESS != retval)
5179 {
5180 ni_log2(p_ctx, NI_LOG_ERROR, "Buffer info query failed in encoder read!!!!\n");
5181 LRETURN;
5182 } else if (0 == buf_info.buf_avail_size)
5183 {
5184 // query to see if it is eos now, if we have sent it
5185 if (p_ctx->ready_to_close)
5186 {
5187 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_ENCODER, &data);
5188 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
5189 p_ctx->device_type, p_ctx->hw_id,
5190 &(p_ctx->session_id), OPT_1);
5191 CHECK_VPU_RECOVERY(retval);
5192
5193 if (NI_RETCODE_SUCCESS != retval)
5194 {
5195 ni_log2(p_ctx, NI_LOG_ERROR, "Stream info query failed in encoder read!!!!\n");
5196 LRETURN;
5197 }
5198
5199 if (data.is_flushed)
5200 {
5201 p_packet->end_of_stream = 1;
5202 }
5203 }
5204 ni_log2(p_ctx, NI_LOG_DEBUG, "Info enc read available buf size %u, eos %u !\n",
5205 buf_info.buf_avail_size, p_packet->end_of_stream);
5206
5207 if ((((ni_xcoder_params_t *)p_ctx->p_session_config)->low_delay_mode ||
5209 !p_packet->end_of_stream && p_ctx->frame_num >= p_ctx->pkt_num)
5210 {
5211 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder low latency mode, eos not sent, frame_num "
5212 "%" PRIu64 " >= %" PRIu64 " pkt_num, keep querying p_ctx->status %d\n",
5213 p_ctx->frame_num, p_ctx->pkt_num, p_ctx->status);
5217 if (query_retry >= NI_MAX_ENCODER_QUERY_RETRIES &&
5219 {
5220 low_delay_notify = 1;
5222 LRETURN;
5223 }
5224 else
5225 {
5226 continue;
5227 }
5228 }
5229 else if (((ni_xcoder_params_t *)p_ctx->p_session_config)->minFramesDelay)
5230 {
5231 if (p_ctx->pkt_num) // do not busy read until header is received
5232 {
5233 uint64_t pkt_num = (p_ctx->codec_format == NI_CODEC_FORMAT_AV1) ? p_ctx->av1_pkt_num : p_ctx->pkt_num - 1; // deduct header from pkt_num
5234 if (p_ctx->frame_num - pkt_num >= p_ctx->current_frame_delay &&
5235 !p_packet->end_of_stream)
5236 {
5237 ni_log2(p_ctx, NI_LOG_TRACE, "%s: low delay mode 2, keep reading send frame %d receive pkt %d gop %d current_frame_delay %d\n",
5238 __FUNCTION__, p_ctx->frame_num, pkt_num,
5239 p_ctx->last_gop_size, p_ctx->current_frame_delay);
5240 continue;
5241 }
5242 }
5243 }
5244 retval = NI_RETCODE_SUCCESS;
5245 LRETURN;
5246 } else
5247 {
5248 if (((ni_xcoder_params_t *)p_ctx->p_session_config)->minFramesDelay & 0x2)
5249 {
5250 if (p_ctx->pkt_num) // do not read until header is received
5251 {
5252 uint64_t pkt_num = (p_ctx->codec_format == NI_CODEC_FORMAT_AV1) ? p_ctx->av1_pkt_num : p_ctx->pkt_num - 1; // deduct header from pkt_num
5253 if (p_ctx->frame_num - pkt_num < (p_ctx->current_frame_delay - 1) &&
5254 !p_ctx->ready_to_close)
5255 {
5256 ni_log2(p_ctx, NI_LOG_TRACE, "%s: constant delay mode 3, delay reading send frame %d receive pkt %d gop %d current_frame_delay %d\n",
5257 __FUNCTION__, p_ctx->frame_num, pkt_num,
5258 p_ctx->last_gop_size, p_ctx->current_frame_delay);
5259 retval = NI_RETCODE_SUCCESS;
5260 LRETURN;
5261 }
5262 }
5263 }
5264 break;
5265 }
5266 }
5267 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder read buf_avail_size %u\n", buf_info.buf_avail_size);
5268
5269 to_read_size = buf_info.buf_avail_size;
5270
5271 p_packet->data_len = 0;
5272 p_packet->pts = NI_NOPTS_VALUE;
5273 p_packet->dts = 0;
5274
5275 p_packet->psnr_y = 0;
5276 p_packet->psnr_u = 0;
5277 p_packet->psnr_v = 0;
5278 p_packet->average_psnr = 0;
5279 p_packet->ssim_y = 0;
5280 p_packet->ssim_u = 0;
5281 p_packet->ssim_v = 0;
5282
5284 actual_read_size = to_read_size;
5285 if (actual_read_size % NI_MEM_PAGE_ALIGNMENT)
5286 {
5287 actual_read_size =
5288 ((actual_read_size / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) +
5290 }
5291
5292 if (p_packet->buffer_size < actual_read_size)
5293 {
5294 if (ni_packet_buffer_alloc(p_packet, actual_read_size))
5295 {
5296 ni_log2(p_ctx, NI_LOG_ERROR,
5297 "ERROR %s(): packet buffer size %u allocation "
5298 "failed\n",
5299 __func__, actual_read_size);
5301 LRETURN;
5302 }
5303 }
5304
5305 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5306 p_packet->p_data, actual_read_size, ui32LBA);
5307 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
5308 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5309 CHECK_VPU_RECOVERY(retval);
5310 if (retval < 0)
5311 {
5312 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
5314 LRETURN;
5315 }
5316
5317 // SSIM is supported if fw_rev is >= 6.2
5319 "62") >= 0)
5320 {
5321 p_meta = (ni_metadata_enc_bstream_t *)p_packet->p_data;
5322 p_packet->pts = (int64_t)(p_meta->frame_tstamp);
5323
5324 // Frame types that encoder can return are I=0, P=1, B=2, Not coded=3.
5325 // Since all I-frames encoded by Quadra are IDR frames, interpret an I frame as IDR frame.
5326 p_packet->frame_type = (p_meta->frame_type == 0) ?
5327 PIC_TYPE_IDR : ((p_meta->frame_type == 3) ? PIC_NOT_CODED : p_meta->frame_type);
5328 p_packet->avg_frame_qp = p_meta->avg_frame_qp;
5329 p_packet->recycle_index = p_meta->recycle_index;
5330 p_packet->av1_show_frame = p_meta->av1_show_frame;
5331 ni_log2(p_ctx, NI_LOG_DEBUG, "%s RECYCLE INDEX = %u!!!\n", __FUNCTION__, p_meta->recycle_index);
5332 ni_log2(p_ctx, NI_LOG_DEBUG, "%s MetaDataSize %d FrameType %d AvgFrameQp %d ssim %d %d %d\n",
5333 __FUNCTION__, p_meta->metadata_size, p_packet->frame_type, p_meta->avg_frame_qp, p_meta->ssimY, p_meta->ssimU, p_meta->ssimV);
5334
5336 "6r2") >= 0)
5337 {
5338 if (((ni_xcoder_params_t *)p_ctx->p_session_config)->cfg_enc_params.lookAheadDepth)
5339 {
5341 "6rX") < 0)
5342 {
5343 if (p_meta->gop_size) // ignore frame 0 gop size 0 (other I-frame gop size 1)
5344 {
5345 if ((int)p_meta->gop_size < p_ctx->last_gop_size)
5346 {
5347 p_ctx->current_frame_delay = p_ctx->max_frame_delay; // shortening gop (including I-frame) causes lookahead queue increase, currently assume worst case frame delay
5348 }
5349 }
5350 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: current gop_size %u last_gop_size %d initial_frame_delay %d max_frame_delay %d current_frame_delay %d\n",
5351 __FUNCTION__, p_meta->gop_size, p_ctx->last_gop_size, p_ctx->initial_frame_delay, p_ctx->max_frame_delay, p_ctx->current_frame_delay);
5352 }
5353 p_ctx->last_gop_size = p_meta->gop_size;
5354 }
5355 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: current gop_size %u\n",
5356 __FUNCTION__, p_meta->gop_size);
5357 }
5358
5360 "6p") >= 0)
5361 {
5362 if (ni_cmp_fw_api_ver((char*)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rm") >= 0)
5363 {
5364 p_packet->still_image_detected = p_meta->ui8StillImage;
5365 p_packet->scene_change_detected = p_meta->ui8SceneChange;
5366 }
5367 else
5368 {
5369 p_packet->still_image_detected = 0;
5370 p_packet->scene_change_detected = 0;
5371 }
5372
5373 if(p_meta->frame_size > 0)
5374 ni_log2(p_ctx, NI_LOG_DEBUG, "pkt_num %d max_mv x[0] %d x[1] %d y[0] %d y[1] %d min_mv x[0] %d x[1] %d y[0] %d y[1] %d frame_size %u inter_total_count %u intra_total_count %u stillImage %d scenechange %d\n",
5375 p_ctx->pkt_num,
5376 p_meta->max_mv_x[0], p_meta->max_mv_x[1], p_meta->max_mv_y[0], p_meta->max_mv_y[1],
5377 p_meta->min_mv_x[0], p_meta->min_mv_x[1], p_meta->min_mv_y[0], p_meta->min_mv_y[1],
5378 p_meta->frame_size, p_meta->inter_total_count, p_meta->intra_total_count,
5379 p_meta->ui8StillImage, p_meta->ui8SceneChange);
5380 }
5381
5383 "6sC") >= 0)
5384 {
5385 if (p_meta->pass1Cost)
5386 ni_log2(p_ctx, NI_LOG_DEBUG, "pkt_num %d pass1Cost %f\n", p_ctx->pkt_num, p_meta->pass1Cost);
5387 }
5388
5389 p_ctx->meta_size = p_meta->metadata_size;
5390
5391 if (p_meta->ssimY != 0)
5392 {
5393 p_packet->ssim_y = (float)p_meta->ssimY/10000;
5394 p_packet->ssim_u = (float)p_meta->ssimU/10000;
5395 p_packet->ssim_v = (float)p_meta->ssimV/10000;
5396 // The SSIM Y, U, V values returned by FW are 4 decimal places multiplied by 10000.
5397 //Divide by 10000 to get the original value.
5398 ni_log2(p_ctx,
5399#ifdef NI_LOG_SSIM_AT_INFO
5401#else
5403#endif
5404 "%s: pkt #%" PRId64 " pts %" PRId64 " ssim "
5405 "Y %.4f U %.4f V %.4f\n", __FUNCTION__, p_ctx->pkt_num,
5406 p_packet->pts, (float)p_meta->ssimY/10000,
5407 (float)p_meta->ssimU/10000, (float)p_meta->ssimV/10000);
5408 }
5409 }
5410 else
5411 {
5412 // Up to fw_rev major 6 and minor 1, use the old meta data structure
5413 p_meta_rev61 = (ni_metadata_enc_bstream_rev61_t *)p_packet->p_data;
5414 p_packet->pts = (int64_t)(p_meta_rev61->frame_tstamp);
5415 p_packet->frame_type = p_meta_rev61->frame_type;
5416 p_packet->avg_frame_qp = p_meta_rev61->avg_frame_qp;
5417 p_packet->recycle_index = p_meta_rev61->recycle_index;
5418 p_packet->av1_show_frame = p_meta_rev61->av1_show_frame;
5419 ni_log2(p_ctx, NI_LOG_DEBUG, "%s RECYCLE INDEX = %u!!!\n", __FUNCTION__, p_meta_rev61->recycle_index);
5420
5421 }
5422
5423 p_packet->data_len = to_read_size;
5424
5425 size = p_packet->data_len;
5426
5427 if (size > 0)
5428 {
5429 if (p_ctx->pkt_num >= 1 &&
5431 "6sM") >= 0)
5432 {
5433 p_meta = (ni_metadata_enc_bstream_t *)p_packet->p_data;
5434
5435 // CU info parsing
5436 if (((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.getBitstreamFeatures)
5437 {
5438 memset(&p_packet->bitstream_features, 0, sizeof(p_packet->bitstream_features));
5439 get_bitstream_features_from_cu_info(p_ctx, p_packet);
5440 }
5441
5442 if (p_meta && p_meta->cuInfoSize != 0)
5443 {
5444 p_packet->data_len -= p_meta->cuInfoSize;
5445 // DEBUG
5446 #if 0
5447 ni_write_bitstream_features_internal(p_ctx, p_packet);
5448 #endif
5449 }
5450 }
5451
5452 if (p_ctx->pkt_num >= 1 &&
5454 "6rc") >= 0)
5455 {
5456 calculate_psnr(p_ctx, p_packet);
5457 }
5458
5459 if (p_ctx->pkt_num < 1)
5460 {
5461 p_ctx->headers_length += (p_packet->data_len - p_ctx->meta_size);
5462 }
5463
5464
5465 if (p_ctx->pkt_num >= 1)
5466 {
5467 if (NI_CODEC_FORMAT_AV1 != p_ctx->codec_format
5468 || p_packet->av1_show_frame)
5469 {
5470 if (ni_timestamp_get_with_threshold(p_ctx->dts_queue, 0, (int64_t*)& p_packet->dts, 0, encq_count % 500 == 0, p_ctx->buffer_pool) != NI_RETCODE_SUCCESS)
5471 {
5472 p_packet->dts = NI_NOPTS_VALUE;
5473 }
5474 }
5475
5476 p_ctx->pkt_num++;
5477 if (p_ctx->codec_format == NI_CODEC_FORMAT_AV1 && p_packet->recycle_index != (uint32_t) NI_AV1_INVALID_BUFFER_INDEX) // av1 invalid buffer index indicates show_existing_frame header packet
5478 {
5479 p_ctx->av1_pkt_num++;
5480 }
5481 low_delay_notify = 1;
5482 }
5483
5484 encq_count++;
5485
5486#ifdef MEASURE_LATENCY
5487#ifndef XCODER_311
5488 ni_log2(p_ctx, NI_LOG_INFO, "ENC fme_num %d, pkt_num %d, latency is %d\n",
5489 p_ctx->frame_num, p_ctx->pkt_num, p_ctx->frame_num - p_ctx->pkt_num);
5490#endif
5491#endif
5492
5493#ifdef XCODER_DUMP_DATA
5494 char dump_file[256];
5495 snprintf(dump_file, sizeof(dump_file), "%ld-%u-enc-pkt/pkt-%04ld.bin",
5496 (long)getpid(), p_ctx->session_id, (long)p_ctx->pkt_num);
5497
5498 FILE *f = NULL;
5499 ni_fopen(&f, dump_file, "wb");
5500 fwrite((uint8_t *)p_packet->p_data + sizeof(ni_metadata_enc_bstream_t),
5501 p_packet->data_len - sizeof(ni_metadata_enc_bstream_t), 1, f);
5502 fflush(f);
5503 fclose(f);
5504#endif
5505 }
5506
5507 ni_log2(p_ctx,
5509 "%s(): %d.%u p_packet->start_of_stream=%u, "
5510 "p_packet->end_of_stream=%u, p_packet->video_width=%u, "
5511 "p_packet->video_height=%u, p_packet->dts=0x%08x 0x%08x, "
5512 "p_packet->pts=0x%08x 0x%08x, type=%u, avg_frame_qp=%u, show_frame=%d\n",
5513 __func__, p_ctx->hw_id, p_ctx->session_id, p_packet->start_of_stream,
5514 p_packet->end_of_stream, p_packet->video_width, p_packet->video_height,
5515 (uint32_t)((p_packet->dts >> 32) & 0xFFFFFFFF),
5516 (uint32_t)(p_packet->dts & 0xFFFFFFFF),
5517 (uint32_t)((p_packet->pts >> 32) & 0xFFFFFFFF),
5518 (uint32_t)(p_packet->pts & 0xFFFFFFFF), p_packet->frame_type,
5519 p_packet->avg_frame_qp, p_packet->av1_show_frame);
5520
5521 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): p_packet->data_len=%u, size=%d\n", __func__,
5522 p_packet->data_len, size);
5523
5524 if (encq_count % 500 == 0)
5525 {
5526 ni_log2(p_ctx, NI_LOG_DEBUG,
5527 "Encoder pts queue size = %u dts queue size = %u\n\n",
5528 p_ctx->pts_table->list.count, p_ctx->dts_queue->list.count);
5529 }
5530
5531 retval = size;
5532
5533#ifdef MEASURE_LATENCY
5534 if ((p_packet->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL) && (p_ctx->pkt_num > 0))
5535 {
5536 if (NI_CODEC_FORMAT_AV1 != p_ctx->codec_format
5537 || p_packet->av1_show_frame)
5538 {
5539 uint64_t abs_time_ns = ni_gettime_ns();
5541 ni_log2(p_ctx, NI_LOG_INFO, "DTS:%" PRId64 ",DELTA:%" PRId64 ",eLAT:%" PRIu64 ";\n",
5542 p_packet->dts, abs_time_ns - q->last_benchmark_time,
5543 ni_lat_meas_q_check_latency(q, abs_time_ns, p_packet->dts));
5544 q->last_benchmark_time = abs_time_ns;
5545 }
5546 }
5547#endif
5548
5549END:
5550
5552
5553 if (low_delay_notify)
5554 {
5555 low_delay_signal(p_ctx);
5556 }
5557
5558 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
5559
5560 return retval;
5561}
5562
5563/*!******************************************************************************
5564 * \brief Send sequnce change to a xcoder encoder instance
5565 *
5566 * \param
5567 *
5568 * \return
5569 *******************************************************************************/
5571{
5573
5574 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
5575
5576 // re-init last_gop_size and av1_pkt_num for minFramesDelay frame delay estimiation
5577 int lookAheadEnable = !!(((ni_xcoder_params_t *)p_ctx->p_session_config)->cfg_enc_params.lookAheadDepth);
5578 int gop_preset_index = ((ni_xcoder_params_t *)p_ctx->p_session_config)->cfg_enc_params.gop_preset_index;
5579 p_ctx->last_gop_size = g_map_preset_to_gopsize[lookAheadEnable][gop_preset_index + 1];
5580 p_ctx->av1_pkt_num = 0;
5581
5582 //Configure encoder sequence change
5584 p_resolution);
5586 p_ctx->device_type, p_ctx->hw_id,
5587 &(p_ctx->session_id), OPT_1);
5588 CHECK_VPU_RECOVERY(retval);
5589 if (retval < 0)
5590 {
5591 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): config encoder sequence change command failed\n",
5592 __func__);
5594 }
5595
5596END:
5597
5598 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
5599
5600 return retval;
5601}
5602
5603/*!******************************************************************************
5604 * \brief Open a xcoder scaler instance
5605 *
5606 * \param[in] p_ctx pointer to session context
5607 *
5608 * \return NI_RETCODE_INVALID_PARAM
5609 * NI_RETCODE_ERROR_NVME_CMD_FAILED
5610 * NI_RETCODE_ERROR_INVALID_SESSION
5611 * NI_RETCODE_ERROR_MEM_ALOC
5612 *******************************************************************************/
5614{
5616 void* p_buffer = NULL;
5617 uint32_t ui32LBA = 0;
5618 char fmt_fw_api_ver1[5], fmt_fw_api_ver2[5];
5619
5620 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
5621
5622 if (!p_ctx)
5623 {
5624 retval = NI_RETCODE_INVALID_PARAM;
5625 LRETURN;
5626 }
5627
5629 {
5631 "64") < 0)
5632 {
5633 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot use stack filter on device with FW API version < 6.4\n");
5635 }
5636 }
5637
5639 {
5641 "67") < 0)
5642 {
5643 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot use rotate filter on device with FW API version < 6.7\n");
5645 }
5646 }
5647
5649 {
5651 "6L") < 0)
5652 {
5653 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot use in-place overlay filter on device with FW API version < 6.L\n");
5655 }
5656 }
5657
5659 {
5661 "6sI") < 0)
5662 {
5663 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot use ai align filter on device with FW API version < 6.sI\n");
5665 }
5666 }
5667
5668 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
5669 {
5671 p_ctx->pts_table = NULL;
5672 p_ctx->dts_queue = NULL;
5673 p_ctx->p_leftover = NULL;
5674 p_ctx->buffer_pool = NULL;
5675 p_ctx->dec_fme_buf_pool = NULL;
5676 p_ctx->prev_size = 0;
5677 p_ctx->sent_size = 0;
5678 p_ctx->status = 0;
5679 p_ctx->key_frame_type = 0;
5680 p_ctx->ready_to_close = 0;
5681 p_ctx->rc_error_count = 0;
5682 p_ctx->frame_num = 0;
5683 p_ctx->pkt_num = 0;
5684 p_ctx->pkt_index = 0;
5685
5686 //malloc zero data buffer
5687 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
5689 {
5690 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc all zero buffer failed\n",
5691 NI_ERRNO, __func__);
5693 LRETURN;
5694 }
5695 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
5696
5697 //malloc data buffer
5698 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
5699 {
5700 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
5701 NI_ERRNO, __func__);
5703 LRETURN;
5704 }
5705 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
5706
5707 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
5708 //In case we can open sesison, the session id would become valid.
5709 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
5710 (uint16_t)NI_INVALID_SESSION_ID;
5711
5712 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
5713 ui32LBA = OPEN_SESSION_CODEC(NI_DEVICE_TYPE_SCALER, ni_htonl(p_ctx->scaler_operation), 0);
5714 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5715 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
5716 if (retval != NI_RETCODE_SUCCESS)
5717 {
5718 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR ni_nvme_send_read_cmd\n");
5719 LRETURN;
5720 }
5721 //Open will return a session status structure with a valid session id if it worked.
5722 //Otherwise the invalid session id set before the open command will stay
5723 p_ctx->session_id = ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
5724 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
5725 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
5726 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
5727 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
5728 {
5729 ni_log2(p_ctx, NI_LOG_ERROR,
5730 "ERROR %s(): p_ctx->device_handle=%" PRIx64
5731 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
5732 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
5733 p_ctx->session_id);
5735 LRETURN;
5736 }
5737 ni_log2(p_ctx, NI_LOG_DEBUG, "Scaler open session ID:0x%x\n",p_ctx->session_id);
5738 ni_log2(p_ctx, NI_LOG_DEBUG,
5739 "%s(): p_ctx->device_handle=%" PRIx64
5740 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
5741 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
5742 p_ctx->session_id);
5743
5744 //Send keep alive timeout Info
5745 uint64_t keep_alive_timeout =
5746 p_ctx->keep_alive_timeout * 1000000; //send us to FW
5747 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
5748 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
5749 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
5750 keep_alive_timeout);
5752 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5753 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
5754 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
5755 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5756 CHECK_VPU_RECOVERY(retval);
5757
5758 if (NI_RETCODE_SUCCESS != retval)
5759 {
5760 ni_log2(p_ctx, NI_LOG_ERROR,
5761 "ERROR %s(): nvme write keep_alive_timeout command "
5762 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
5763 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
5765 LRETURN;
5766 }
5767
5768 // Send SW version to FW if FW API version is >= 6.2
5770 "62") >= 0)
5771 {
5772 // Send SW version to session manager
5773 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
5774 memcpy(p_buffer, NI_XCODER_REVISION, sizeof(uint64_t));
5776 ni_fmt_fw_api_ver_str((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], &fmt_fw_api_ver2[0]);
5777 ni_log2(p_ctx, NI_LOG_DEBUG, "%s libxcoder FW API ver %s, FW FW API ver %s\n",
5778 __func__, fmt_fw_api_ver1, fmt_fw_api_ver2);
5779 ui32LBA = CONFIG_SESSION_SWVersion_W(p_ctx->session_id);
5780 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5781 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
5782 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
5783 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5784 CHECK_VPU_RECOVERY(retval);
5785
5786 if (NI_RETCODE_SUCCESS != retval)
5787 {
5788 ni_log2(p_ctx, NI_LOG_ERROR,
5789 "ERROR %s(): nvme write sw_version command "
5790 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
5791 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
5793 LRETURN;
5794 }
5795 }
5796 }
5797
5798 // init for frame pts calculation
5799 p_ctx->is_first_frame = 1;
5800 p_ctx->last_pts = 0;
5801 p_ctx->last_dts = 0;
5802 p_ctx->active_video_width = 0;
5803 p_ctx->active_video_height = 0;
5804 p_ctx->actual_video_width = 0;
5805
5806#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OPEN_HARMONY__) && !defined(_ANDROID)
5807 if (p_ctx->isP2P)
5808 {
5809 retval = p2p_fill_pcie_address(p_ctx);
5810 if(retval != NI_RETCODE_SUCCESS)
5811 {
5812 LRETURN;
5813 }
5814 }
5815#endif
5816
5817END:
5818
5819 ni_aligned_free(p_buffer);
5820 return retval;
5821}
5822
5823/*!******************************************************************************
5824 * \brief close a scaler session
5825 *
5826 * \param[in] p_ctx pointer to session context
5827 * \param[in] eos_received (not used)
5828 *
5829 * \return NI_RETCODE_INVALID_PARAM
5830 * NI_RETCODE_ERROR_INVALID_SESSION
5831 * NI_RETCODE_ERROR_NVME_CMD_FAILED
5832 *******************************************************************************/
5834{
5836 void * p_buffer = NULL;
5837 uint32_t ui32LBA = 0;
5838
5839 if (!p_ctx)
5840 {
5841 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
5842 __func__);
5844 }
5845
5847
5848 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
5849 {
5850 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): Invalid session ID, return.\n", __func__);
5851 retval = NI_RETCODE_SUCCESS;
5852 LRETURN;
5853 }
5854
5855 //malloc data buffer
5856 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
5857 {
5858 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc data buffer failed\n",
5859 NI_ERRNO, __func__);
5861 LRETURN;
5862 }
5863 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
5864
5866
5867 int retry = 0;
5868 while (retry < NI_SESSION_CLOSE_RETRY_MAX)
5869 {
5870 ni_log2(p_ctx, NI_LOG_DEBUG,
5871 "%s(): p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
5872 "p_ctx->session_id=%d, close_mode=1\n",
5873 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
5874 p_ctx->session_id);
5875
5877 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
5878 {
5879 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): command failed!\n", __func__);
5882 break;
5883 } else
5884 {
5885 //Close should always succeed
5886 retval = NI_RETCODE_SUCCESS;
5888 break;
5889 }
5890 retry++;
5891 }
5892
5893#ifndef _WIN32
5894 if (p_ctx->isP2P)
5895 {
5896 if (p_ctx->netint_fd)
5897 {
5898 close(p_ctx->netint_fd);
5899 }
5900 }
5901#endif
5902
5903END:
5904
5905 ni_aligned_free(p_buffer);
5907
5909
5910 return retval;
5911}
5912
5913/*!******************************************************************************
5914 * \brief Send a p_config command to configure scaling parameters.
5915 *
5916 * \param ni_session_context_t p_ctx - xcoder Context
5917 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_params_t struct
5918 *
5919 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
5920 *******************************************************************************/
5922 ni_scaler_params_t *p_params)
5923{
5924 void *p_scaler_config = NULL;
5925 ni_scaler_config_t *p_cfg = NULL;
5926 uint32_t buffer_size = sizeof(ni_scaler_params_t);
5928 uint32_t ui32LBA = 0;
5929
5930 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
5931
5932 if (!p_ctx || !p_params)
5933 {
5934 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
5935 __func__);
5936 retval = NI_RETCODE_INVALID_PARAM;
5937 LRETURN;
5938 }
5939
5940 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
5941 {
5942 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
5943 __func__);
5945 LRETURN;
5946 }
5947
5948 buffer_size =
5949 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
5951 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
5952 {
5953 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
5954 NI_ERRNO, __func__);
5956 LRETURN;
5957 }
5958 memset(p_scaler_config, 0, buffer_size);
5959
5960 //configure the session here
5963
5964 //Flip the bytes!!
5965 p_cfg = (ni_scaler_config_t *)p_scaler_config;
5966 p_cfg->filterblit = p_params->filterblit;
5967 p_cfg->numInputs = p_params->nb_inputs;
5968 if (p_cfg->filterblit == 5)
5969 {
5970 // check fw revision
5973 "6sL") < 0)
5974 {
5975 ni_log2(p_ctx, NI_LOG_ERROR, "%s: not supported config filterblit 5 "
5976 "on device with FW API version < 6rL\n", __func__);
5977 // Close the session since we can't configure it as per fw
5978 retval = ni_scaler_session_close(p_ctx, 0);
5979 if (NI_RETCODE_SUCCESS != retval)
5980 {
5981 ni_log2(p_ctx, NI_LOG_ERROR,
5982 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
5983 "hw_id, %d, xcoder_inst_id: %d\n",
5984 __func__,
5985 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
5986 p_ctx->session_id);
5987 }
5989 LRETURN;
5990 }
5991
5992 // set filterblit 5 default parameter
5993 p_cfg->scaler_param_b = (uint16_t)(3.5 * 10000);
5994 p_cfg->scaler_param_c = (uint16_t)(1.25 * 10000);
5995 }
5996 else
5997 {
5998 p_cfg->scaler_param_b = (uint16_t)(0);
5999 p_cfg->scaler_param_c = (uint16_t)(0.75 * 10000);
6000 }
6001
6002 if (p_params->enable_scaler_params)
6003 {
6004 // check fw revision
6007 "6s2") < 0)
6008 {
6009 ni_log2(p_ctx, NI_LOG_ERROR, "%s: not supported config scaler params B and C "
6010 "on device with FW API version < 6s1\n", __func__);
6011 // Close the session since we can't configure it as per fw
6012 retval = ni_scaler_session_close(p_ctx, 0);
6013 if (NI_RETCODE_SUCCESS != retval)
6014 {
6015 ni_log2(p_ctx, NI_LOG_ERROR,
6016 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
6017 "hw_id, %d, xcoder_inst_id: %d\n",
6018 __func__,
6019 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
6020 p_ctx->session_id);
6021 }
6022
6024 LRETURN;
6025 }
6026 if (p_params->scaler_param_b < 0 || p_params->scaler_param_c < 0 ||
6027 p_params->scaler_param_b > 5 || p_params->scaler_param_c > 5)
6028 {
6029 ni_log2(p_ctx, NI_LOG_ERROR, "%s: scaler_params_b and scaler_params_c must "
6030 "be in [0 , 5]. scaler_params_b is %lf, scaler_params_c is %lf\n",
6031 __func__, p_params->scaler_param_b, p_params->scaler_param_c);
6032 // Close the session since we can't configure it as per fw
6033 retval = ni_scaler_session_close(p_ctx, 0);
6034 if (NI_RETCODE_SUCCESS != retval)
6035 {
6036 ni_log2(p_ctx, NI_LOG_ERROR,
6037 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
6038 "hw_id, %d, xcoder_inst_id: %d\n",
6039 __func__,
6040 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
6041 p_ctx->session_id);
6042 }
6043
6045 LRETURN;
6046 }
6047 p_cfg->scaler_param_b = (uint16_t)(p_params->scaler_param_b * 10000);
6048 p_cfg->scaler_param_c = (uint16_t)(p_params->scaler_param_c * 10000);
6049 }
6050
6051 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
6052 p_scaler_config, buffer_size, ui32LBA);
6053 if ((int32_t)retval < 0)
6054 {
6055 ni_log2(p_ctx, NI_LOG_ERROR,
6056 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
6057 ", hw_id, %d, xcoder_inst_id: %d\n",
6058 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
6059 // Close the session since we can't configure it as per fw
6060 retval = ni_scaler_session_close(p_ctx, 0);
6061 if (NI_RETCODE_SUCCESS != retval)
6062 {
6063 ni_log2(p_ctx, NI_LOG_ERROR,
6064 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
6065 "hw_id, %d, xcoder_inst_id: %d\n",
6066 __func__,
6067 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
6068 p_ctx->session_id);
6069 }
6070
6072 LRETURN;
6073 }
6075 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
6076
6077END:
6078
6079 ni_aligned_free(p_scaler_config);
6080 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
6081
6082 return retval;
6083}
6084
6085/*!******************************************************************************
6086 * \brief allocate a frame in the scaler
6087 *
6088 * \param[in] p_ctx pointer to session context
6089 * \param[in] width width in pixels
6090 * \param[in] height height in pixels
6091 * \param[in] format pixel format
6092 * \param[in] options option flags
6093 * \param[in] rectangle_width clipping rectangle width in pixels
6094 * \param[in] rectangle_height clipping rectangle height in pixels
6095 * \param[in] rectangle_x clipping rectangle x position
6096 * \param[in] rectangle_y clipping rectangle y position
6097 * \param[in] rgba_color background colour (only used by pad filter)
6098 * \param[in] frame_index frame index (only for hardware frames)
6099 *
6100 * \return NI_RETCODE_INVALID_PARAM
6101 * NI_RETCODE_ERROR_INVALID_SESSION
6102 * NI_RETCODE_ERROR_NVME_CMD_FAILED
6103 * NI_RETCODE_ERROR_MEM_ALOC
6104 *******************************************************************************/
6106 int width,
6107 int height,
6108 int format,
6109 int options,
6110 int rectangle_width,
6111 int rectangle_height,
6112 int rectangle_x,
6113 int rectangle_y,
6114 int rgba_color,
6115 int frame_index)
6116{
6119 uint32_t dataLen;
6120 uint32_t ui32LBA = 0;
6121 uint32_t query_retry = 0;
6122
6123 /* Round up to nearest 4096 bytes */
6124 dataLen =
6126 dataLen = dataLen & 0xFFFFF000;
6127
6128 if (!p_ctx)
6129 {
6131 }
6132
6133 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
6134 {
6135 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
6136 __func__);
6138 }
6139
6140 if (((options & NI_SCALER_FLAG_IO) && (options & NI_SCALER_FLAG_PC)))
6141 {
6142 // this operation is to free/allocate scaler frame pool
6143 if (rgba_color == 0)
6144 {
6147 "6r3") < 0)
6148 {
6149 ni_log2(p_ctx, NI_LOG_INFO,
6150 "WARNING: Allocate framepool size 0 for session 0x%x\n", p_ctx->session_id);
6151 return NI_RETCODE_SUCCESS;
6152 }
6153 else if (p_ctx->pool_type == NI_POOL_TYPE_NONE)
6154 {
6155 ni_log2(p_ctx, NI_LOG_ERROR,
6156 "ERROR: %s() try to free session 0x%x framepool while it's not allocated\n",
6157 __func__, p_ctx->session_id);
6159 }
6160 else if ((options & NI_SCALER_FLAG_P2) == p_ctx->pool_type)
6161 {
6162 ni_log2(p_ctx, NI_LOG_INFO, "Free framepool of scaler 0x%x\n", p_ctx->session_id);
6163 }
6164 else
6165 {
6166 ni_log2(p_ctx, NI_LOG_ERROR,
6167 "ERROR: %s() try to free session 0x%x framepool of type %u while "
6168 "passing type %u\n",
6169 __func__, p_ctx->session_id, p_ctx->pool_type,
6170 (options & NI_SCALER_FLAG_P2));
6171 }
6172 }
6173 else
6174 {
6175 if (p_ctx->pool_type != NI_POOL_TYPE_NONE)
6176 {
6177 // try to expand the framepool
6180 "6r3") < 0)
6181 {
6182 ni_log2(p_ctx, NI_LOG_ERROR,
6183 "ERROR: allocate framepool multiple times for session 0x%x "
6184 "not supported in FW API version < 6r3\n",
6185 p_ctx->session_id);
6187 }
6188 if ((options & NI_SCALER_FLAG_P2) == p_ctx->pool_type)
6189 {
6190 ni_log2(p_ctx, NI_LOG_INFO,
6191 "Expand frame pool of scaler 0x%x with %u more frames\n",
6192 p_ctx->session_id, rgba_color);
6193 }
6194 else
6195 {
6196 ni_log2(p_ctx, NI_LOG_ERROR,
6197 "ERROR: try to expand session 0x%x framepool with type %u "
6198 "while pool type is %u\n",
6199 p_ctx->session_id, options & NI_SCALER_FLAG_P2, p_ctx->pool_type);
6201 }
6202 }
6203 }
6204 }
6205
6206 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
6207 {
6208 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6209 NI_ERRNO, __func__);
6211 }
6212
6213 memset(p_data, 0x00, dataLen);
6214
6215 p_data->picture_width = width;
6216 p_data->picture_height = height;
6217 p_data->picture_format = format;
6218 p_data->options = options;
6219 p_data->rectangle_width = rectangle_width;
6220 p_data->rectangle_height = rectangle_height;
6221 p_data->rectangle_x = rectangle_x;
6222 p_data->rectangle_y = rectangle_y;
6223 p_data->rgba_color = rgba_color;
6224 p_data->frame_index = frame_index;
6225
6226 ni_log2(p_ctx, NI_LOG_DEBUG, "%s() options %d frame_index %u buffered_frame_index %d\n",
6227 __func__, options, p_data->frame_index, p_ctx->buffered_frame_index);
6228
6229 switch (p_ctx->scaler_operation)
6230 {
6233 if ((options & NI_SCALER_FLAG_IO) && !(options & NI_SCALER_FLAG_PC))
6234 {
6235 p_data->frame_index = frame_index; // background
6236 if (p_ctx->buffered_frame_index)
6237 {
6238 p_data->rgba_color = p_ctx->buffered_frame_index; // output frame
6239 }
6240 else
6241 {
6242 p_data->rgba_color = 0; // no output frame, fw must acquire
6243 }
6244 }
6245 break;
6246
6247 default:
6248 // Send acquired buffer index in AdminWr SET_ALLOC_FRAME command to prevent FP
6249 // ConfigOutput from acquire buffer again
6250 if ((options & NI_SCALER_FLAG_IO) && p_ctx->buffered_frame_index)
6251 {
6252 p_data->frame_index = p_ctx->buffered_frame_index;
6253 }
6254 break;
6255 }
6256
6257 bool isrgb = ((GC620_RGBA8888 == format) || (GC620_BGRX8888 == format) ||
6258 (GC620_ARGB8888 == format) || (GC620_ABGR8888 == format));
6259 if(width > NI_MAX_RESOLUTION_WIDTH || height > NI_MAX_RESOLUTION_HEIGHT ||
6261 ((width > NI_MAX_RESOLUTION_RGBA_WIDTH || height > NI_MAX_RESOLUTION_RGBA_HEIGHT) && isrgb))
6262 {
6264 ni_log2(p_ctx, NI_LOG_ERROR, "Invalid Picture Width: too small for scaler\n");
6266 ni_log2(p_ctx, NI_LOG_ERROR, "Invalid Picture Height: too small for scaler\n");
6267 if(width > NI_MAX_RESOLUTION_WIDTH || ((width > NI_MAX_RESOLUTION_RGBA_WIDTH) && isrgb))
6268 ni_log2(p_ctx, NI_LOG_ERROR, "Invalid Picture Width: too big for scaler\n");
6269 if(height > NI_MAX_RESOLUTION_HEIGHT || ((height > NI_MAX_RESOLUTION_RGBA_HEIGHT) && isrgb))
6270 ni_log2(p_ctx, NI_LOG_ERROR, "Invalid Picture Height: too big for scaler\n");
6271
6272 ni_log2(p_ctx, NI_LOG_ERROR, "Resolution %d x %d not supported for %d format!\n", width, height, format);
6273 ni_aligned_free(p_data);
6275 }
6276 ni_log2(p_ctx, NI_LOG_DEBUG,
6277 "Session=0x%x: Dev alloc frame: FrameIndex=%d; W=%d; H=%d; C=%d; RW=%d; RH=%d; RX=%d; RY=%d\n",
6278 p_ctx->session_id, p_data->frame_index,
6279 p_data->picture_width, p_data->picture_height,
6280 p_data->picture_format, p_data->rectangle_width,
6281 p_data->rectangle_height, p_data->rectangle_x, p_data->rectangle_y);
6282
6285
6286 for (;;)
6287 {
6288 query_retry++;
6289
6290 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
6291 p_data, dataLen, ui32LBA);
6292
6294 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_3);
6295
6297 {
6298 if (query_retry >= 1000 || (options & NI_SCALER_FLAG_PC))
6299 {
6300 ni_log2(p_ctx, NI_LOG_ERROR, "Error: 2D could not acquire frame\n");
6301 retval = NI_RETCODE_FAILURE;
6302 LRETURN;
6303 }
6305 continue;
6306 }
6307 else
6308 {
6309 p_ctx->pool_type = ((options & NI_SCALER_FLAG_IO) && (options & NI_SCALER_FLAG_PC)) ?
6310 (options & NI_SCALER_FLAG_P2) : (p_ctx->pool_type);
6311 break;
6312 }
6313 }
6314
6315 if (NI_RETCODE_SUCCESS != retval)
6316 {
6317 ni_log2(p_ctx, NI_LOG_ERROR,
6318 "ERROR: ni_nvme_send_admin_cmd failed: "
6319 "blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n",
6320 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
6321 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n", __func__);
6323 }
6324
6325END:
6326
6327 ni_aligned_free(p_data);
6328 return retval;
6329}
6330
6331/*!******************************************************************************
6332 * \brief config a frame in the scaler
6333 *
6334 * \param[in] p_ctx pointer to session context
6335 * \param[in] p_cfg pointer to frame config
6336 *
6337 * \return NI_RETCODE_INVALID_PARAM
6338 * NI_RETCODE_ERROR_INVALID_SESSION
6339 * NI_RETCODE_ERROR_NVME_CMD_FAILED
6340 * NI_RETCODE_ERROR_MEM_ALOC
6341 *******************************************************************************/
6343 ni_frame_config_t *p_cfg)
6344{
6347 uint32_t dataLen;
6348 uint32_t ui32LBA = 0;
6349
6350 /* Round up to nearest 4096 bytes */
6351 dataLen =
6353 dataLen = dataLen & 0xFFFFF000;
6354
6355 if (!p_ctx || !p_cfg)
6356 {
6358 }
6359
6360 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
6361 {
6362 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
6363 __func__);
6365 }
6366
6367 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
6368 {
6369 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6370 NI_ERRNO, __func__);
6372 }
6373
6374 memset(p_data, 0x00, dataLen);
6375
6376 p_data->picture_width = p_cfg->picture_width;
6377 p_data->picture_height = p_cfg->picture_height;
6378 p_data->picture_format = p_cfg->picture_format;
6379 p_data->options = p_cfg->options;
6380
6381 p_data->rectangle_width = p_cfg->rectangle_width;
6382 p_data->rectangle_height = p_cfg->rectangle_height;
6383 p_data->rectangle_x = p_cfg->rectangle_x;
6384 p_data->rectangle_y = p_cfg->rectangle_y;
6385 p_data->rgba_color = p_cfg->rgba_color;
6386 p_data->frame_index = p_cfg->frame_index;
6387 p_data->session_id = p_cfg->session_id;
6388 p_data->output_index = p_cfg->output_index;
6389 switch (p_cfg->orientation)
6390 {
6391 case 0:
6392 case 2:
6393 case 4:
6394 case 5:
6395 p_data->orientation = p_cfg->orientation;
6396 break;
6397 case 1:
6398 p_data->orientation = 3;
6399 break;
6400 case 3:
6401 p_data->orientation = 1;
6402 break;
6403 default:
6404 ni_log2(p_ctx, NI_LOG_ERROR, "Bad orientation: %u\n", p_cfg->orientation);
6406 }
6407 bool isrgb = ((GC620_RGBA8888 == p_data->picture_format) || (GC620_BGRX8888 == p_data->picture_format) ||
6408 (GC620_ARGB8888 == p_data->picture_format) || (GC620_ABGR8888 == p_data->picture_format));
6412 {
6413 ni_log2(p_ctx, NI_LOG_ERROR, "Resolution %d x %d not supported for %d format!\n", p_data->picture_width, p_data->picture_height, p_data->picture_format);
6414 ni_aligned_free(p_data);
6416 }
6417
6418 ni_log2(p_ctx, NI_LOG_DEBUG,
6419 "Session=0x%x: Dev config frame: FrameIndex=%u; W=%d; H=%d; C=%d; RW=%d; RH=%d; RX=%d; RY=%d; O=%d\n",
6420 p_ctx->session_id, p_cfg->frame_index,
6421 p_data->picture_width, p_data->picture_height,
6422 p_data->picture_format, p_data->rectangle_width,
6423 p_data->rectangle_height, p_data->rectangle_x,
6424 p_data->rectangle_y, p_data->orientation);
6425
6428
6429 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
6430 p_data, dataLen, ui32LBA);
6432 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
6433 if (NI_RETCODE_SUCCESS != retval)
6434 {
6435 ni_log2(p_ctx, NI_LOG_ERROR,
6436 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
6437 ", hw_id, %u, xcoder_inst_id: %d\n",
6438 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
6439
6440 ni_log2(p_ctx, NI_LOG_ERROR,
6441 "ERROR ni_scaler_config(): nvme command failed!\n");
6443 }
6444
6445END:
6446
6447 ni_aligned_free(p_data);
6448 return retval;
6449}
6450
6451/*!******************************************************************************
6452 * \brief config multiple frames in the scaler
6453 *
6454 * \param[in] p_ctx pointer to session context
6455 * \param[in] p_cfg_in pointer to input frame config array
6456 * \param[in] numInCfgs number of input frame configs in the p_cfg array
6457 * \param[in] p_cfg_out pointer to output frame config
6458 *
6459 * \return NI_RETCODE_INVALID_PARAM
6460 * NI_RETCODE_ERROR_INVALID_SESSION
6461 * NI_RETCODE_ERROR_NVME_CMD_FAILED
6462 * NI_RETCODE_ERROR_MEM_ALOC
6463 *******************************************************************************/
6465 ni_frame_config_t p_cfg_in[],
6466 int numInCfgs,
6467 ni_frame_config_t *p_cfg_out)
6468{
6470 ni_instance_mgr_allocation_info_t *p_data, *p_data_orig;
6471 uint32_t dataLen;
6472 uint32_t ui32LBA = 0;
6473 int i;
6474
6475 /* Round up to nearest 4096 bytes */
6476 dataLen =
6477 sizeof(ni_instance_mgr_allocation_info_t) * (numInCfgs + 1) + NI_MEM_PAGE_ALIGNMENT - 1;
6478 dataLen = dataLen & 0xFFFFF000;
6479
6480 if (!p_ctx || (!p_cfg_in && numInCfgs))
6481 {
6483 }
6484
6485 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
6486 {
6487 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
6488 __func__);
6490 }
6491
6492 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
6493 {
6494 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6495 NI_ERRNO, __func__);
6497 }
6498
6499 memset(p_data, 0x00, dataLen);
6500
6501 p_data_orig = p_data;
6502
6503 for (i = 0; i < numInCfgs; i++)
6504 {
6505 p_data->picture_width = p_cfg_in[i].picture_width;
6506 p_data->picture_height = p_cfg_in[i].picture_height;
6507 p_data->picture_format = p_cfg_in[i].picture_format;
6508 p_data->options = p_cfg_in[i].options & ~NI_SCALER_FLAG_IO;
6509
6510 p_data->rectangle_width = p_cfg_in[i].rectangle_width;
6511 p_data->rectangle_height = p_cfg_in[i].rectangle_height;
6512 p_data->rectangle_x = p_cfg_in[i].rectangle_x;
6513 p_data->rectangle_y = p_cfg_in[i].rectangle_y;
6514 p_data->rgba_color = p_cfg_in[i].rgba_color;
6515 p_data->frame_index = p_cfg_in[i].frame_index;
6516 p_data->session_id = p_cfg_in[i].session_id;
6517 p_data->output_index = p_cfg_in[i].output_index;
6518
6519 ni_log2(p_ctx, NI_LOG_DEBUG,
6520 "Session=0x%x: Dev in config frame %d: FrameIndex=%u; Session=0x%x; W=%d; H=%d; C=%d; RW=%d; RH=%d; RX=%d; RY=%d\n",
6521 p_ctx->session_id, i,
6522 p_data->frame_index, p_data->session_id,
6523 p_data->picture_width, p_data->picture_height,
6524 p_data->picture_format, p_data->rectangle_width,
6525 p_data->rectangle_height, p_data->rectangle_x, p_data->rectangle_y);
6526
6527 p_data++;
6528 }
6529
6530 if (p_cfg_out)
6531 {
6532 p_data->picture_width = p_cfg_out->picture_width;
6533 p_data->picture_height = p_cfg_out->picture_height;
6534 p_data->picture_format = p_cfg_out->picture_format;
6535 p_data->options = p_cfg_out->options | NI_SCALER_FLAG_IO;
6536
6537 p_data->rectangle_width = p_cfg_out->rectangle_width;
6538 p_data->rectangle_height = p_cfg_out->rectangle_height;
6539 p_data->rectangle_x = p_cfg_out->rectangle_x;
6540 p_data->rectangle_y = p_cfg_out->rectangle_y;
6541 p_data->rgba_color = p_cfg_out->rgba_color;
6542 p_data->frame_index = p_cfg_out->frame_index;
6543
6544 ni_log2(p_ctx, NI_LOG_DEBUG,
6545 "Session=0x%x: Dev out config frame: FrameIndex=%u; W=%d; H=%d; C=%d; RW=%d; RH=%d; RX=%d; RY=%d\n",
6546 p_ctx->session_id, p_data->frame_index,
6547 p_data->picture_width, p_data->picture_height,
6548 p_data->picture_format, p_data->rectangle_width,
6549 p_data->rectangle_height, p_data->rectangle_x,
6550 p_data->rectangle_y);
6551 }
6553 {
6554 ni_log2(p_ctx, NI_LOG_ERROR, "Resolution %d x %d not supported for %d format!\n", p_data->picture_width, p_data->picture_height, p_data->picture_format);
6555 ni_aligned_free(p_data);
6557 }
6558
6561
6562 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
6563 p_data_orig, dataLen, ui32LBA);
6565 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
6566 if (NI_RETCODE_SUCCESS != retval)
6567 {
6568 ni_log2(p_ctx, NI_LOG_ERROR,
6569 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
6570 ", hw_id, %u, xcoder_inst_id: %d\n",
6571 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
6572
6573 ni_log2(p_ctx, NI_LOG_ERROR,
6574 "ERROR ni_scaler_config(): nvme command failed!\n");
6576 }
6577
6578END:
6579
6580 ni_aligned_free(p_data_orig);
6581 return retval;
6582}
6583
6584/*!******************************************************************************
6585 * \brief Query a particular xcoder instance to get GeneralStatus data
6586 *
6587 * \param ni_session_context_t p_ctx - xcoder Context
6588 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
6589 * \param ni_instance_mgr_general_status_t *out - Struct preallocated from the caller where the
6590 * resulting data will be placed
6591 *
6592 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
6593 *******************************************************************************/
6595{
6596 void* p_buffer = NULL;
6597 int retval = NI_RETCODE_SUCCESS;
6598 uint32_t ui32LBA = 0;
6600
6601 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
6602
6603 if ((!p_ctx) || (!p_gen_status))
6604 {
6605 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
6606 __func__);
6607 retval = NI_RETCODE_INVALID_PARAM;
6608 LRETURN;
6609 }
6610
6611 if (!IS_XCODER_DEVICE_TYPE(device_type))
6612 {
6613 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
6614 __func__, device_type);
6615 retval = NI_RETCODE_INVALID_PARAM;
6616 LRETURN;
6617 }
6618
6619 ui32LBA = QUERY_GENERAL_GET_STATUS_R(device_type);
6620
6621 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
6622 {
6623 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6624 NI_ERRNO, __func__);
6626 LRETURN;
6627 }
6628
6629 memset(p_buffer, 0, dataLen);
6630
6631 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
6632 {
6633 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
6635 LRETURN;
6636 }
6637
6638 //No need to flip the bytes since the datastruct has only uint8_t datatypes
6639 memcpy((void*)p_gen_status, p_buffer, sizeof(ni_instance_mgr_general_status_t));
6640
6641 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): model_load:%u qc:%d percent:%d\n", __func__,
6642 p_gen_status->fw_model_load, p_gen_status->cmd_queue_count,
6643 p_gen_status->process_load_percent);
6644END:
6645
6646 ni_aligned_free(p_buffer);
6647 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
6648
6649 return retval;
6650}
6651
6652/*!******************************************************************************
6653 * \brief Query a particular xcoder instance to get DetailStatus data
6654 *
6655 * \param ni_session_context_t p_ctx - xcoder Context
6656 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
6657 * \param ni_instance_mgr_detail_status_t *out - Struct preallocated from the caller where the
6658 * resulting data will be placed
6659 *
6660 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
6661 *******************************************************************************/
6662int ni_query_detail_status(ni_session_context_t* p_ctx, ni_device_type_t device_type, void* p_detail_status, int ver)
6663{
6664 void* p_buffer = NULL;
6665 int retval = NI_RETCODE_SUCCESS;
6666 uint32_t ui32LBA = 0;
6667 uint32_t dataLen = 0;
6668 uint32_t copyLen = 0;
6669 if(ver == 0)
6670 {
6671 ui32LBA = QUERY_DETAIL_GET_STATUS_R(device_type);
6673 dataLen = ((copyLen + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
6674 }
6675 else if(ver == 1)
6676 {
6677 ui32LBA = QUERY_DETAIL_GET_STATUS_V1_R(device_type);
6678 copyLen = sizeof(ni_instance_mgr_detail_status_v1_t);
6680 }
6681 else
6682 {
6683 retval = NI_RETCODE_INVALID_PARAM;
6684 LRETURN;
6685 }
6686
6687 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
6688
6689 if ((!p_ctx) || (!p_detail_status))
6690 {
6691 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
6692 __func__);
6693 retval = NI_RETCODE_INVALID_PARAM;
6694 LRETURN;
6695 }
6696
6697 if (!IS_XCODER_DEVICE_TYPE(device_type))
6698 {
6699 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
6700 __func__, device_type);
6701 retval = NI_RETCODE_INVALID_PARAM;
6702 LRETURN;
6703 }
6704
6705 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
6706 {
6707 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6708 NI_ERRNO, __func__);
6710 LRETURN;
6711 }
6712
6713 memset(p_buffer, 0, dataLen);
6714
6715 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
6716 {
6717 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
6719 LRETURN;
6720 }
6721
6722 //No need to flip the bytes since the datastruct has only uint8_t datatypes
6723 memcpy(p_detail_status, p_buffer, copyLen);
6724
6725END:
6726
6727 ni_aligned_free(p_buffer);
6728 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
6729
6730 return retval;
6731}
6732
6733/*!******************************************************************************
6734 * \brief Query a particular xcoder instance to get Stream Info data
6735 *
6736 * \param ni_session_context_t p_ctx - xcoder Context
6737 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
6738 * \param ni_instance_mgr_stream_info_t *out - Struct preallocated from the caller where the
6739 * resulting data will be placed
6740 *
6741 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_MEM_ALOC
6742 * or NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
6743 *******************************************************************************/
6745{
6746 void* p_buffer = NULL;
6748 uint32_t ui32LBA = 0;
6750
6751 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
6752
6753 if ((!p_ctx) || (!p_stream_info))
6754 {
6755 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
6756 __func__);
6757 retval = NI_RETCODE_INVALID_PARAM;
6758 LRETURN;
6759 }
6760
6761 if (! (NI_DEVICE_TYPE_DECODER == device_type ||
6762 NI_DEVICE_TYPE_ENCODER == device_type))
6763 {
6764 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
6765 __func__, device_type);
6766 retval = NI_RETCODE_INVALID_PARAM;
6767 LRETURN;
6768 }
6769
6770 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
6771 {
6772 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
6773 __func__);
6775 LRETURN;
6776 }
6777
6778 ui32LBA = QUERY_INSTANCE_STREAM_INFO_R(p_ctx->session_id, device_type);
6779
6780 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
6781 {
6782 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6783 NI_ERRNO, __func__);
6785 LRETURN;
6786 }
6787 memset(p_buffer, 0, dataLen);
6788
6789 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
6790 {
6791 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
6793 LRETURN;
6794 }
6795
6796 memcpy((void*)p_stream_info, p_buffer, sizeof(ni_instance_mgr_stream_info_t));
6797
6798 //flip the bytes to host order
6799 p_stream_info->picture_width = ni_htons(p_stream_info->picture_width);
6800 p_stream_info->picture_height = ni_htons(p_stream_info->picture_height);
6801 p_stream_info->frame_rate = ni_htons(p_stream_info->frame_rate);
6802 p_stream_info->is_flushed = ni_htons(p_stream_info->is_flushed);
6803 p_stream_info->transfer_frame_stride = ni_htons(p_stream_info->transfer_frame_stride);
6804 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): pix_format = %d\n", __func__,
6805 p_stream_info->pix_format); //temp
6806
6807END:
6808
6809 ni_aligned_free(p_buffer);
6810 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
6811
6812 return retval;
6813}
6814
6815/*!*****************************************************************************
6816 * \brief Query a particular session to get the stats info
6817 *
6818 * \param ni_session_context_t p_ctx - xcoder Context
6819 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
6820 * \param ni_session_stats_t *out - Struct preallocated from the
6821 * caller where the resulting data will be placed
6822 *
6823 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
6824 * NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED
6825 * on failure
6826 ******************************************************************************/
6828 ni_device_type_t device_type,
6829 ni_session_stats_t *p_session_stats, int rc,
6830 int opcode)
6831{
6833 void* p_buffer = NULL;
6834 uint64_t session_timestamp;
6835 uint32_t ui32LBA = 0;
6837
6838 ni_device_type_t xc_device_type =
6839 (device_type != NI_DEVICE_TYPE_UPLOAD ? device_type :
6841
6842 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
6843
6844 if ((!p_ctx) || (!p_session_stats))
6845 {
6846 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
6847 __func__);
6848 retval = NI_RETCODE_INVALID_PARAM;
6849 LRETURN;
6850 }
6851
6852 if (!IS_XCODER_DEVICE_TYPE(xc_device_type))
6853 {
6854 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
6855 __func__, device_type);
6856 retval = NI_RETCODE_INVALID_PARAM;
6857 LRETURN;
6858 }
6859
6860 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
6861 {
6862 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
6863 __func__);
6865 LRETURN;
6866 }
6867
6868 ui32LBA = QUERY_SESSION_STATS_R(p_ctx->session_id, xc_device_type);
6869
6870 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
6871 {
6872 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6873 NI_ERRNO, __func__);
6875 LRETURN;
6876 }
6877 memset(p_buffer, 0, dataLen);
6878
6879 // Set session ID to be invalid. In case, the last command fails because the invalid session ID was submitted
6880 // with the command, the session id would remain invalid.
6881 // If the last command is processed successfully in session manager, the session id would become valid.
6882 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
6883 (uint16_t)NI_INVALID_SESSION_ID;
6884
6885 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA)
6886 < 0)
6887 {
6888 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): read command Failed\n", __func__);
6890 LRETURN;
6891 }
6892
6893 memcpy((void*)p_session_stats, p_buffer, sizeof(ni_session_stats_t));
6894
6895 // flip the bytes to host order
6896 // all query commands are guaranteed success once a session is opened
6897 p_session_stats->ui16SessionId = ni_htons(p_session_stats->ui16SessionId);
6898 p_session_stats->ui16ErrorCount = ni_htons(p_session_stats->ui16ErrorCount);
6899 p_session_stats->ui32LastTransactionId =
6900 ni_htonl(p_session_stats->ui32LastTransactionId);
6901 p_session_stats->ui32LastTransactionCompletionStatus =
6902 ni_htonl(p_session_stats->ui32LastTransactionCompletionStatus);
6903 p_session_stats->ui32LastErrorTransactionId = ni_htonl(p_session_stats->ui32LastErrorTransactionId);
6904 p_session_stats->ui32LastErrorStatus = ni_htonl(p_session_stats->ui32LastErrorStatus);
6905 p_session_stats->ui32Session_timestamp_high = ni_htonl(p_session_stats->ui32Session_timestamp_high);
6906 p_session_stats->ui32Session_timestamp_low = ni_htonl(p_session_stats->ui32Session_timestamp_low);
6907
6908 session_timestamp = p_session_stats->ui32Session_timestamp_high;
6909 session_timestamp <<= 32;
6910 session_timestamp |= p_session_stats->ui32Session_timestamp_low;
6911
6912 // get the session timestamp when open session
6913 // check the timestamp during transcoding
6914 if ((p_ctx->session_timestamp != session_timestamp) &&
6916 // if VPU recovery, the session timestamp will be reset.
6917 {
6918 p_session_stats->ui32LastErrorStatus =
6920 ni_log2(p_ctx, NI_LOG_DEBUG, "instance id invalid:%u, timestamp:%" PRIu64 ", "
6921 "query timestamp:%" PRIu64 "\n", p_ctx->session_id,
6922 p_ctx->session_timestamp, session_timestamp);
6923 }
6924
6925 // check rc here, if rc != NI_RETCODE_SUCCESS, it means that last read/write command failed
6926 // failures may be link layer errors, such as physical link errors or ERROR_WRITE_PROTECT in windows.
6927 if (NI_RETCODE_SUCCESS != rc)
6928 {
6929 ni_log2(p_ctx, NI_LOG_ERROR, "%s():last command Failed: rc %d\n", __func__, rc);
6930 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): session id %u ts %lu hw_id %d device_type %u codec_format %u frame_num %lu pkt_num %lu "
6931 "ready_to_close %u session_run_state %d active_video_width %u active_video_height %u\n",
6932 __func__,
6933 p_ctx->session_id,
6934 p_ctx->session_timestamp,
6935 p_ctx->hw_id,
6936 p_ctx->device_type,
6937 p_ctx->codec_format,
6938 p_ctx->frame_num,
6939 p_ctx->pkt_num,
6940 p_ctx->ready_to_close,
6941 p_ctx->session_run_state,
6942 p_ctx->active_video_width,
6943 p_ctx->active_video_height);
6944
6945#if __linux__ || __APPLE__
6946#if !defined(_ANDROID) && !defined(__OPENHARMONY__)
6947#ifndef DISABLE_BACKTRACE_PRINT
6948 ni_print_backtrace(); // log backtrace
6949#endif
6950#endif
6951#endif
6952
6953 p_session_stats->ui32LastTransactionCompletionStatus =
6957 } else if (p_ctx->session_id != p_session_stats->ui16SessionId)
6958 {
6959 uint64_t ct = ni_gettime_ns();
6960 uint64_t dt = ct - p_ctx->last_access_time;
6961 ni_log2(p_ctx, NI_LOG_ERROR,
6962 "%s(): device 0x%" PRIx64 " last command Failed due to wrong "
6963 "session ID. Expected 0x%x, got 0x%x keep alive last access "
6964 "time %" PRIu64 ", current %" PRIu64 "\n", __func__,
6965 (int64_t)p_ctx->blk_io_handle, p_ctx->session_id,
6966 p_session_stats->ui16SessionId, p_ctx->last_access_time, ct);
6967 if (dt > 1000000000)
6968 {
6969 ni_log2(p_ctx, NI_LOG_ERROR,
6970 "%s():long delay between last command dt = %" PRId64 " ns, "
6971 "process was possibly blocked.\n", __func__, dt);
6972 }
6974
6975 // Mark session id to INVALID so that all commands afterward are blocked
6977 }
6978
6979 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): error count %u last rc 0x%x inst_err_no 0x%x\n",
6980 __func__, p_session_stats->ui16ErrorCount,
6981 p_session_stats->ui32LastTransactionCompletionStatus,
6982 p_session_stats->ui32LastErrorStatus);
6983
6984END:
6985
6986 ni_aligned_free(p_buffer);
6987 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
6988
6989 return retval;
6990}
6991
6992/*!******************************************************************************
6993 * \brief Query a particular xcoder instance to get End of Output data
6994 *
6995 * \param ni_session_context_t p_ctx - xcoder Context
6996 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
6997 * \param InstMgrStreamComp *out - Struct preallocated from the caller where the
6998 * resulting data will be placed
6999 *
7000 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_MEM_ALOC
7001 * or NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7002 *******************************************************************************/
7004{
7005 void* p_buffer = NULL;
7007 uint32_t ui32LBA = 0;
7009
7010 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7011
7012 if (!p_ctx || !p_stream_complete)
7013 {
7014 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7015 __func__);
7016 retval = NI_RETCODE_INVALID_PARAM;
7017 LRETURN;
7018 }
7019
7020 if (! (NI_DEVICE_TYPE_DECODER == device_type ||
7021 NI_DEVICE_TYPE_ENCODER == device_type))
7022 {
7023 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7024 __func__, device_type);
7025 retval = NI_RETCODE_INVALID_PARAM;
7026 LRETURN;
7027 }
7028
7029 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7030 {
7031 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7032 __func__);
7034 LRETURN;
7035 }
7036
7037 ui32LBA = QUERY_INSTANCE_EOS_R(p_ctx->session_id, device_type);
7038
7039 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
7040 {
7041 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate buffer.\n");
7043 LRETURN;
7044 }
7045
7046 memset(p_buffer, 0, dataLen);
7047
7048 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
7049 {
7050 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7052 LRETURN;
7053 }
7054
7055 memcpy((void*)p_stream_complete, p_buffer, sizeof(ni_instance_mgr_stream_complete_t));
7056
7057 //flip the bytes to host order
7058 p_stream_complete->is_flushed = ni_htons(p_stream_complete->is_flushed);
7059
7060END:
7061
7062 ni_aligned_free(p_buffer);
7063 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7064
7065 return retval;
7066}
7067
7068static const char* ni_get_device_type_str(int type)
7069{
7070 if (type < NI_DEVICE_TYPE_DECODER || type > NI_DEVICE_TYPE_AI)
7071 {
7072 return "Invalid device type";
7073 }
7074 return g_device_type_str[type];
7075}
7076
7077static void
7078ni_parse_session_statistic_info(ni_session_context_t *p_ctx,
7079 ni_session_statistic_t *p_session_statistic,
7080 void *p_buffer)
7081{
7082 memcpy((void *)p_session_statistic, p_buffer,
7083 sizeof(ni_session_statistic_t));
7084
7085 //flip the bytes to host order
7086 p_session_statistic->ui32RdBufAvailSize =
7087 ni_htonl(p_session_statistic->ui32RdBufAvailSize);
7088 p_session_statistic->ui32WrBufAvailSize =
7089 ni_htonl(p_session_statistic->ui32WrBufAvailSize);
7090
7091 p_session_statistic->ui32FramesInput =
7092 ni_htonl(p_session_statistic->ui32FramesInput);
7093 p_session_statistic->ui32FramesBuffered =
7094 ni_htonl(p_session_statistic->ui32FramesBuffered);
7095 p_session_statistic->ui32FramesCompleted =
7096 ni_htonl(p_session_statistic->ui32FramesCompleted);
7097 p_session_statistic->ui32FramesOutput =
7098 ni_htonl(p_session_statistic->ui32FramesOutput);
7099 p_session_statistic->ui32FramesDropped =
7100 ni_htonl(p_session_statistic->ui32FramesDropped);
7101 p_session_statistic->ui32InstErrors =
7102 ni_htonl(p_session_statistic->ui32InstErrors);
7103
7104 p_session_statistic->ui16SessionId =
7105 ni_htons(p_session_statistic->ui16SessionId);
7106 p_session_statistic->ui16ErrorCount =
7107 ni_htons(p_session_statistic->ui16ErrorCount);
7108 p_session_statistic->ui32LastTransactionId =
7109 ni_htonl(p_session_statistic->ui32LastTransactionId);
7110 p_session_statistic->ui32LastTransactionCompletionStatus =
7111 ni_htonl(p_session_statistic->ui32LastTransactionCompletionStatus);
7112 p_session_statistic->ui32LastErrorTransactionId =
7113 ni_htonl(p_session_statistic->ui32LastErrorTransactionId);
7114 p_session_statistic->ui32LastErrorStatus =
7115 ni_htonl(p_session_statistic->ui32LastErrorStatus);
7116 p_session_statistic->ui32Session_timestamp_high =
7117 ni_htonl(p_session_statistic->ui32Session_timestamp_high);
7118 p_session_statistic->ui32Session_timestamp_low =
7119 ni_htonl(p_session_statistic->ui32Session_timestamp_low);
7120
7121 // p_session_statistic->ui8AdditionalFramesDelay does not require endian conversion
7122
7123 if (p_ctx->session_id != p_session_statistic->ui16SessionId)
7124 {
7125 uint64_t ct = ni_gettime_ns();
7126 uint64_t dt = ct - p_ctx->last_access_time;
7127 ni_log2(p_ctx, NI_LOG_ERROR,
7128 "%s(): %s device 0x%" PRIx64 " last command Failed due to wrong "
7129 "session ID. Expected 0x%x, got 0x%x w_r <%u %u> keep alive "
7130 "last access time %" PRIu64 ", current %" PRIu64 "\n", __func__,
7131 ni_get_device_type_str(p_ctx->device_type),
7132 (int64_t)p_ctx->device_handle, p_ctx->session_id,
7133 p_session_statistic->ui16SessionId,
7134 p_session_statistic->ui32WrBufAvailSize,
7135 p_session_statistic->ui32RdBufAvailSize, p_ctx->last_access_time,
7136 ct);
7137 if (dt > 1000000000)
7138 {
7139 ni_log2(p_ctx, NI_LOG_ERROR,
7140 "%s():long delay between last command dt = %" PRId64 " ns, "
7141 "process was possibly blocked.\n", __func__, dt);
7142 }
7143 p_session_statistic->ui32LastErrorStatus =
7145 //Mark session id to INVALID so that all commands afterward are blocked
7147 } else
7148 {
7149 //Acknowledge that total error count here
7150 }
7151
7152 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): error count %u last rc 0x%x inst_err_no 0x%x\n",
7153 __func__, p_session_statistic->ui16ErrorCount,
7154 p_session_statistic->ui32LastTransactionCompletionStatus,
7155 p_session_statistic->ui32LastErrorStatus);
7156}
7157
7158/*!*****************************************************************************
7159 * \brief Query a particular xcoder session to get session statistics
7160 *
7161 * \param ni_session_context_t p_ctx - xcoder Context
7162 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7163 * \param ni_session_statistic_t*out - Struct preallocated from the caller
7164 * where the resulting data will be placed
7165 *
7166 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
7167 * NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on
7168 * failure
7169 ******************************************************************************/
7172 ni_device_type_t device_type,
7173 ni_session_statistic_t *p_session_statistic)
7174{
7175 void *p_buffer = NULL;
7177 uint32_t ui32LBA = 0;
7178 uint32_t dataLen =
7182
7183 if (!p_ctx || !p_session_statistic)
7184 {
7185 ni_log2(p_ctx, NI_LOG_ERROR,
7186 "ERROR: %s() passed parameters are null!, return\n", __func__);
7187 retval = NI_RETCODE_INVALID_PARAM;
7188 LRETURN;
7189 }
7190
7192 "65") < 0)
7193 {
7194 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() not supported on device with FW api version < 6.5\n", __func__);
7196 }
7197
7198 if (!(NI_DEVICE_TYPE_DECODER == device_type ||
7199 NI_DEVICE_TYPE_ENCODER == device_type ||
7200 NI_DEVICE_TYPE_AI == device_type))
7201 {
7202 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7203 __func__, device_type);
7204 retval = NI_RETCODE_INVALID_PARAM;
7205 LRETURN;
7206 }
7207
7208 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7209 {
7210 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7211 __func__);
7213 LRETURN;
7214 }
7215
7216 ui32LBA = QUERY_INSTANCE_CUR_STATUS_INFO_R(p_ctx->session_id, device_type);
7217
7218 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
7219 {
7220 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7221 NI_ERRNO, __func__);
7223 LRETURN;
7224 }
7225 memset(p_buffer, 0, dataLen);
7226
7227 // Set session ID to be invalid. In case, the last command fails because the invalid session ID was submitted
7228 // with the command, the session id would remain invalid.
7229 // If the Last command is processed successfully in session manager, the session id would become valid.
7230 ((ni_session_statistic_t *)p_buffer)->ui16SessionId =
7231 (uint16_t)NI_INVALID_SESSION_ID;
7232
7234 p_buffer, dataLen, ui32LBA) < 0)
7235 {
7236 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): NVME command Failed\n", __func__);
7237 p_session_statistic->ui32LastTransactionCompletionStatus =
7239 p_session_statistic->ui32LastErrorStatus =
7242 LRETURN;
7243 }
7244
7245 ni_parse_session_statistic_info(p_ctx, p_session_statistic, p_buffer);
7246 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
7247 {
7249 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, %s return.\n",
7250 __func__, ni_get_device_type_str(p_ctx->device_type));
7251 LRETURN;
7252 }
7253 p_ctx->session_statistic = *p_session_statistic;
7254
7255END:
7256 ni_aligned_free(p_buffer);
7257 ni_log2(p_ctx, NI_LOG_TRACE, "%s():exit\n", __func__);
7258
7259 return retval;
7260}
7261/*!*****************************************************************************
7262 * \brief Query a particular xcoder instance to get buffer/data Info data
7263 *
7264 * \param ni_session_context_t p_ctx - xcoder Context
7265 * \param ni_instance_buf_info_rw_type_t rw_type
7266 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7267 * \param ni_instance_buf_info_t *out - Struct preallocated from the caller
7268 * where the resulting data will be placed
7269 *
7270 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
7271 * NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on
7272 * failure
7273 ******************************************************************************/
7276 ni_device_type_t device_type,
7277 ni_instance_buf_info_t *p_inst_buf_info)
7278{
7279 void* p_buffer = NULL;
7281 uint32_t ui32LBA = 0;
7282 uint32_t dataLen =
7286
7287 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7288
7289 if (!p_ctx || !p_inst_buf_info)
7290 {
7291 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7292 __func__);
7293 retval = NI_RETCODE_INVALID_PARAM;
7294 LRETURN;
7295 }
7296
7297 if (!(NI_DEVICE_TYPE_DECODER == device_type ||
7298 NI_DEVICE_TYPE_ENCODER == device_type ||
7299 NI_DEVICE_TYPE_SCALER == device_type ||
7300 NI_DEVICE_TYPE_AI == device_type))
7301 {
7302 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7303 __func__, device_type);
7304 retval = NI_RETCODE_INVALID_PARAM;
7305 LRETURN;
7306 }
7307
7308 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7309 {
7310 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7311 __func__);
7313 LRETURN;
7314 }
7315
7316 if (INST_BUF_INFO_RW_READ == rw_type)
7317 {
7318 ui32LBA = QUERY_INSTANCE_RBUFF_SIZE_R(p_ctx->session_id, device_type);
7319 }
7320 else if (INST_BUF_INFO_RW_WRITE == rw_type)
7321 {
7322 ui32LBA = QUERY_INSTANCE_WBUFF_SIZE_R(p_ctx->session_id, device_type);
7323 }
7324 else if(INST_BUF_INFO_RW_WRITE_BY_EP == rw_type)
7325 {
7327 "65") >= 0)
7328 {
7329 ui32LBA = QUERY_INSTANCE_WBUFF_SIZE_R_BY_EP(p_ctx->session_id, device_type);
7330 }
7331 else
7332 {
7334 LRETURN;
7335 }
7336 }
7337 else if (INST_BUF_INFO_RW_UPLOAD == rw_type)
7338 {
7339 ui32LBA = QUERY_INSTANCE_UPLOAD_ID_R(p_ctx->session_id, device_type);
7340 } else if (INST_BUF_INFO_R_ACQUIRE == rw_type)
7341 {
7342 ui32LBA = QUERY_INSTANCE_ACQUIRE_BUF(p_ctx->session_id, device_type);
7343 } else if (INST_BUF_INFO_RW_READ_BUSY == rw_type)
7344 {
7345 ui32LBA =
7346 QUERY_INSTANCE_RBUFF_SIZE_BUSY_R(p_ctx->session_id, device_type);
7347 } else if (INST_BUF_INFO_RW_WRITE_BUSY == rw_type)
7348 {
7349 ui32LBA =
7350 QUERY_INSTANCE_WBUFF_SIZE_BUSY_R(p_ctx->session_id, device_type);
7351 } else if (INST_BUF_INFO_RW_READ_BY_AI == rw_type)
7352 {
7353 ui32LBA = QUERY_INSTANCE_AI_INFO_R(p_ctx->session_id, device_type);
7354 } else
7355 {
7356 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown query type %d, return\n",
7357 __func__, rw_type);
7358 retval = NI_RETCODE_INVALID_PARAM;
7359 LRETURN;
7360 }
7361
7362 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
7363 {
7364 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7365 NI_ERRNO, __func__);
7367 LRETURN;
7368 }
7369
7370 memset(p_buffer, 0, dataLen);
7371
7372 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
7373 {
7374 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7376 LRETURN;
7377 }
7378
7379 memcpy((void*)p_inst_buf_info, p_buffer, sizeof(ni_instance_buf_info_t));
7380
7381 p_inst_buf_info->buf_avail_size = ni_htonl(p_inst_buf_info->buf_avail_size);
7382
7383END:
7384
7385 ni_aligned_free(p_buffer);
7386 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7387
7388 return retval;
7389}
7390
7391/*!*****************************************************************************
7392 * \brief Configure the read/write pipe for a session to control its behavior
7393 *
7394 * \param ni_session_context_t p_ctx - xcoder Context
7395 * \param ni_session_config_rw_t rw_type
7396 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7397 * \param uint8_t enable
7398 * \param uint8_t hw_action
7399 * \param uint16_t frame_id
7400 *
7401 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
7402 * NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on
7403 * failure
7404 ******************************************************************************/
7407 uint8_t enable, uint8_t hw_action,
7408 uint16_t frame_id)
7409{
7411 uint32_t ui32LBA = 0;
7412 void * p_buffer = NULL;
7413 uint32_t buffer_size = 0;
7414 ni_session_config_rw_t * rw_config = NULL;
7415
7416 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7417
7418 if (!p_ctx)
7419 {
7420 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7421 __func__);
7422 retval = NI_RETCODE_INVALID_PARAM;
7423 LRETURN;
7424 }
7425
7426 if (!((SESSION_READ_CONFIG == rw_type) || (SESSION_WRITE_CONFIG == rw_type)))
7427 {
7428 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown config type %d, return\n",
7429 __func__, rw_type);
7430 retval = NI_RETCODE_INVALID_PARAM;
7431 LRETURN;
7432 }
7433
7435 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
7436 {
7437 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7438 NI_ERRNO, __func__);
7440 LRETURN;
7441 }
7442 memset(p_buffer, 0, buffer_size);
7443 rw_config = (ni_session_config_rw_t *)p_buffer;
7444 rw_config->ui8Enable = enable;
7445 rw_config->ui8HWAccess = hw_action;
7446 switch(rw_type)
7447 {
7449 rw_config->uHWAccessField.ui16ReadFrameId = frame_id;
7450 break;
7452 rw_config->uHWAccessField.ui16WriteFrameId = frame_id;
7453 break;
7454 default:
7455 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown config type %d, return\n",
7456 __func__, rw_type);
7457 retval = NI_RETCODE_INVALID_PARAM;
7458 LRETURN;
7459 }
7460
7461 switch(rw_type)
7462 {
7464 ui32LBA = CONFIG_SESSION_Read_W(p_ctx->session_id);
7465 break;
7467 ui32LBA = CONFIG_SESSION_Write_W(p_ctx->session_id);
7468 break;
7469 default:
7470 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown config type %d, return\n",
7471 __func__, rw_type);
7472 retval = NI_RETCODE_INVALID_PARAM;
7473 LRETURN;
7474 }
7475 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, buffer_size, ui32LBA) < 0)
7476 {
7477 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7479 LRETURN;
7480 }
7481
7482END:
7483
7484 ni_aligned_free(p_buffer);
7485 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7486
7487 return retval;
7488}
7489
7490/*!******************************************************************************
7491 * \brief Send a p_config command for Start Of Stream
7492 *
7493 * \param ni_session_context_t p_ctx - xcoder Context
7494 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7495 *
7496 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION. NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7497 *******************************************************************************/
7499{
7501 uint32_t ui32LBA = 0;
7502
7503 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7504
7505 if (!p_ctx)
7506 {
7507 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7508 __func__);
7509 retval = NI_RETCODE_INVALID_PARAM;
7510 LRETURN;
7511 }
7512
7513 if (! (NI_DEVICE_TYPE_DECODER == device_type ||
7514 NI_DEVICE_TYPE_ENCODER == device_type))
7515 {
7516 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7517 __func__, device_type);
7518 retval = NI_RETCODE_INVALID_PARAM;
7519 LRETURN;
7520 }
7521
7522 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7523 {
7524 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7525 __func__);
7527 LRETURN;
7528 }
7529
7530 ui32LBA = CONFIG_INSTANCE_SetSOS_W(p_ctx->session_id, device_type);
7531
7532 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_ctx->p_all_zero_buf, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
7533 {
7534 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7536 }
7537
7538END:
7539
7540 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7541 return retval;
7542}
7543
7544/*!******************************************************************************
7545 * \brief Send a p_config command for End Of Stream
7546 *
7547 * \param ni_session_context_t p_ctx - xcoder Context
7548 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7549 *
7550 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7551 *******************************************************************************/
7553{
7555 uint32_t ui32LBA = 0;
7556
7557 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7558
7559 if (!p_ctx)
7560 {
7561 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7562 __func__);
7563 retval = NI_RETCODE_INVALID_PARAM;
7564 LRETURN;
7565 }
7566
7567 if (! (NI_DEVICE_TYPE_DECODER == device_type ||
7568 NI_DEVICE_TYPE_ENCODER == device_type))
7569 {
7570 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7571 __func__, device_type);
7572 retval = NI_RETCODE_INVALID_PARAM;
7573 LRETURN;
7574 }
7575
7576 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7577 {
7578 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7579 __func__);
7581 LRETURN;
7582 }
7583
7584 ui32LBA = CONFIG_INSTANCE_SetEOS_W(p_ctx->session_id, device_type);
7585
7586 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_ctx->p_all_zero_buf, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
7587 {
7588 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7590 }
7591
7592END:
7593
7594 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7595
7596 return retval;
7597}
7598
7599/*!******************************************************************************
7600 * \brief Send a p_config command to flush the stream
7601 *
7602 * \param ni_session_context_t p_ctx - xcoder Context
7603 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7604 *
7605 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7606 *******************************************************************************/
7608{
7610 uint32_t ui32LBA = 0;
7611
7612 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7613
7614 if (!p_ctx)
7615 {
7616 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7617 __func__);
7618 retval = NI_RETCODE_INVALID_PARAM;
7619 LRETURN;
7620 }
7621
7622 if (NI_DEVICE_TYPE_DECODER != device_type)
7623 {
7624 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7625 __func__, device_type);
7626 retval = NI_RETCODE_INVALID_PARAM;
7627 LRETURN;
7628 }
7629
7630 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7631 {
7632 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7633 __func__);
7635 LRETURN;
7636 }
7637
7638 ui32LBA = CONFIG_INSTANCE_Flush_W(p_ctx->session_id, device_type);
7639 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
7641 ui32LBA);
7643 p_ctx->device_type, p_ctx->hw_id,
7644 &(p_ctx->session_id), OPT_1);
7645 CHECK_VPU_RECOVERY(retval);
7646
7647END:
7648
7649 if (NI_RETCODE_SUCCESS != retval)
7650 {
7652 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed with %d\n", __func__, retval);
7653 }
7654
7655 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7656
7657 return retval;
7658}
7659
7660/*!******************************************************************************
7661 * \brief Send a p_config command to set the length for the incoming write packet
7662 *
7663 * \param ni_session_context_t p_ctx - xcoder Context
7664 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7665 * \param
7666 *
7667 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7668 *******************************************************************************/
7670{
7672 uint32_t ui32LBA = 0;
7673 void * p_buffer = NULL;
7674 uint32_t buffer_size = 0;
7675
7676 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7677
7678 if (!p_ctx)
7679 {
7680 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7681 __func__);
7682 retval = NI_RETCODE_INVALID_PARAM;
7683 LRETURN;
7684 }
7685
7686 if (!(NI_DEVICE_TYPE_DECODER == device_type ||
7687 NI_DEVICE_TYPE_ENCODER == device_type))
7688 {
7689 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7690 __func__, device_type);
7691 retval = NI_RETCODE_INVALID_PARAM;
7692 LRETURN;
7693 }
7694
7695 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7696 {
7697 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7698 __func__);
7700 LRETURN;
7701 }
7702
7703 buffer_size = ((sizeof(len) + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
7704 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
7705 {
7706 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7707 NI_ERRNO, __func__);
7709 LRETURN;
7710 }
7711 memset(p_buffer, 0, buffer_size);
7712 memcpy(p_buffer, &len, sizeof(len));
7713
7714 ui32LBA = CONFIG_INSTANCE_SetPktSize_W(p_ctx->session_id, device_type);
7715
7716 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, buffer_size, ui32LBA) < 0)
7717 {
7718 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7720 }
7721
7722END:
7723
7724 ni_aligned_free(p_buffer);
7725 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7726
7727 return retval;
7728}
7729
7730/*!******************************************************************************
7731 * \brief Send a p_config command to inform encoder sequence change
7732 *
7733 * \param ni_session_context_t p_ctx - xcoder Context
7734 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7735 * \param ni_resolution_t p_resolution - sequence change resolution
7736 *
7737 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7738 *******************************************************************************/
7740{
7742 uint32_t ui32LBA = 0;
7743 void * p_buffer = NULL;
7744 uint32_t buffer_size = 0;
7745
7746 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7747
7748 if (!p_ctx)
7749 {
7750 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7751 __func__);
7752 retval = NI_RETCODE_INVALID_PARAM;
7753 LRETURN;
7754 }
7755
7756 if (!(NI_DEVICE_TYPE_ENCODER == device_type))
7757 {
7758 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Seq Change not supported for device type %d, return\n", device_type);
7759 retval = NI_RETCODE_INVALID_PARAM;
7760 LRETURN;
7761 }
7762
7763 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7764 {
7765 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7766 __func__);
7768 LRETURN;
7769 }
7770
7772 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
7773 {
7774 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7775 NI_ERRNO, __func__);
7777 LRETURN;
7778 }
7779 memset(p_buffer, 0, buffer_size);
7780 memcpy(p_buffer, p_resolution, sizeof(ni_resolution_t));
7781
7782 ui32LBA = CONFIG_INSTANCE_SetSeqChange_W(p_ctx->session_id, device_type);
7783
7784 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, buffer_size, ui32LBA) < 0)
7785 {
7786 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7788 }
7789
7790END:
7791
7792 ni_aligned_free(p_buffer);
7793 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7794
7795 return retval;
7796}
7797
7798/*!******************************************************************************
7799 * \brief Send a p_config command to configure encoding parameters.
7800 *
7801 * \param ni_session_context_t p_ctx - xcoder Context
7802 *
7803 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7804 *******************************************************************************/
7806{
7807 void* p_encoder_config = NULL;
7808 void* p_encoder_roi_qp_map = NULL;
7809 ni_encoder_config_t* p_cfg = NULL;
7810 uint32_t buffer_size = 0;
7812 uint32_t ui32LBA = 0;
7813 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7814
7815 if (!p_ctx)
7816 {
7817 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7818 __func__);
7819 retval = NI_RETCODE_INVALID_PARAM;
7820 LRETURN;
7821 }
7822
7823 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7824 {
7825 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7826 __func__);
7828 LRETURN;
7829 }
7830
7831 if (ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rh") >= 0)
7832 {
7834 ni_xcoder_params_t *session_config = (ni_xcoder_params_t *)p_ctx->p_session_config;
7835 if (session_config->cfg_enc_params.customize_roi_qp_level > 64) {
7837 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
7838 if (ni_posix_memalign(&p_encoder_roi_qp_map, sysconf(_SC_PAGESIZE), buffer_size))
7839 {
7840 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7841 NI_ERRNO, __func__);
7843 LRETURN;
7844 }
7845 memset(p_encoder_roi_qp_map, 0, buffer_size);
7846 memcpy(p_encoder_roi_qp_map, session_config->customize_roi_qp_map,
7848 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
7849 p_encoder_roi_qp_map, buffer_size, ui32LBA);
7851 p_ctx->device_type, p_ctx->hw_id,
7852 &(p_ctx->session_id), OPT_1);
7853 if (NI_RETCODE_SUCCESS != retval)
7854 {
7855 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
7856 //Close the session since we can't configure it
7857 retval = ni_encoder_session_close(p_ctx, 0);
7858 if (NI_RETCODE_SUCCESS != retval)
7859 {
7860 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_encoder_session_close failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
7861 }
7863 LRETURN;
7864 }
7865 session_config->cfg_enc_params.customize_roi_qp_level -= 64;
7866 } else if (session_config->cfg_enc_params.customize_roi_qp_level == 64) {
7867 ni_log2(p_ctx, NI_LOG_INFO, "customizeQpMapFile is ignored since customizeQpLevel=0");
7868 session_config->cfg_enc_params.customize_roi_qp_level = 0;
7869 }
7870 }
7871
7872 buffer_size = sizeof(ni_encoder_config_t);
7873 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
7874 if (ni_posix_memalign(&p_encoder_config, sysconf(_SC_PAGESIZE), buffer_size))
7875 {
7876 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7877 NI_ERRNO, __func__);
7879 LRETURN;
7880 }
7881 memset(p_encoder_config, 0, buffer_size);
7882
7883 ni_set_custom_template(p_ctx, p_encoder_config, p_ctx->p_session_config);
7884 retval = ni_validate_custom_template(p_ctx, p_encoder_config, p_ctx->p_session_config, p_ctx->param_err_msg, sizeof(p_ctx->param_err_msg));
7885 if (NI_RETCODE_PARAM_WARN == retval)
7886 {
7887 ni_log2(p_ctx, NI_LOG_INFO, "WARNING: ni_validate_custom_template() . %s\n", p_ctx->param_err_msg);
7888 fflush(stdout);
7889 }
7890 else if (NI_RETCODE_SUCCESS != retval)
7891 {
7892 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_validate_custom_template() failed. %s\n", p_ctx->param_err_msg);
7893 fflush(stdout);
7894 retval = NI_RETCODE_INVALID_PARAM;
7895 LRETURN;
7896 }
7897 //configure the session here
7899
7900 //Flip the bytes!! any param 16bits in size need ni_htons, 32bit need ni_htonl
7901 p_cfg = (ni_encoder_config_t*)p_encoder_config;
7902 p_cfg->i32picWidth = ni_htonl(p_cfg->i32picWidth);
7903 p_cfg->i32picHeight = ni_htonl(p_cfg->i32picHeight);
7904 p_cfg->i32meBlkMode = ni_htonl(p_cfg->i32meBlkMode);
7905 p_cfg->i32frameRateInfo = ni_htonl(p_cfg->i32frameRateInfo);
7906 p_cfg->i32vbvBufferSize = ni_htonl(p_cfg->i32vbvBufferSize);
7907 p_cfg->i32userQpMax = ni_htonl(p_cfg->i32userQpMax);
7908 p_cfg->i32maxIntraSize = ni_htonl(p_cfg->i32maxIntraSize);
7909 p_cfg->i32userMaxDeltaQp = ni_htonl(p_cfg->i32userMaxDeltaQp);
7910 p_cfg->i32userMinDeltaQp = ni_htonl(p_cfg->i32userMinDeltaQp);
7911 p_cfg->i32userQpMin = ni_htonl(p_cfg->i32userQpMin);
7912 p_cfg->i32bitRate = ni_htonl(p_cfg->i32bitRate);
7913 p_cfg->i32bitRateBL = ni_htonl(p_cfg->i32bitRateBL);
7914 p_cfg->i32srcBitDepth = ni_htonl(p_cfg->i32srcBitDepth);
7915 p_cfg->hdrEnableVUI = ni_htonl(p_cfg->hdrEnableVUI);
7916 p_cfg->ui32VuiDataSizeBits = ni_htonl(p_cfg->ui32VuiDataSizeBits);
7917 p_cfg->ui32VuiDataSizeBytes = ni_htonl(p_cfg->ui32VuiDataSizeBytes);
7918 p_cfg->i32hwframes = ni_htonl(p_cfg->i32hwframes);
7919 p_cfg->ui16HDR10MaxLight = ni_htons(p_cfg->ui16HDR10MaxLight);
7920 p_cfg->ui16HDR10AveLight = ni_htons(p_cfg->ui16HDR10AveLight);
7921 p_cfg->ui16gdrDuration = ni_htons(p_cfg->ui16gdrDuration);
7922 p_cfg->ui32ltrRefInterval = ni_htonl(p_cfg->ui32ltrRefInterval);
7923 p_cfg->i32ltrRefQpOffset = ni_htonl(p_cfg->i32ltrRefQpOffset);
7924 p_cfg->ui32ltrFirstGap = ni_htonl(p_cfg->ui32ltrFirstGap);
7925 p_cfg->i32tolCtbRcInter = ni_htonl(p_cfg->i32tolCtbRcInter);
7926 p_cfg->i32tolCtbRcIntra = ni_htonl(p_cfg->i32tolCtbRcIntra);
7927 p_cfg->i16bitrateWindow = ni_htons(p_cfg->i16bitrateWindow);
7928 p_cfg->ui16hdr10_dx0 = ni_htons(p_cfg->ui16hdr10_dx0);
7929 p_cfg->ui16hdr10_dy0 = ni_htons(p_cfg->ui16hdr10_dy0);
7930 p_cfg->ui16hdr10_dx1 = ni_htons(p_cfg->ui16hdr10_dx1);
7931 p_cfg->ui16hdr10_dy1 = ni_htons(p_cfg->ui16hdr10_dy1);
7932 p_cfg->ui16hdr10_dx2 = ni_htons(p_cfg->ui16hdr10_dx2);
7933 p_cfg->ui16hdr10_dy2 = ni_htons(p_cfg->ui16hdr10_dy2);
7934 p_cfg->ui16hdr10_wx = ni_htons(p_cfg->ui16hdr10_wx);
7935 p_cfg->ui16hdr10_wy = ni_htons(p_cfg->ui16hdr10_wy);
7936 p_cfg->ui32hdr10_maxluma = ni_htonl(p_cfg->ui32hdr10_maxluma);
7937 p_cfg->ui32hdr10_minluma = ni_htonl(p_cfg->ui32hdr10_minluma);
7938 p_cfg->ui32lumaLinesize = ni_htons(p_cfg->ui32lumaLinesize);
7939 p_cfg->ui32chromaLinesize = ni_htons(p_cfg->ui32chromaLinesize);
7940
7941 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
7942 p_encoder_config, buffer_size, ui32LBA);
7944 p_ctx->device_type, p_ctx->hw_id,
7945 &(p_ctx->session_id), OPT_1);
7946 if (NI_RETCODE_SUCCESS != retval)
7947 {
7948 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
7949 //Close the session since we can't configure it
7950 retval = ni_encoder_session_close(p_ctx, 0);
7951 if (NI_RETCODE_SUCCESS != retval)
7952 {
7953 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_encoder_session_close failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
7954 }
7955
7957 }
7958
7959END:
7960
7961 ni_aligned_free(p_encoder_config);
7962 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7963 return retval;
7964}
7965
7966/*!******************************************************************************
7967 * \brief Send a p_config command to configure encoding p_frame parameters.
7968 *
7969 * \param ni_session_context_t p_ctx - xcoder Context
7970 * \param ni_encoder_frame_params_t * params - pointer to the encoder ni_encoder_frame_params_t struct
7971 *
7972 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7973 *******************************************************************************/
7975{
7977 uint32_t buffer_size = sizeof(ni_encoder_frame_params_t);
7979 uint32_t ui32LBA = 0;
7980
7981 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7982
7983 if (!p_ctx || !p_params)
7984 {
7985 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7986 __func__);
7988 }
7989
7990 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7991 {
7992 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7993 __func__);
7995 }
7996
7997 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
7998 if (ni_posix_memalign((void **)&p_cfg, sysconf(_SC_PAGESIZE), buffer_size))
7999 {
8000 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
8001 NI_ERRNO, __func__);
8003 }
8004
8005 //configure the session here
8007
8008 //Flip the bytes!!
8009 p_cfg->force_picture_type = ni_htons(p_params->force_picture_type);
8010 p_cfg->data_format = ni_htons(p_params->data_format);
8011 p_cfg->picture_type = ni_htons(p_params->picture_type);
8012 p_cfg->video_width = ni_htons(p_params->video_width);
8013 p_cfg->video_height = ni_htons(p_params->video_height);
8014 p_cfg->timestamp = ni_htonl(p_params->timestamp);
8015
8016 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_cfg,
8017 buffer_size, ui32LBA) < 0)
8018 {
8019 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64 ", hw_id, %d, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
8020 //Close the session since we can't configure it
8021 retval = ni_encoder_session_close(p_ctx, 0);
8022 if (NI_RETCODE_SUCCESS != retval)
8023 {
8024 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_encoder_session_close failed: blk_io_handle: %" PRIx64 ", hw_id, %d, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
8025 }
8026
8028 }
8029
8030 ni_aligned_free(p_cfg);
8031 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
8032
8033 return retval;
8034}
8035
8036/*!******************************************************************************
8037 * \brief Get info from received p_frame
8038 *
8039 * \param
8040 *
8041 * \return
8042 *******************************************************************************/
8043int ni_create_frame(ni_frame_t* p_frame, uint32_t read_length, uint64_t*
8044 p_frame_offset, uint32_t* p_frame_dropped, bool is_hw_frame)
8045{
8046 uint32_t rx_size =
8047 read_length; //get the length since its the only thing in DW10 now
8048
8049 if (!p_frame || !p_frame_offset)
8050 {
8051 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
8052 __func__);
8054 }
8055
8056 *p_frame_offset = 0;
8057 if (p_frame_dropped)
8058 *p_frame_dropped = 0;
8059
8060 unsigned int metadata_size = NI_FW_META_DATA_SZ -
8062 unsigned int video_data_size = p_frame->data_len[0] + p_frame->data_len[1] +
8063 p_frame->data_len[2] + ((is_hw_frame) ? p_frame->data_len[3] : 0);
8064 ni_log(NI_LOG_DEBUG, "%s: rx_size = %d metadataSize = %d\n", __func__, rx_size,
8065 metadata_size);
8066
8067 p_frame->p_custom_sei_set = NULL;
8068
8069 if (rx_size == metadata_size)
8070 {
8071 video_data_size = 0;
8072 }
8073
8074 if (rx_size > video_data_size)
8075 {
8076 ni_metadata_dec_frame_t *p_meta =
8077 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
8078 video_data_size);
8079
8080 *p_frame_offset = p_meta->metadata_common.ui64_data.frame_offset;
8081 rx_size -= metadata_size;
8082 p_frame->crop_top = p_meta->metadata_common.crop_top;
8083 p_frame->crop_bottom = p_meta->metadata_common.crop_bottom;
8084 p_frame->crop_left = p_meta->metadata_common.crop_left;
8085 p_frame->crop_right = p_meta->metadata_common.crop_right;
8086 p_frame->ni_pict_type = p_meta->metadata_common.frame_type;
8087 p_frame->video_width = p_meta->metadata_common.frame_width;
8088 p_frame->video_height = p_meta->metadata_common.frame_height;
8089
8090 ni_log(
8092 "%s: [metadata] cropRight=%u, cropLeft=%u, "
8093 "cropBottom=%u, cropTop=%u, frame_offset=%" PRIu64 ", pic=%ux%u, "
8094 "pict_type=%d, crop=%ux%u, sei header: 0x%0x number %u size %u num_frame_dropped %u\n",
8095 __func__, p_frame->crop_right, p_frame->crop_left,
8096 p_frame->crop_bottom, p_frame->crop_top,
8099 p_meta->metadata_common.frame_height, p_frame->ni_pict_type,
8100 p_frame->crop_right - p_frame->crop_left,
8101 p_frame->crop_bottom - p_frame->crop_top, p_meta->sei_header,
8102 p_meta->sei_number, p_meta->sei_size, p_meta->metadata_common.num_frame_dropped);
8103
8104 p_frame->sei_total_len = 0;
8105 p_frame->sei_cc_offset = 0;
8106 p_frame->sei_cc_len = 0;
8111 p_frame->sei_hdr_plus_offset = 0;
8112 p_frame->sei_hdr_plus_len = 0;
8113 p_frame->sei_user_data_unreg_offset = 0;
8114 p_frame->sei_user_data_unreg_len = 0;
8115
8116 if (p_frame_dropped)
8117 {
8118 *p_frame_dropped = p_meta->metadata_common.num_frame_dropped;
8119 }
8120
8121 if (p_meta->sei_number)
8122 {
8123#if 1 // QUADRA_SEI_FMT
8124 ni_log(NI_LOG_DEBUG, "ui32SeiHeader 0x%x ui16SeiNumber %d ui16SeiSize %d SEI 0x%02x%02x\n",
8125 p_meta->sei_header, p_meta->sei_number, p_meta->sei_size,
8126 *((uint8_t*)p_meta + metadata_size),
8127 *((uint8_t*)p_meta + metadata_size+1));
8128
8129 { // retrieve sei from new format
8130 uint16_t ui16SeiProcessed = 0;
8131 ni_sei_header_t * pEntryHeader = &p_meta->first_sei_header;
8132 uint32_t ui32Offset = 0;
8133 uint32_t ui32Size;
8134
8135 rx_size -= p_meta->sei_size;
8136
8137 do
8138 {
8139 ui16SeiProcessed++;
8140
8141 if (pEntryHeader->status)
8142 {
8143 ui32Size = pEntryHeader->size;
8144 }
8145 else
8146 {
8147 ui32Size = 0;
8148 }
8149
8150 ni_log(NI_LOG_DEBUG, "SEI #%x st %d size %d ty %d sz/of %u/%u 0x%02x%02x\n",
8151 ui16SeiProcessed, pEntryHeader->status,
8152 pEntryHeader->size, pEntryHeader->type, ui32Size,
8153 ui32Offset,
8154 *((uint8_t *)p_meta + metadata_size + ui32Offset),
8155 *((uint8_t *)p_meta + metadata_size + ui32Offset + 1));
8156
8157 // - if multiple entries with same SEI type/subtype, only the last entry is saved;
8158 // consider to use sei_offset[] array instead of explicit sei_*_offset
8159 // - user_data_unreg (UDU) and custom sei passthru via HW and SW respectively
8160 // thus custom SEI is not processed here as it is by SW.
8161
8162 switch(pEntryHeader->type)
8163 {
8164 case 4: //HEVC_SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
8165 if (ui32Size)
8166 {
8167 uint8_t *ptr = (uint8_t*)p_meta + metadata_size + ui32Offset;
8168 if(ptr[0] == NI_HDR10P_SEI_BYTE0 && ptr[1] == NI_HDR10P_SEI_BYTE1 &&
8169 ptr[2] == NI_HDR10P_SEI_BYTE2 && ptr[3] == NI_HDR10P_SEI_BYTE3 &&
8170 ptr[4] == NI_HDR10P_SEI_BYTE4 && ptr[5] == NI_HDR10P_SEI_BYTE5)
8171 {
8172 p_frame->sei_hdr_plus_len = ui32Size;
8173 p_frame->sei_hdr_plus_offset =
8174 video_data_size + metadata_size + ui32Offset;
8175
8176 p_frame->sei_total_len += ui32Size;
8177
8178 ni_log(NI_LOG_DEBUG, "%s: hdr10+ size=%u hdr10+ offset=%u\n",
8179 __func__, p_frame->sei_hdr_plus_len,
8180 p_frame->sei_hdr_plus_offset);
8181 }
8182 else if(ptr[0] == NI_CC_SEI_BYTE0 && ptr[1] == NI_CC_SEI_BYTE1 &&
8183 ptr[2] == NI_CC_SEI_BYTE2 && ptr[3] == NI_CC_SEI_BYTE3 &&
8184 ptr[4] == NI_CC_SEI_BYTE4 && ptr[5] == NI_CC_SEI_BYTE5 &&
8185 ptr[6] == NI_CC_SEI_BYTE6 && ptr[7] == NI_CC_SEI_BYTE7)
8186 {
8187 // Found CC data
8188 // number of 3 byte close captions is bottom 5 bits of
8189 // 9th byte of T35 payload
8190 // uint32_t ui32CCSize = (ptr[8] & 0x1F) * 3; // avoid overwriting ui32CCSize
8191
8192 // return close caption data offset and length, and
8193 // skip past 10 header bytes to close caption data
8194 p_frame->sei_cc_len = (ptr[8] & 0x1F) * 3; // ui32CCSize;
8195 p_frame->sei_cc_offset = video_data_size + metadata_size
8196 + ui32Offset + 10;
8197
8198 p_frame->sei_total_len += p_frame->sei_cc_len;
8199
8201 "%s: close caption size %u ,"
8202 "offset %u = video size %u meta size %d off "
8203 " %u + 10\n",
8204 __func__, p_frame->sei_cc_len, p_frame->sei_cc_offset,
8205 video_data_size, metadata_size, ui32Offset);
8206 }
8207 else
8208 {
8210 "%s: unsupported T35; type %u size %u status %u "
8211 "offset %u\n",
8212 __func__, pEntryHeader->type, pEntryHeader->size,
8213 pEntryHeader->status, ui32Offset);
8214 }
8215 }
8216 else
8217 {
8219 "Error %s: T35 SEI dropped due to %s; type %u size %u status %u offset %u\n",
8220 __func__, pEntryHeader->status ? "missing payload" : "payload size exceeded SEI buffer size",
8221 pEntryHeader->type, pEntryHeader->size, pEntryHeader->status, ui32Offset);
8222 }
8223 break;
8224
8225 case 5: // HEVC_SEI_TYPE_USER_DATA_UNREGISTERED
8226 // set offset now so len=0 will signify an error if this SEI is dropped
8227 p_frame->sei_user_data_unreg_offset = video_data_size + metadata_size + ui32Offset;
8228 if (ui32Size)
8229 {
8230 p_frame->sei_user_data_unreg_len = ui32Size;
8231 p_frame->sei_total_len += ui32Size;
8232 ni_log(NI_LOG_DEBUG, "User Data Unreg size = %u\n", ui32Size);
8233 }
8234 else
8235 {
8236 p_frame->sei_user_data_unreg_len = 0; // in case there are multiple UDU SEI entries
8238 "Error %s: User Data Unreg dropped due to %s; type %u size %u status %u offset %u\n",
8239 __func__, pEntryHeader->status ? "missing payload" : "payload size exceeded SEI buffer size",
8240 pEntryHeader->type, pEntryHeader->size, pEntryHeader->status, ui32Offset);
8241 }
8242 break;
8243
8244 case 137: //HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO
8245 if (ui32Size)
8246 {
8247 p_frame->sei_hdr_mastering_display_color_vol_len = ui32Size;
8249 video_data_size + metadata_size + ui32Offset;
8250
8251 p_frame->sei_total_len += ui32Size;
8254 *)((uint8_t *)p_meta + metadata_size + ui32Offset);
8255
8256 ni_log(NI_LOG_DEBUG, "Display Primaries x[0]=%u y[0]=%u\n",
8257 ni_ntohs(pColourVolume->display_primaries[0][0]),
8258 ni_ntohs(pColourVolume->display_primaries[0][1]));
8259 ni_log(NI_LOG_DEBUG, "Display Primaries x[1]=%u y[1]=%u\n",
8260 ni_ntohs(pColourVolume->display_primaries[1][0]),
8261 ni_ntohs(pColourVolume->display_primaries[1][1]));
8262 ni_log(NI_LOG_DEBUG, "Display Primaries x[2]=%u y[2]=%u\n",
8263 ni_ntohs(pColourVolume->display_primaries[2][0]),
8264 ni_ntohs(pColourVolume->display_primaries[2][1]));
8265
8266 ni_log(NI_LOG_DEBUG, "White Point x=%u y=%u\n",
8267 ni_ntohs(pColourVolume->white_point_x),
8268 ni_ntohs(pColourVolume->white_point_y));
8269 ni_log(NI_LOG_DEBUG, "Display Mastering Lum, Max=%u Min=%u\n",
8270 ni_ntohl(pColourVolume->max_display_mastering_luminance),
8271 ni_ntohl(pColourVolume->min_display_mastering_luminance));
8272 }
8273 else
8274 {
8276 "Error %s: mastering display info dropped due to %s; type %u size %u status %u offset %u\n",
8277 __func__, pEntryHeader->status ? "missing payload" : "payload size exceeded SEI buffer size",
8278 pEntryHeader->type, pEntryHeader->size, pEntryHeader->status, ui32Offset);
8279 }
8280 break;
8281
8282 case 144: //HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO
8283 if (ui32Size)
8284 {
8285 p_frame->sei_hdr_content_light_level_info_len = ui32Size;
8287 video_data_size + metadata_size + ui32Offset;
8288
8289 p_frame->sei_total_len += ui32Offset;
8290
8293 (uint8_t*)p_meta + metadata_size + ui32Offset);
8294
8295 ni_log(NI_LOG_DEBUG, "Max Content Light level=%u Max Pic Avg Light Level=%u\n",
8296 ni_ntohs(pLightLevel->max_content_light_level),
8297 ni_ntohs(pLightLevel->max_pic_average_light_level));
8298 }
8299 else
8300 {
8302 "Error %s: content light level info dropped due to %s; type %u size %u status %u offset %u\n",
8303 __func__, pEntryHeader->status ? "missing payload" : "payload size exceeded SEI buffer size",
8304 pEntryHeader->type, pEntryHeader->size, pEntryHeader->status, ui32Offset);
8305 }
8306 break;
8307
8308 case 200: // Custom SEI not included in HEVC_SEI_Type
8309 if (ui32Size)
8310 {
8311 p_frame->vui_len = ui32Size;
8312 p_frame->vui_offset =
8313 video_data_size + metadata_size + ui32Offset;
8314 p_frame->sei_total_len += ui32Size;
8315 }
8316 break;
8317 case 206: // Customer reset ppu resolution, need dropped
8318 ni_log(NI_LOG_DEBUG, "Custom SEI PPU_RECONFIG dropped", __func__);
8319 break;
8320 default:
8322 "Warning %s: SEI message dropped (unsupported - check "
8323 "decoder SEI bitmap settings);"
8324 " type %u size %u status %u offset %u payload bytes %u\n",
8325 __func__, pEntryHeader->type, pEntryHeader->size,
8326 pEntryHeader->status, ui32Offset, ui32Size);
8327 break;
8328 }
8329 ui32Offset += ui32Size;
8330 pEntryHeader = (ni_sei_header_t *)((uint8_t*)p_meta + metadata_size + ui32Offset);
8331 ui32Offset += sizeof(ni_sei_header_t);
8332 } while (ui32Offset <= p_meta->sei_size && ui16SeiProcessed < p_meta->sei_number);
8333
8334 if (p_meta->sei_number != ui16SeiProcessed)
8335 {
8336 ni_log(
8338 "Error %s: number of SEI messages reported %u != processed %u\n",
8339 __func__, p_meta->sei_number, ui16SeiProcessed);
8340 }
8341 }
8342
8343#else // QUADRA_SEI_FMT
8344
8345 // ni_assert(p_meta->sei_header);
8346 // else // backward compatibility
8347 {
8348 ni_sei_user_data_entry_t *pEntry;
8349 uint32_t ui32CCOffset = 0, ui32CCSize = 0;
8350
8351 rx_size -= p_meta->sei_size;
8352
8353 pEntry = (ni_sei_user_data_entry_t *)((uint8_t*)p_meta + metadata_size);
8354
8355 if (find_t35_sei(p_meta->sei_header, NI_T35_SEI_HDR10_PLUS, pEntry,
8356 &ui32CCOffset, &ui32CCSize))
8357 {
8358 p_frame->sei_hdr_plus_len = ui32CCSize;
8359 p_frame->sei_hdr_plus_offset =
8360 video_data_size + metadata_size + ui32CCOffset;
8361
8362 p_frame->sei_total_len += ui32CCSize;
8363
8364 ni_log(NI_LOG_DEBUG, "%s: hdr10+ size=%u hdr10+ offset=%u\n", __func__,
8365 p_frame->sei_hdr_plus_len, p_frame->sei_hdr_plus_offset);
8366 }
8367 else
8368 {
8369 ni_log(NI_LOG_DEBUG, "%s: hdr+ NOT found in meta data!\n", __func__);
8370 }
8371
8372 if (find_t35_sei(p_meta->sei_header, NI_T35_SEI_CLOSED_CAPTION, pEntry,
8373 &ui32CCOffset, &ui32CCSize))
8374 {
8375 uint8_t *ptr;
8376 // Found CC data at pEntry + ui32CCOffset
8377 ptr = (uint8_t*)pEntry + ui32CCOffset;
8378 // number of 3 byte close captions is bottom 5 bits of
8379 // 9th byte of T35 payload
8380 ui32CCSize = (ptr[8] & 0x1F) * 3;
8381
8382 // return close caption data offset and length, and
8383 // skip past 10 header bytes to close caption data
8384 p_frame->sei_cc_len = ui32CCSize;
8385 p_frame->sei_cc_offset = video_data_size + metadata_size
8386 + ui32CCOffset + 10;
8387
8388 p_frame->sei_total_len += p_frame->sei_cc_len;
8389
8391 "%s: close caption size %u ,"
8392 "offset %u = video size %u meta size %u off "
8393 " %u + 10\n",
8394 __func__, p_frame->sei_cc_len, p_frame->sei_cc_offset,
8395 video_data_size, metadata_size, ui32CCOffset);
8396 }
8397 else
8398 {
8399 ni_log(NI_LOG_DEBUG, "%s: close caption NOT found in meta data!\n",
8400 __func__);
8401 }
8402
8403 if (find_sei(p_meta->sei_header, pEntry,
8405 &ui32CCOffset, &ui32CCSize))
8406 {
8407 p_frame->sei_hdr_mastering_display_color_vol_len = ui32CCSize;
8409 video_data_size + metadata_size + ui32CCOffset;
8410
8411 p_frame->sei_total_len += ui32CCSize;
8412
8413 ni_dec_mastering_display_colour_volume_t* pColourVolume =
8414 (ni_dec_mastering_display_colour_volume_t*)((uint8_t*)pEntry + ui32CCOffset);
8415
8416 ni_log(NI_LOG_DEBUG, "Display Primaries x[0]=%u y[0]=%u\n",
8417 pColourVolume->display_primaries_x[0],
8418 pColourVolume->display_primaries_y[0]);
8419 ni_log(NI_LOG_DEBUG, "Display Primaries x[1]=%u y[1]=%u\n",
8420 pColourVolume->display_primaries_x[1],
8421 pColourVolume->display_primaries_y[1]);
8422 ni_log(NI_LOG_DEBUG, "Display Primaries x[2]=%u y[2]=%u\n",
8423 pColourVolume->display_primaries_x[2],
8424 pColourVolume->display_primaries_y[2]);
8425
8426 ni_log(NI_LOG_DEBUG, "White Point x=%u y=%u\n",
8427 pColourVolume->white_point_x,
8428 pColourVolume->white_point_y);
8429 ni_log(NI_LOG_DEBUG, "Display Mastering Lum, Max=%u Min=%u\n",
8430 pColourVolume->max_display_mastering_luminance, pColourVolume->min_display_mastering_luminance);
8431 }
8432 if (find_sei(p_meta->sei_header, pEntry,
8434 &ui32CCOffset, &ui32CCSize))
8435 {
8436 p_frame->sei_hdr_content_light_level_info_len = ui32CCSize;
8438 video_data_size + metadata_size + ui32CCOffset;
8439
8440 p_frame->sei_total_len += ui32CCSize;
8441
8442 ni_content_light_level_info_t* pLightLevel =
8443 (ni_content_light_level_info_t*)((uint8_t*)pEntry + ui32CCOffset);
8444 ni_log(NI_LOG_DEBUG, "Max Content Light level=%u Max Pic Avg Light Level=%u\n",
8445 pLightLevel->max_content_light_level, pLightLevel->max_pic_average_light_level);
8446 }
8447
8448 if (find_sei(p_meta->sei_header, pEntry,
8450 &ui32CCOffset, &ui32CCSize) ||
8451 find_sei(p_meta->sei_header, pEntry,
8453 &ui32CCOffset, &ui32CCSize))
8454 {
8455 p_frame->sei_user_data_unreg_len = ui32CCSize;
8457 video_data_size + metadata_size + ui32CCOffset;
8458
8459 p_frame->sei_total_len += ui32CCSize;
8460
8461 ni_log(NI_LOG_DEBUG, "User Data Unreg size = %u\n", ui32CCSize);
8462 }
8463 }
8464#endif // QUADRA_SEI_FMT
8465 if (0 == p_frame->sei_total_len)
8466 {
8467 ni_log(NI_LOG_DEBUG, "Warning retrieved 0 supported SEI !\n");
8468 }
8469 }
8470 }
8471
8472 p_frame->dts = NI_NOPTS_VALUE;
8473 p_frame->pts = NI_NOPTS_VALUE;
8474 //p_frame->end_of_stream = isEndOfStream;
8475 p_frame->start_of_stream = 0;
8476
8477 if (rx_size == 0)
8478 {
8479 p_frame->data_len[0] = 0;
8480 p_frame->data_len[1] = 0;
8481 p_frame->data_len[2] = 0;
8482 p_frame->data_len[3] = 0;
8483 }
8484
8485 ni_log(NI_LOG_DEBUG, "received [0x%08x] data size: %d, end of stream=%u\n",
8486 read_length, rx_size, p_frame->end_of_stream);
8487
8488 return rx_size;
8489}
8490
8491/*!******************************************************************************
8492 * \brief Get info from received xcoder capability
8493 *
8494 * \param
8495 *
8496 * \return
8497 *******************************************************************************/
8499 ni_device_handle_t device_handle, bool device_in_ctxt)
8500{
8501 int i, total_types = 0, total_modules = 0;
8502 ni_nvme_identity_t *p_id_data = (ni_nvme_identity_t *)p_data;
8503
8504 COMPILE_ASSERT(sizeof(p_cap->xcoder_cnt) <= sizeof(p_id_data->xcoder_cnt) &&
8506 sizeof(p_id_data->xcoder_cnt[0]) ==
8507 sizeof(p_cap->xcoder_cnt));
8508
8509 if (!p_cap || !p_data)
8510 {
8511 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
8512 __func__);
8513 LRETURN;
8514 }
8515
8516 if ((p_id_data->ui16Vid != NETINT_PCI_VENDOR_ID) ||
8517 (p_id_data->ui16Ssvid != NETINT_PCI_VENDOR_ID))
8518 {
8519 if (device_in_ctxt)
8520 {
8522 "ERROR: Previously in context device got an invalid vendor ID 0x%X SSVID 0x%X. Netint "
8523 "ID 0x%X. Retrying\n",
8524 p_id_data->ui16Vid, p_id_data->ui16Ssvid, NETINT_PCI_VENDOR_ID);
8525 //print some other fields as a test to see if they are invalid too
8526 ni_log(NI_LOG_ERROR, "Model Number: %.*s\n",
8527 (int)sizeof(p_id_data->ai8Sn), p_id_data->ai8Sn);
8528 ni_log(NI_LOG_ERROR, "Serial Number: %.*s\n",
8529 (int)sizeof(p_id_data->ai8Mn), p_id_data->ai8Mn);
8530 ni_log(NI_LOG_ERROR, "Firmware Revision: %.*s\n",
8531 (int)sizeof(p_id_data->ai8Fr), p_id_data->ai8Fr);
8532 ni_log(NI_LOG_ERROR, "xcoder_num_elements: %d\n",
8533 p_id_data->xcoder_num_elements);
8534
8535 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
8536 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
8537 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_data,
8538 NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
8539 {
8540 LRETURN;
8541 }
8542 if ((p_id_data->ui16Vid != NETINT_PCI_VENDOR_ID) ||
8543 (p_id_data->ui16Ssvid != NETINT_PCI_VENDOR_ID))
8544 {
8546 "ERROR: %s(): Retry got an invalid vendor ID too 0x%X SSVID "
8547 "0x%X!\n",
8548 __func__, p_id_data->ui16Vid, p_id_data->ui16Ssvid);
8549 //print some other fields as a test to see if they are invalid too
8550 ni_log(NI_LOG_ERROR, "Model Number: %.*s\n",
8551 (int)sizeof(p_id_data->ai8Sn), p_id_data->ai8Sn);
8552 ni_log(NI_LOG_ERROR, "Serial Number: %.*s\n",
8553 (int)sizeof(p_id_data->ai8Mn), p_id_data->ai8Mn);
8554 ni_log(NI_LOG_ERROR, "Firmware Revision: %.*s\n",
8555 (int)sizeof(p_id_data->ai8Fr), p_id_data->ai8Fr);
8556 ni_log(NI_LOG_ERROR, "xcoder_num_elements: %d\n",
8557 p_id_data->xcoder_num_elements);
8558 LRETURN;
8559 }
8560 else
8561 {
8563 "Retry got valid a vendor ID 0x%X SSVID 0x%X. Netint ID 0x%X\n",
8564 p_id_data->ui16Vid, p_id_data->ui16Ssvid, NETINT_PCI_VENDOR_ID);
8565 }
8566 }
8567 else
8568 {
8569 LRETURN;
8570 }
8571 }
8572
8573 memcpy(p_cap->serial_number, p_id_data->ai8Sn, sizeof(p_cap->serial_number));
8574 memcpy(p_cap->model_number, p_id_data->ai8Mn, sizeof(p_cap->model_number));
8575
8576 memset(p_cap->fw_rev, 0, sizeof(p_cap->fw_rev));
8577 memcpy(p_cap->fw_rev, p_id_data->ai8Fr, sizeof(p_cap->fw_rev));
8578
8579 p_cap->warning_temp = p_id_data->ui16Wctemp;
8580 p_cap->critical_temp = p_id_data->ui16Cctemp;
8581
8582 ni_log(NI_LOG_DEBUG, "F/W rev: %.*s\n", (int)sizeof(p_cap->fw_rev),
8583 p_cap->fw_rev);
8584
8585 if (p_id_data->xcoder_num_elements)
8586 {
8587 ni_log(NI_LOG_DEBUG, "xcoder_num_elements: %d xcoder_num_devices: %d\n",
8588 p_id_data->xcoder_num_elements,
8589 p_id_data->xcoder_num_devices);
8590
8591 for (i = 0; i < NI_DEVICE_TYPE_XCODER_MAX; i++)
8592 {
8593 if (p_id_data->xcoder_cnt[i])
8594 {
8595 total_types++;
8596 total_modules += p_id_data->xcoder_cnt[i];
8597 ni_log(NI_LOG_DEBUG, "type #%d: xcoder_cnt[%d] = %d\n", total_types, i,
8598 p_id_data->xcoder_cnt[i]);
8599 }
8600 }
8601
8602 if (p_id_data->xcoder_num_elements != total_types ||
8603 p_id_data->xcoder_num_devices != total_modules)
8604 {
8606 "Error: mismatch; xcoder_num_elements: %d (calculated: %d) "
8607 "xcoder_num_devices: %d (calculated: %d)\n",
8608 p_id_data->xcoder_num_elements, total_types,
8609 p_id_data->xcoder_num_devices, total_modules);
8610 LRETURN;
8611 }
8612
8614 p_cap->hw_elements_cnt = p_id_data->xcoder_num_elements;
8615 p_cap->xcoder_devices_cnt = p_id_data->xcoder_num_devices;
8616 memcpy(p_cap->xcoder_cnt, p_id_data->xcoder_cnt,
8617 NI_DEVICE_TYPE_XCODER_MAX * sizeof(p_id_data->xcoder_cnt[0]));
8618
8620 {
8621 if (!p_id_data->xcoder_cnt[i])
8622 continue;
8623
8624 p_cap->xcoder_devices[i].hw_id = p_id_data->xcoder_devices[i].hw_id;
8628 p_cap->xcoder_devices[i].codec_format =
8629 p_id_data->xcoder_devices[i].hw_codec_format;
8630 p_cap->xcoder_devices[i].codec_type =
8631 p_id_data->xcoder_devices[i].hw_codec_type;
8634 if (i == NI_DEVICE_TYPE_ENCODER)
8635 {
8638 }
8639 else
8640 {
8643 }
8644
8645 p_cap->xcoder_devices[i].video_profile =
8646 p_id_data->xcoder_devices[i].hw_video_profile;
8647 p_cap->xcoder_devices[i].video_level =
8648 p_id_data->xcoder_devices[i].hw_video_level;
8649 }
8650
8651 goto CAP_POPULATED;
8652 }
8653
8654 p_cap->device_is_xcoder = p_id_data->device_is_xcoder;
8655 ni_log(NI_LOG_DEBUG, "device_is_xcoder: value in id cmd: %u\n",
8656 p_cap->device_is_xcoder);
8657 if (0 == p_cap->device_is_xcoder)
8658 {
8659 ni_log(NI_LOG_ERROR, "Not an xcoder device !\n");
8660
8661 if (device_in_ctxt)
8662 {
8664 "ERROR: Previously in context device is not a xcoder device "
8665 "now!\n");
8666 }
8667 LRETURN;
8668 }
8669
8670 p_cap->hw_elements_cnt = p_id_data->xcoder_num_hw;
8671
8672 total_modules = p_cap->xcoder_cnt[NI_DEVICE_TYPE_DECODER] =
8673 p_id_data->xcoder_num_h264_decoder_hw +
8674 p_id_data->xcoder_num_h265_decoder_hw;
8675
8677 p_id_data->xcoder_num_h264_encoder_hw +
8678 p_id_data->xcoder_num_h265_encoder_hw;
8679
8680 total_modules += p_cap->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
8681
8682 p_cap->xcoder_devices_cnt = total_modules;
8683
8684 if (total_modules >= 1)
8685 {
8686 p_cap->xcoder_devices[0].hw_id = p_id_data->hw0_id;
8690 p_cap->xcoder_devices[0].codec_format = p_id_data->hw0_codec_format;
8691 p_cap->xcoder_devices[0].codec_type = p_id_data->hw0_codec_type;
8696 p_cap->xcoder_devices[0].video_profile = p_id_data->hw0_video_profile;
8697 p_cap->xcoder_devices[0].video_level = p_id_data->hw0_video_level;
8698 }
8699 if (total_modules >= 2)
8700 {
8701 p_cap->xcoder_devices[1].hw_id = p_id_data->hw1_id;
8705 p_cap->xcoder_devices[1].codec_format = p_id_data->hw1_codec_format;
8706 p_cap->xcoder_devices[1].codec_type = p_id_data->hw1_codec_type;
8711 p_cap->xcoder_devices[1].video_profile = p_id_data->hw1_video_profile;
8712 p_cap->xcoder_devices[1].video_level = p_id_data->hw1_video_level;
8713 }
8714 if (total_modules >= 3)
8715 {
8716 p_cap->xcoder_devices[2].hw_id = p_id_data->hw2_id;
8720 p_cap->xcoder_devices[2].codec_format = p_id_data->hw2_codec_format;
8721 p_cap->xcoder_devices[2].codec_type = p_id_data->hw2_codec_type;
8726 p_cap->xcoder_devices[2].video_profile = p_id_data->hw2_video_profile;
8727 p_cap->xcoder_devices[2].video_level = p_id_data->hw2_video_level;
8728 }
8729 if (total_modules >= 4)
8730 {
8731 p_cap->xcoder_devices[3].hw_id = p_id_data->hw3_id;
8735 p_cap->xcoder_devices[3].codec_format = p_id_data->hw3_codec_format;
8736 p_cap->xcoder_devices[3].codec_type = p_id_data->hw3_codec_type;
8741 p_cap->xcoder_devices[3].video_profile = p_id_data->hw3_video_profile;
8742 p_cap->xcoder_devices[3].video_level = p_id_data->hw3_video_level;
8743 }
8744
8745CAP_POPULATED:
8746
8747 for (i = 0; i < NI_MAX_DEVICES_PER_HW_INSTANCE; i++)
8748 {
8749 ni_log(NI_LOG_DEBUG, "HW%d hw_id: %d\n", i, p_cap->xcoder_devices[i].hw_id);
8750 ni_log(NI_LOG_DEBUG, "HW%d max_number_of_contexts: %d\n", i,
8752 ni_log(NI_LOG_DEBUG, "HW%d max_4k_fps: %d\n", i,
8753 p_cap->xcoder_devices[i].max_4k_fps);
8754 ni_log(NI_LOG_DEBUG, "HW%d codec_format: %d\n", i,
8755 p_cap->xcoder_devices[i].codec_format);
8756 ni_log(NI_LOG_DEBUG, "HW%d codec_type: %d\n", i,
8757 p_cap->xcoder_devices[i].codec_type);
8758 ni_log(NI_LOG_DEBUG, "HW%d max_video_width: %d\n", i,
8760 ni_log(NI_LOG_DEBUG, "HW%d max_video_height: %d\n", i,
8762 ni_log(NI_LOG_DEBUG, "HW%d min_video_width: %d\n", i,
8764 ni_log(NI_LOG_DEBUG, "HW%d min_video_height: %d\n", i,
8766 ni_log(NI_LOG_DEBUG, "HW%d video_profile: %d\n", i,
8767 p_cap->xcoder_devices[i].video_profile);
8768 ni_log(NI_LOG_DEBUG, "HW%d video_level: %d\n", i,
8769 p_cap->xcoder_devices[i].video_level);
8770 }
8771
8772 memset(p_cap->fw_branch_name, 0, sizeof(p_cap->fw_branch_name));
8773 memcpy(p_cap->fw_branch_name, p_id_data->fw_branch_name,
8774 sizeof(p_cap->fw_branch_name) - 1);
8775 ni_log(NI_LOG_DEBUG, "F/W branch name: %s\n", p_cap->fw_branch_name);
8776 memset(p_cap->fw_commit_time, 0, sizeof(p_cap->fw_commit_time));
8777 memcpy(p_cap->fw_commit_time, p_id_data->fw_commit_time,
8778 sizeof(p_cap->fw_commit_time) - 1);
8779 ni_log(NI_LOG_DEBUG, "F/W commit time: %s\n", p_cap->fw_commit_time);
8780 memset(p_cap->fw_commit_hash, 0, sizeof(p_cap->fw_commit_hash));
8781 memcpy(p_cap->fw_commit_hash, p_id_data->fw_commit_hash,
8782 sizeof(p_cap->fw_commit_hash) - 1);
8783 ni_log(NI_LOG_DEBUG, "F/W commit hash: %s\n", p_cap->fw_commit_hash);
8784 memset(p_cap->fw_build_time, 0, sizeof(p_cap->fw_build_time));
8785 memcpy(p_cap->fw_build_time, p_id_data->fw_build_time,
8786 sizeof(p_cap->fw_build_time) - 1);
8787 ni_log(NI_LOG_DEBUG, "F/W build time: %s\n", p_cap->fw_build_time);
8788 memset(p_cap->fw_build_id, 0, sizeof(p_cap->fw_build_id));
8789 memcpy(p_cap->fw_build_id, p_id_data->fw_build_id,
8790 sizeof(p_cap->fw_build_id) - 1);
8791 ni_log(NI_LOG_DEBUG, "F/W build id: %s\n", p_cap->fw_build_id);
8792
8793END:
8794 return;
8795}
8796
8797static uint32_t presetGopSize[] = {
8798 1,
8799 1,
8800 1,
8801 1,
8802 2,
8803 4,
8804 4,
8805 4,
8806 8 };
8807
8808/*!******************************************************************************
8809 * \brief insert the 32 bits of integer value at bit position pos
8810 *
8811 * \param int pos, int value
8812 *
8813 * \return void
8814 ******************************************************************************/
8815void ni_fix_VUI(uint8_t *vui, int pos, int value)
8816{
8817 int pos_byte = (pos/8);
8818 int pos_in_byte = pos%8;
8819 int remaining_bytes_in_current_byte = 8 - pos_in_byte;
8820
8821 if (pos_in_byte == 0) // at beginning of the byte
8822 {
8823 vui[pos_byte] = (uint8_t)(value >> 24);
8824 vui[pos_byte+1] = (uint8_t)(value >> 16);
8825 vui[pos_byte+2] = (uint8_t)(value >> 8);
8826 vui[pos_byte+3] = (uint8_t)(value);
8827 }
8828 else
8829 {
8830 vui[pos_byte] = vui[pos_byte] + (uint8_t)(value >> (32-remaining_bytes_in_current_byte));
8831 vui[pos_byte+1] = (uint8_t)(value >> (32-remaining_bytes_in_current_byte-8));
8832 vui[pos_byte+2] = (uint8_t)(value >> (32-remaining_bytes_in_current_byte-16));
8833 vui[pos_byte+3] = (uint8_t)(value >> (32-remaining_bytes_in_current_byte-24));
8834 vui[pos_byte+4] = vui[pos_byte+4] + ((uint8_t)(value << remaining_bytes_in_current_byte));
8835 }
8836
8837}
8838
8839/*!******************************************************************************
8840* \brief Setup all xcoder configurations with custom parameters (Rev. B)
8841*
8842* \param
8843*
8844* \return
8845******************************************************************************/
8847 ni_decoder_config_t *p_cfg,
8848 ni_xcoder_params_t *p_src,
8849 uint32_t max_pkt_size)
8850{
8851 int i,j;
8852 ni_decoder_input_params_t* p_dec = NULL;
8853 if ((!p_ctx) || (!p_cfg) || (!p_src))
8854 {
8855 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
8856 __func__);
8857 return;
8858 }
8859 p_dec = &p_src->dec_input_params;
8860 int w = p_src->source_width;
8861 int h = p_src->source_height;
8862 bool shift_params = false;
8863
8864 p_cfg->ui8HWFrame = p_dec->hwframes;
8865 p_cfg->ui8MCMode = p_dec->mcmode;
8868 p_cfg->ui8DisablePictureReordering = (p_dec->decoder_low_delay > 0) ? 1 :
8869 (p_dec->decoder_disable_reorder ? 1 : 0);
8870 p_ctx->force_low_delay = p_dec->force_low_delay;
8872 p_cfg->ui32SourceWidth = w;
8873 p_cfg->ui32SourceHeight = h;
8874
8875 if (max_pkt_size)
8876 {
8877 p_cfg->ui32MaxPktSize = max_pkt_size;
8878 } else {
8879 // p_cfg->ui32MaxPktSize = width x height x 3/2 x min compression ratio(QP=0);
8880 // set min compression ratio = 1/2, so MaxPktSize = w * h * 3/4
8881 p_cfg->ui32MaxPktSize = w * h * 3 / 4;
8882 }
8883 // packet buffer aligned to NI_MAX_PACKET_SZ(128k)
8884 p_cfg->ui32MaxPktSize =
8886
8887 p_cfg->fps_number =
8888 ((ni_xcoder_params_t *)p_ctx->p_session_config)->fps_number;
8889 p_cfg->fps_denominator =
8890 ((ni_xcoder_params_t *)p_ctx->p_session_config)->fps_denominator;
8891 ni_log2(p_ctx, NI_LOG_INFO, "%s height %d width %d fps_number %d fps_denominator %d\n",
8892 __func__, h, w, p_cfg->fps_number, p_cfg->fps_denominator);
8893
8894 p_cfg->asOutputConfig[0].ui8Enabled = 1; // always enabled
8895 p_cfg->asOutputConfig[1].ui8Enabled = p_dec->enable_out1;
8896 p_cfg->asOutputConfig[2].ui8Enabled = p_dec->enable_out2;
8897 if (p_cfg->asOutputConfig[2].ui8Enabled && p_cfg->asOutputConfig[1].ui8Enabled == 0)
8898 {
8899 p_cfg->asOutputConfig[1].ui8Enabled = 1;
8900 p_cfg->asOutputConfig[2].ui8Enabled = 0;
8901 shift_params = true;
8902 ni_log2(p_ctx, NI_LOG_DEBUG, "Output 2 used before output 1, Shifting output2 settings to output1 and disabling output 2\n");
8903 }
8904
8905 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
8906 {
8907 if (!shift_params || i == 0)
8908 {
8909 j = i;
8910 }
8911 else
8912 {
8913 j = (i == 1) ? 2 : 1; //swap settings
8914 }
8915 p_cfg->asOutputConfig[i].ui8Force8Bit = p_dec->force_8_bit[j];
8916 p_cfg->asOutputConfig[i].ui8SemiPlanarEnabled = p_dec->semi_planar[j];
8917 p_cfg->asOutputConfig[i].ui8CropMode = p_dec->crop_mode[j];
8919 (uint16_t)((p_dec->crop_whxy[j][0]) & 0xFFFE);
8921 (uint16_t)((p_dec->crop_whxy[j][1]) & 0xFFFE);
8923 (uint16_t)((p_dec->crop_whxy[j][2]) & 0xFFFE);
8925 (uint16_t)((p_dec->crop_whxy[j][3]) & 0xFFFE);
8926
8927 //Offset resized if out of bounds
8929 {
8931 }
8933 {
8935 }
8936
8937 if (p_dec->enable_ppu_scale_adapt)
8938 {
8940 }
8941 else if (p_dec->scale_long_short_edge[j] == 1)
8942 {
8944 }
8945 else if (p_dec->scale_long_short_edge[j] == 2)
8946 {
8948 }
8949 else
8950 {
8952 }
8954
8955 if (p_dec->scale_round[j] == -1)
8956 {
8957 if (p_cfg->asOutputConfig[i].ui8EnablePpuScaleAdapt == 1 ||
8959 {
8960 p_cfg->asOutputConfig[i].ui8ScaleResCeil = p_dec->scale_resolution_ceil[j] - 1;
8961 }
8962 else
8963 {
8965 }
8966 }
8967 else if (p_dec->scale_round[j] == 0)
8968 {
8970 }
8971 else
8972 {
8973 p_cfg->asOutputConfig[i].ui8ScaleResCeil = p_dec->scale_resolution_ceil[j] - 1;
8974 }
8975
8976 if (p_cfg->ui8MaxExtraHwFrameCnt != 255 &&
8978 {
8979 p_cfg->asOutputConfig[i].sOutputPictureSize.i16Width = (p_dec->scale_wh[j][0] < 0) ?
8980 (int16_t)(p_dec->scale_wh[j][0] & -2) : (int16_t)((p_dec->scale_wh[j][0]+1) & 0xFFFE);
8981 p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height = (p_dec->scale_wh[j][1] < 0) ?
8982 (int16_t)(p_dec->scale_wh[j][1] & -2) : (int16_t)((p_dec->scale_wh[j][1]+1) & 0xFFFE);
8983 }
8984 else
8985 {
8986 p_cfg->asOutputConfig[i].sOutputPictureSize.i16Width = (p_dec->scale_wh[j][0] < 0) ?
8987 0 : (int16_t)((p_dec->scale_wh[j][0]+1) & 0xFFFE);
8988 p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height = (p_dec->scale_wh[j][1] < 0) ?
8989 0 : (int16_t)((p_dec->scale_wh[j][1]+1) & 0xFFFE);
8990 }
8991
8994 {
8995 p_cfg->asOutputConfig[i].ui8ScaleEnabled = 1;
8996 }
8997 else
8998 {
8999 p_cfg->asOutputConfig[i].ui8ScaleEnabled = 0;
9000 }
9001 }
9002
9004 if (p_cfg->ui8MaxExtraHwFrameCnt != 255 &&
9006 {
9007 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): maxExtraHwFrameCnt is not support for FW < 6rB\n", __func__);
9008 }
9009 p_cfg->ui8EcPolicy = p_dec->ec_policy;
9012 if (p_cfg->ui8EnableAdvancedEc == 2 &&
9014 {
9015 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): (enableAdvancedEc == 2) is not support for FW < 6rO\n", __func__);
9016 p_cfg->ui8EnableAdvancedEc = 1;
9017 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): reset enableAdvancedEc to %d\n", __func__, p_cfg->ui8EnableAdvancedEc);
9018 }
9021 {
9022 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): (EcPolicy == limited_error) not supported for FW < 6ri\n", __func__);
9024 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): reset EcPolicy to %d\n", __func__, p_cfg->ui8EcPolicy);
9025 }
9028 {
9029 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): setting ecErrThreshold not supported for FW < 6ri\n", __func__);
9031 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): reset ecErrThreshold to %d\n", __func__, NI_EC_ERR_THRESHOLD_DEFAULT);
9032 }
9035 {
9036 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): (EcPolicy == best_effort_out_dc) not supported for FW < 6s1\n", __func__);
9038 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): reset EcPolicy to %d\n", __func__, p_cfg->ui8EcPolicy);
9039 }
9042 if (p_cfg->ui8SurviveStreamErr != 0 &&
9043 ni_cmp_fw_api_ver((char *)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rl") < 0) {
9044 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): surviveStreamErr is not supported for FW < 6rl\n", __func__);
9045 }
9046 if (p_dec->reduce_dpb_delay)
9047 {
9048 if (p_ctx->codec_format == NI_CODEC_FORMAT_H264 &&
9050 p_cfg->ui8ReduceDpbDelay = p_dec->reduce_dpb_delay;
9051 else
9052 {
9053 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s():Not support to reduce dpb delay and reset.\n", __func__);
9054 p_dec->reduce_dpb_delay = 0;
9055 }
9056 }
9057
9058 //print it all out
9059 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8HWFrame = %d\n", p_cfg->ui8HWFrame);
9060 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8MCMode = %d\n", p_cfg->ui8MCMode);
9061 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8UduSeiEnabled = %d\n", p_cfg->ui8UduSeiEnabled);
9062 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16MaxSeiDataSize = %d\n", p_cfg->ui16MaxSeiDataSize);
9063 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8DisablePictureReordering = %d\n", p_cfg->ui8DisablePictureReordering);
9064 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8Enabled0 = %d\n", p_cfg->asOutputConfig[0].ui8Enabled);
9065 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8Enabled1 = %d\n", p_cfg->asOutputConfig[1].ui8Enabled);
9066 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8Enabled2 = %d\n", p_cfg->asOutputConfig[2].ui8Enabled);
9067 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32MaxPktSize = %u\n", p_cfg->ui32MaxPktSize);
9068 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
9069 {
9070 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8Force8Bit %d\n", i, p_cfg->asOutputConfig[i].ui8Force8Bit);
9071 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8SemiPlanarEnabled %d\n", i, p_cfg->asOutputConfig[i].ui8SemiPlanarEnabled);
9072 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8CropMode %d\n", i, p_cfg->asOutputConfig[i].ui8CropMode);
9073 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] sCroppingRectable.ui16XYWH %d,%d - %d x %d\n", i,
9078 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] sOutputPictureSize.i16Width x height %d x %d\n", i,
9081 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8ScaleEnabled %d\n", i, p_cfg->asOutputConfig[i].ui8ScaleEnabled);
9082 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8EnablePpuScaleAdapt %u\n", i, p_cfg->asOutputConfig[i].ui8EnablePpuScaleAdapt);
9083 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8EnablePpuScaleLimit %u\n", i, p_cfg->asOutputConfig[i].ui8EnablePpuScaleLimit);
9084 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8ScaleResCeil %u\n", i, p_cfg->asOutputConfig[i].ui8ScaleResCeil);
9085 }
9086 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8MaxExtraHwFrameCnt %u\n", p_cfg->ui8MaxExtraHwFrameCnt);
9087 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EcPolicy = %u\n", p_cfg->ui8EcPolicy);
9088 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnableAdvancedEc = %u\n", p_cfg->ui8EnableAdvancedEc);
9089 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnablelowDelayCheck = %u\n", p_cfg->ui8EnablelowDelayCheck);
9090 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8DisableAdaptiveBuffers = %u\n", p_cfg->ui8DisableAdaptiveBuffers);
9091 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32ErrRatioThreshold = %u\n", p_cfg->ui32ErrRatioThreshold);
9092 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8ReduceDpbDelay = %u\n", p_cfg->ui8ReduceDpbDelay);
9093
9094}
9095
9096
9097/*!******************************************************************************
9098 * \brief Setup all xcoder configurations with custom parameters (Rev. B)
9099 *
9100 * \param
9101 *
9102 * \return
9103 ******************************************************************************/
9105 ni_encoder_config_t *p_cfg,
9106 ni_xcoder_params_t *p_src)
9107{
9108 ni_t408_config_t* p_t408 = NULL;
9109 ni_encoder_cfg_params_t *p_enc = NULL;
9110 int i = 0;
9111
9112 if ((!p_ctx) || (!p_cfg) || (!p_src))
9113 {
9114 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
9115 __func__);
9116 return;
9117 }
9118 p_t408 = &(p_cfg->niParamT408);
9119 p_enc = &p_src->cfg_enc_params;
9120
9121 ni_set_default_template(p_ctx, p_cfg);
9122
9123 p_cfg->i32picWidth = p_src->source_width;
9124 p_cfg->i32picHeight = p_src->source_height;
9125 p_t408->tier = p_enc->high_tier;
9127 p_t408->cu_size_mode = p_enc->cu_size_mode;
9128 p_t408->max_num_merge = p_enc->max_num_merge;
9129 p_cfg->ui8AiEnhanceMode = p_src->enable_ai_enhance;
9131 // enhance_level is in range [1,3] set level when paramters is valid, otherwise make it to 1.
9132 if(p_cfg->ui8AiEnhanceMode && p_src->ai_enhance_level > 0 && p_src->ai_enhance_level < 4){
9133 p_cfg->ui8AiEnhanceLevel = p_src->ai_enhance_level;
9134 }else{
9135 p_cfg->ui8AiEnhanceLevel = 1;
9136 }
9138 p_cfg->i8skipFrameEnable = p_enc->skip_frame_enable;
9141 p_cfg->ui16iFrameSizeRatio = p_enc->iframe_size_ratio;
9142 p_cfg->ui8EnableAcqLimit = p_enc->enable_acq_limit;
9145 if (p_enc->crfFloat == (float)-1.0 && p_enc->enable_smooth_crf == 1)
9146 {
9147 //smooth crf only support when setting float crf
9148 p_enc->enable_smooth_crf = 0;
9149 }
9150 p_cfg->ui8enableSmoothCrf = p_enc->enable_smooth_crf;
9153 p_cfg->ui8adaptiveCrfMode = p_enc->adaptiveCrfMode;
9156 p_cfg->ui8cutreeFlushIframe = (p_src->minFramesDelay >> 2);
9157
9158 // enable_dynamic_8x8_merge, enable_dynamic_16x16_merge, enable_dynamic_32x32_merge,
9159 // trans_rate, enable_hvs_qp_scale:
9160 // are not present in Rev B p_config
9161
9162#if 0
9163 if ((p_enc->rc.enable_rate_control == 0) &&
9164 ((p_enc->rc.enable_mb_level_rc == 1) || (p_enc->rc.enable_cu_level_rate_control == 1)))
9165 {
9167 ni_log2(p_ctx, NI_LOG_DEBUG, "force enable_mb_level_rc & enable_cu_level_rate_control to 0 because rate control is disabled\n");
9168 }
9169#endif
9170
9171 ni_log2(p_ctx, NI_LOG_TRACE, "### %s: b preset_index %d bitrate %d rcEnable %d %d EnableRdoQuant %d lookAheadDepth %d gop_preset_index %d rdoLevel %d vbv_buffer_size %d crf %d %f\n", __func__,
9172 p_enc->preset_index, p_src->bitrate, p_cfg->ui8rcEnable, p_enc->rc.enable_rate_control, p_enc->EnableRdoQuant, p_enc->lookAheadDepth, p_enc->gop_preset_index, p_enc->rdoLevel,
9173 p_enc->rc.vbv_buffer_size, p_enc->crf, p_enc->crfFloat);
9174
9175 if (!p_enc->preset_enabled && p_enc->preset_index != NI_PRESETS_NONE) {
9176 p_enc->preset_enabled = 1;
9177 p_enc->reset_dts_offset = 1;
9178 p_enc->rc.enable_rate_control = 1;
9180 p_enc->EnableRdoQuant = (STD_AV1 == p_cfg->ui8bitstreamFormat) ? 0 : (p_enc->EnableRdoQuant != -1 ? p_enc->EnableRdoQuant : 1);
9181
9182 // Disable CRF if enabled
9183 if (p_enc->crf != -1 || p_enc->crfFloat != -1.0f) {
9184 p_enc->crf = -1;
9185 p_enc->crfFloat = -1.0f;
9186 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): CRF disabled due to preset enabled\n", __func__);
9187 }
9188
9189 // Ensure preset_index is valid to avoid out-of-bounds access
9190 if (p_enc->preset_index >= 0 && p_enc->preset_index < sizeof(preset_configs) / sizeof(preset_configs[0])) {
9191 const PresetConfig *cfg = &preset_configs[p_enc->preset_index];
9192
9193 p_enc->rdoLevel = cfg->rdoLevel;
9194 p_enc->lookAheadDepth = cfg->lookAheadDepth;
9196 p_enc->rc.vbv_buffer_size = (p_enc->rc.vbv_buffer_size != -1) ? p_enc->rc.vbv_buffer_size : cfg->vbvBufferSize;
9198
9199 // Only set tolCtbRcInter/Intra for veryfast, faster, fast presets
9200 if (p_enc->preset_index <= NI_VQ_FAST) {
9201 p_enc->tolCtbRcInter = (p_enc->tolCtbRcInter != 0.1f) ? p_enc->tolCtbRcInter : cfg->tolCtbRcInter;
9202 p_enc->tolCtbRcIntra = (p_enc->tolCtbRcIntra != 0.1f) ? p_enc->tolCtbRcIntra : cfg->tolCtbRcIntra;
9203 }
9204 }
9205
9206 // Adjust rdoLevel for AVC format
9207 if (STD_AVC == p_cfg->ui8bitstreamFormat) {
9208 p_enc->rdoLevel = 1;
9209 }
9210 }
9211
9212 if (p_enc->EnableRdoQuant == -1)
9213 {
9214 p_enc->EnableRdoQuant = 0;
9215 }
9216
9218 {
9220 }
9221
9222 if(p_ctx->last_bitrate != 0)
9223 {
9224 // Slow sequence change happened. Retain the last bitrate.
9225 ni_log2(p_ctx, NI_LOG_DEBUG, "### %s: Slow sequence happened retain last_bitrate %d. assigned bitrate %d\n",
9226 __FUNCTION__, p_ctx->last_bitrate, p_src->bitrate);
9227 p_src->bitrate = p_ctx->last_bitrate;
9228 }
9229
9230 if (p_src->bitrate != 0)
9231 {
9232 p_cfg->i32bitRate = p_src->bitrate;
9233 }
9234
9235 p_cfg->ui8rcEnable = p_enc->rc.enable_rate_control;
9236
9237 ni_log2(p_ctx, NI_LOG_TRACE, "### %s: a bitrate %d rcEnable %d %d EnableRdoQuant %d lookAheadDepth %d gop_preset_index %d rdoLevel %d vbv_buffer_size %d enable_cu_level_rate_control %d\n", __func__,
9238 p_src->bitrate, p_enc->EnableRdoQuant, p_cfg->ui8rcEnable, p_enc->rc.enable_rate_control, p_enc->lookAheadDepth, p_enc->gop_preset_index, p_enc->rdoLevel, p_enc->rc.vbv_buffer_size,
9240
9241 // Update the bitrate to be used after Slow sequence change
9242 p_ctx->last_bitrate = p_cfg->i32bitRate;
9243
9244 p_t408->gop_preset_index = p_enc->gop_preset_index;
9246 p_t408->enable_hvs_qp = p_enc->rc.enable_hvs_qp;
9247 p_t408->hvs_qp_scale = p_enc->rc.hvs_qp_scale;
9248 p_t408->minQpI = p_enc->rc.min_qp;
9249 p_t408->minQpP = p_enc->rc.min_qp;
9250 p_t408->minQpB = p_enc->rc.min_qp;
9251 p_t408->maxQpI = p_enc->rc.max_qp;
9252 p_t408->maxQpP = p_enc->rc.max_qp;
9253 p_t408->maxQpB = p_enc->rc.max_qp;
9254
9255 p_t408->max_delta_qp = p_enc->rc.max_delta_qp;
9256 if (p_enc->rc.vbv_buffer_size != -1)
9257 {
9258 p_cfg->i32vbvBufferSize = p_enc->rc.vbv_buffer_size;
9259 }
9260 else
9261 {
9262 if (p_enc->rc.enable_rate_control)
9263 p_cfg->i32vbvBufferSize = 3000; // enable CBR (default vbv buffer size 3000) even if user does not set vbvBufferSize
9264 else
9265 p_cfg->i32vbvBufferSize = 0; // if user sets CRF but not vbvBufferSize, do not eanble capped CRF
9266 }
9267 p_cfg->ui32vbvMaxRate = p_enc->rc.vbv_max_rate;
9268 p_cfg->i8intraQpDelta = p_enc->rc.intra_qp_delta;
9269 p_cfg->ui8fillerEnable = p_enc->rc.enable_filler;
9270 p_cfg->ui8picSkipEnable = p_enc->rc.enable_pic_skip;
9271 p_cfg->ui16maxFrameSize = p_enc->maxFrameSize / 2000;
9272 p_t408->intra_period = p_enc->intra_period;
9273 p_t408->roiEnable = p_enc->roi_enable;
9274 p_t408->useLongTerm = p_enc->long_term_ref_enable;
9275 if (QUADRA)
9276 {
9279 }
9280 p_t408->conf_win_top = p_enc->conf_win_top;
9281 p_t408->conf_win_bottom = p_enc->conf_win_bottom;
9282 p_t408->conf_win_left = p_enc->conf_win_left;
9283 p_t408->conf_win_right = p_enc->conf_win_right;
9284 p_t408->avcIdrPeriod = p_enc->intra_period;
9285
9286 if (QUADRA)
9287 {
9288 if(p_ctx->last_framerate.framerate_num != 0)
9289 {
9290 // Slow sequence change happened. Retain the last framerate.
9291 ni_log2(p_ctx, NI_LOG_DEBUG, "### %s: Slow sequence happened retain last_framerate num %d den %d. assigned num %d den %d\n",
9292 __FUNCTION__, p_ctx->last_framerate.framerate_num, p_ctx->last_framerate.framerate_denom,
9294 p_src->fps_number = p_ctx->last_framerate.framerate_num;
9296
9297 if (!p_src->enable_vfr) {
9298 p_enc->frame_rate = (int)(p_src->fps_number / p_src->fps_denominator);
9299 }
9300 }
9301
9302 if (p_cfg->i32frameRateInfo != p_enc->frame_rate)
9303 {
9304 if (p_src->fps_denominator != 0 &&
9305 (p_src->fps_number % p_src->fps_denominator) != 0)
9306 {
9307 // Fractional FPS
9308 uint32_t numUnitsInTick = 1000;
9309 if (p_src->fps_denominator == numUnitsInTick + 1)
9310 {
9311 p_cfg->i32frameRateDenominator = numUnitsInTick + 1;
9312 p_cfg->i32frameRateInfo = p_enc->frame_rate + 1;
9313 p_cfg->i32frameRateInfo *= numUnitsInTick;
9314 }
9315 else
9316 {
9317 p_cfg->i32frameRateDenominator = numUnitsInTick + 1;
9318 p_cfg->i32frameRateInfo = (int32_t)(((uint64_t)p_src->fps_number * (uint64_t)numUnitsInTick) / (uint64_t)p_src->fps_denominator);
9319 }
9320 }
9321 else if (p_src->fps_denominator != 0 && p_src->fps_number < p_src->fps_denominator)
9322 {
9323 // Fractional FPS < 1, set to 1
9324 p_cfg->i32frameRateInfo = 1;
9325 p_cfg->i32frameRateDenominator = 1;
9326 }
9327 else
9328 {
9329 // Integer FPS: use the frame_rate directly
9330 p_cfg->i32frameRateInfo = p_enc->frame_rate;
9331 p_cfg->i32frameRateDenominator = 1;
9332 }
9333 }
9334
9335 // Update the framerate to be used after Slow sequence change
9338 }
9339 else
9340 {
9341 if (p_cfg->i32frameRateInfo != p_enc->frame_rate)
9342 {
9343 p_cfg->i32frameRateInfo = p_enc->frame_rate;
9344 p_t408->numUnitsInTick = 1000;
9345 if (p_src->fps_denominator != 0 &&
9346 (p_src->fps_number % p_src->fps_denominator) != 0)
9347 {
9348 p_t408->numUnitsInTick += 1;
9349 p_cfg->i32frameRateInfo += 1;
9350 }
9351 p_t408->timeScale = p_cfg->i32frameRateInfo * 1000;
9352 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
9353 {
9354 p_t408->timeScale *= 2;
9355 }
9356 }
9357 }
9358
9359 p_t408->intra_qp = p_enc->rc.intra_qp;
9360
9361 // "repeatHeaders" value 1 (all I frames) maps to forcedHeaderEnable
9362 // value 2; all other values are ignored
9363 if (p_t408->forcedHeaderEnable != p_enc->forced_header_enable &&
9365 {
9366 p_t408->forcedHeaderEnable = 2;
9367 p_cfg->ui8repeatHeaders = p_enc->forced_header_enable;
9368 }
9369
9371
9372 if (STD_AVC == p_cfg->ui8bitstreamFormat)
9373 {
9374 switch (p_t408->decoding_refresh_type)
9375 {
9376 case 0: // Non-IRAP I-p_frame
9377 {
9378 // intra_period set to user-configured (above), avcIdrPeriod set to 0
9379 p_t408->avcIdrPeriod = 0;
9380 break;
9381 }
9382 case 1: // CRA
9383 case 2: // IDR
9384 {
9385 // intra_period set to 0, avcIdrPeriod set to user-configured (above)
9386 p_t408->intra_period = 0;
9387 break;
9388 }
9389 default:
9390 {
9391 ni_log(
9393 "ERROR: %s() unknown value for p_t408->decoding_refresh_type: %d\n",
9394 __func__, p_t408->decoding_refresh_type);
9395 break;
9396 }
9397 }
9398 } else if (STD_HEVC == p_cfg->ui8bitstreamFormat ||
9399 STD_AV1 == p_cfg->ui8bitstreamFormat)
9400 {
9401 p_t408->avcIdrPeriod = 0;
9402 }
9403
9404 // Rev. B: H.264 only parameters.
9407
9408 // Rev. B: shared between HEVC and H.264
9409 p_t408->slice_mode = p_enc->slice_mode;
9410 p_t408->slice_arg = p_enc->slice_arg;
9411 if (p_t408->intra_mb_refresh_mode != p_enc->intra_mb_refresh_mode)
9412 {
9414 if (1 != p_t408->intra_mb_refresh_mode)
9415 {
9416 p_t408->intra_mb_refresh_mode = 1;
9417 ni_log2(p_ctx, NI_LOG_DEBUG, "force intraRefreshMode to 1 because quadra only supports intra refresh by rows\n");
9418 }
9419 }
9420
9421 if (p_t408->intra_mb_refresh_arg != p_enc->intra_mb_refresh_arg)
9422 {
9424 if (1 == p_t408->intra_mb_refresh_mode)
9425 {
9426 int mbHeight = (p_cfg->ui8bitstreamFormat == STD_AVC) ? 16 : 64;
9427 int mbRows = (p_cfg->i32picHeight + mbHeight - 1) / mbHeight;
9428 p_cfg->ui16gdrDuration = (mbRows + p_t408->intra_mb_refresh_arg - 1) / p_t408->intra_mb_refresh_arg;
9429 }
9430 }
9431
9433
9434 // Rev. B: could be shared for HEVC and H.264
9435 p_t408->enable_mb_level_rc = p_enc->rc.enable_mb_level_rc;
9436
9437 // profile setting: if user specified profile
9438 if (0 != p_enc->profile)
9439 {
9440 p_t408->profile = p_enc->profile;
9441 }
9442
9443 p_t408->level = p_enc->level_idc;
9444
9445 // main, extended or baseline profile of 8 bit (if input is 10 bit, Quadra auto converts to 8 bit) H.264 requires the following:
9446 // main: profile = 2 transform8x8Enable = 0
9447 // extended: profile = 3 entropyCodingMode = 0, transform8x8Enable = 0
9448 // baseline: profile = 1 entropyCodingMode = 0, transform8x8Enable = 0 and
9449 // gop with no B frames (gopPresetIdx=1, 2, 6, or 0
9450 // (custom with no B frames)
9451 if (STD_AVC == p_cfg->ui8bitstreamFormat)
9452 {
9453 if (2 == p_t408->profile)
9454 {
9455 p_t408->enable_transform_8x8 = 0;
9456 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_transform_8x8 set to 0 for profile 2 (main)\n");
9457 }
9458 else if (3 == p_t408->profile || 1 == p_t408->profile)
9459 {
9460 p_t408->entropy_coding_mode = p_t408->enable_transform_8x8 = 0;
9461 ni_log2(p_ctx, NI_LOG_DEBUG, "entropy_coding_mode and enable_transform_8x8 set to 0 "
9462 "for profile 3 (extended) or 1 (baseline)\n");
9463 }
9464 }
9465
9466 if (QUADRA)
9467 {
9468 p_enc->profile = p_t408->profile; // record profile for Bitstream Features reporting
9469 if (0 == p_t408->entropy_coding_mode && 1 == p_enc->EnableRdoQuant)
9470 {
9471 ni_log2(p_ctx, NI_LOG_DEBUG, "RDOQ does not support entropy_coding_mode 0 (CAVLC) "
9472 "force EnableRdoQuant 0 to accommodate HW limiation\n");
9473 p_enc->EnableRdoQuant = 0;
9474 }
9475 }
9476
9477#ifndef QUADRA
9478 if (!QUADRA)
9479 {
9481 {
9483 for (i = 0; i < p_t408->custom_gop_params.custom_gop_size; i++)
9484 {
9487 p_t408->custom_gop_params.pic_param[i].pic_qp = p_enc->custom_gop_params.pic_param[i].pic_qp + p_t408->intra_qp;
9488 p_t408->custom_gop_params.pic_param[i].num_ref_pic_L0 = p_enc->custom_gop_params.pic_param[i].num_ref_pic_L0;
9489 p_t408->custom_gop_params.pic_param[i].ref_poc_L0 = p_enc->custom_gop_params.pic_param[i].ref_poc_L0;
9490 p_t408->custom_gop_params.pic_param[i].ref_poc_L1 = p_enc->custom_gop_params.pic_param[i].ref_poc_L1;
9492 }
9493 }
9494 }
9495 else // QUADRA
9496#endif
9497 {
9501 {
9504 for (i = 0; i < p_t408->custom_gop_params.custom_gop_size; i++)
9505 {
9518 for (int j = 0;
9519 j < p_enc->custom_gop_params.pic_param[i].num_ref_pics; j++)
9520 {
9521 p_t408->custom_gop_params.pic_param[i].rps[j].ref_pic =
9525 }
9526 }
9527 }
9528 }
9529
9530 p_ctx->key_frame_type = p_t408->decoding_refresh_type; //Store to use when force key p_frame
9531
9532 // forceFrameType=1 requires intraPeriod=0 and avcIdrPeriod=0 and gopPresetIdx=8
9533 if (1 == p_src->force_frame_type)
9534 {
9535 p_t408->intra_period = 0;
9536 p_t408->avcIdrPeriod = 0;
9537 p_t408->gop_preset_index = 8;
9538 p_ctx->force_frame_type = 1;
9539 }
9540
9541 p_cfg->hdrEnableVUI = p_src->hdrEnableVUI;
9542
9543 if (p_cfg->i32hwframes != p_src->hwframes)
9544 {
9545 if (p_src->hwframes && p_ctx->auto_dl_handle == 0)
9546 {
9547 p_cfg->i32hwframes = p_src->hwframes;
9548 }
9549 else
9550 {
9551 p_cfg->i32hwframes = 0;
9552 }
9553 }
9554 p_cfg->ui16rootBufId = p_src->rootBufId;
9555
9556 //set VUI info deprecated
9557 //p_cfg->ui32VuiDataSizeBits = p_src->ui32VuiDataSizeBits;
9558 //p_cfg->ui32VuiDataSizeBytes = p_src->ui32VuiDataSizeBytes;
9559 //memcpy(p_cfg->ui8VuiRbsp, p_src->ui8VuiRbsp, NI_MAX_VUI_SIZE);
9560 //if ((p_src->pos_num_units_in_tick > p_src->ui32VuiDataSizeBits) || (p_src->pos_time_scale > p_src->ui32VuiDataSizeBits))
9561 //{
9562 // ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() VUI filling error\n", __func__);
9563 // return;
9564 //}
9565 //else
9566 //{
9567 // ni_fix_VUI(p_cfg->ui8VuiRbsp, p_src->pos_num_units_in_tick, p_t408->numUnitsInTick);
9568 // ni_fix_VUI(p_cfg->ui8VuiRbsp, p_src->pos_time_scale, p_t408->timeScale);
9569 //}
9570
9571 if (p_src->enable_vfr)
9572 {
9573 p_cfg->ui8fixedframerate = 0;
9574 } else
9575 {
9576 p_cfg->ui8fixedframerate = 1;
9577 }
9578
9579 //new QUADRA param
9580 if (p_enc->EnableAUD != 0)
9581 {
9582 p_cfg->ui8EnableAUD = p_enc->EnableAUD;
9583 }
9584 if (p_enc->lookAheadDepth != 0)
9585 {
9586 p_cfg->ui8LookAheadDepth = p_enc->lookAheadDepth;
9587 }
9588 if (p_enc->rdoLevel != 1)
9589 {
9590 p_cfg->ui8rdoLevel = p_enc->rdoLevel;
9591 }
9592 if (p_enc->crf != -1)
9593 {
9594 p_cfg->i8crf = p_enc->crf;
9595 }
9596 if (p_enc->HDR10MaxLight != 0)
9597 {
9598 p_cfg->ui16HDR10MaxLight = p_enc->HDR10MaxLight;
9599 }
9600 if (p_enc->HDR10AveLight != 0)
9601 {
9602 p_cfg->ui16HDR10AveLight = p_enc->HDR10AveLight;
9603 }
9604 if (p_enc->HDR10CLLEnable != 0)
9605 {
9606 p_cfg->ui8HDR10CLLEnable = p_enc->HDR10CLLEnable;
9607 }
9608 if (p_enc->HDR10Enable != 0)
9609 {
9610 p_cfg->ui8hdr10_enable = p_enc->HDR10Enable;
9611 p_cfg->ui16hdr10_dx0 = p_enc->HDR10dx0;
9612 p_cfg->ui16hdr10_dy0 = p_enc->HDR10dy0;
9613 p_cfg->ui16hdr10_dx1 = p_enc->HDR10dx1;
9614 p_cfg->ui16hdr10_dy1 = p_enc->HDR10dy1;
9615 p_cfg->ui16hdr10_dx2 = p_enc->HDR10dx2;
9616 p_cfg->ui16hdr10_dy2 = p_enc->HDR10dy2;
9617 p_cfg->ui16hdr10_wx = p_enc->HDR10wx;
9618 p_cfg->ui16hdr10_wy = p_enc->HDR10wy;
9619 p_cfg->ui32hdr10_maxluma = p_enc->HDR10maxluma;
9620 p_cfg->ui32hdr10_minluma = p_enc->HDR10minluma;
9621 }
9622
9623 if (p_enc->EnableRdoQuant != 0)
9624 {
9625 p_cfg->ui8EnableRdoQuant = p_enc->EnableRdoQuant;
9626 }
9627 if (p_enc->ctbRcMode != 0)
9628 {
9629 p_cfg->ui8ctbRcMode = p_enc->ctbRcMode;
9630 }
9631 if (p_enc->gopSize != 0)
9632 {
9633 p_cfg->ui8gopSize = p_enc->gopSize;
9634 }
9635 if (p_src->use_low_delay_poc_type != 0)
9636 {
9638 }
9639 if (p_enc->gopLowdelay != 0)
9640 {
9641 p_cfg->ui8gopLowdelay = p_enc->gopLowdelay;
9642 }
9643 if (p_enc->gdrDuration != 0)
9644 {
9645 p_cfg->ui16gdrDuration = p_enc->gdrDuration;
9646 }
9647 if (p_enc->colorDescPresent)
9648 {
9649 p_cfg->ui8colorDescPresent = 1;
9650 p_cfg->ui8colorPrimaries = p_enc->colorPrimaries;
9651 p_cfg->ui8colorTrc = p_enc->colorTrc;
9652 p_cfg->ui8colorSpace = p_enc->colorSpace;
9653 p_cfg->ui8videoFullRange = p_enc->videoFullRange;
9654 }
9655 if (p_enc->videoFullRange)
9656 {
9657 p_cfg->ui8videoFullRange = p_enc->videoFullRange;
9658 }
9659 if (p_enc->hrdEnable != 0)
9660 {
9661 p_cfg->ui8hrdEnable = p_enc->hrdEnable;
9662 }
9663
9664 p_cfg->ui8planarFormat = p_src->cfg_enc_params.planar;
9665 p_cfg->ui16aspectRatioWidth = p_enc->aspectRatioWidth;
9667
9668 if (p_enc->ltrRefInterval != 0)
9669 {
9670 p_cfg->ui32ltrRefInterval = p_enc->ltrRefInterval;
9671 p_cfg->i32ltrRefQpOffset = p_enc->ltrRefQpOffset;
9672 p_cfg->ui32ltrFirstGap = p_enc->ltrFirstGap;
9673 p_cfg->ui32ltrNextInterval = p_enc->ltrNextInterval;
9674 }
9675 if (p_enc->multicoreJointMode != 0)
9676 {
9678 }
9679 p_cfg->ui32QLevel = p_enc->qlevel;
9680
9681 if (p_enc->chromaQpOffset != 0)
9682 {
9683 p_cfg->i8chromaQpOffset = p_enc->chromaQpOffset;
9684 }
9685
9686 if (p_enc->tolCtbRcInter != (float)0.1)
9687 {
9688 p_cfg->i32tolCtbRcInter = (int32_t)(p_enc->tolCtbRcInter * 1000);
9689 }
9690
9691 if (p_enc->tolCtbRcIntra != (float)0.1)
9692 {
9693 p_cfg->i32tolCtbRcIntra = (int32_t)(p_enc->tolCtbRcIntra * 1000);
9694 }
9695
9696 if (p_enc->bitrateWindow != -255)
9697 {
9698 p_cfg->i16bitrateWindow = p_enc->bitrateWindow;
9699 }
9700
9701 if (p_enc->inLoopDSRatio != 1)
9702 {
9703 p_cfg->ui8inLoopDSRatio = p_enc->inLoopDSRatio;
9704 }
9705
9706 if (p_enc->blockRCSize != 0)
9707 {
9708 p_cfg->ui8blockRCSize = p_enc->blockRCSize;
9709 }
9710
9711 if (p_enc->rcQpDeltaRange != 10)
9712 {
9713 p_cfg->ui8rcQpDeltaRange = p_enc->rcQpDeltaRange;
9714 }
9715
9716 if (p_enc->ctbRowQpStep != 0)
9717 {
9718 p_cfg->i16ctbRowQpStep = p_enc->ctbRowQpStep;
9719 }
9720
9721 if (p_enc->newRcEnable != -1)
9722 {
9723 p_cfg->ui8NewRCEnable = p_enc->newRcEnable;
9724 }
9725
9726 // convert enable_mb_level_rc, enable_cu_level_rate_control, and enable_hvs_qp to ctbRcMode
9727 if (QUADRA)
9728 {
9729 // ctbRcMode has priority over enable_mb_level_rc, enable_cu_level_rate_control, and enable_hvs_qp
9730 if (!p_cfg->ui8ctbRcMode)
9731 {
9732 if (p_t408->enable_mb_level_rc || p_t408->enable_cu_level_rate_control)
9733 {
9734 if (p_t408->enable_hvs_qp)
9735 {
9736 p_cfg->ui8ctbRcMode = 3;
9737 // If hvsQP is enabled, disable strongIntraSmooth to apply one filtering at a time for better VQ.
9738 p_t408->strongIntraSmoothEnable = 0;
9740 "Turning off strongIntraSmoothing because hvsQPEnable=1 "
9741 "for better subjective VQ\n");
9742 } else
9743 {
9744 p_cfg->ui8ctbRcMode = 2;
9745 }
9746 }
9747 else if (p_t408->enable_hvs_qp)
9748 {
9749 p_cfg->ui8ctbRcMode = 1;
9750 // If hvsQP is enabled, disable strongIntraSmooth to apply one filtering at a time for better VQ.
9751 p_t408->strongIntraSmoothEnable = 0;
9753 "Turning off strongIntraSmoothing because hvsQPEnable=1 for "
9754 "better subjective VQ\n");
9755 }
9756 }
9757 }
9758
9759 if (p_src->low_delay_mode != 0)
9760 {
9761 p_cfg->ui8LowDelay = !!(p_src->low_delay_mode);
9762 }
9763
9764 if (p_enc->enable_ssim != 0)
9765 {
9766 p_cfg->ui8enableSSIM = p_enc->enable_ssim;
9767 }
9768
9769 if (p_enc->avcc_hvcc != 0)
9770 {
9771 p_cfg->ui8avccHvcc = p_enc->avcc_hvcc;
9772 }
9773
9774 if (p_enc->av1_error_resilient_mode != 0)
9775 {
9777 }
9778
9779 if (p_enc->temporal_layers_enable != 0)
9780 {
9782 }
9783
9784 if (p_enc->spatial_layers > 1)
9785 {
9786 p_cfg->ui8spatialLayersMinusOne = p_enc->spatial_layers - 1;
9787 if (ni_cmp_fw_api_ver((char *)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rw") < 0) {
9788 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): spatialLayers is not supported for FW < 6rw\n", __func__);
9789 }
9790 }
9791
9792 if (p_enc->spatial_layers_ref_base_layer != 0)
9793 {
9795 if (ni_cmp_fw_api_ver((char *)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6s0") < 0) {
9796 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): spatialLayers is not supported for FW < 6s0\n", __func__);
9797 }
9798 }
9799
9800 if (p_ctx->pixel_format != NI_PIX_FMT_YUV420P)
9801 {
9802 p_cfg->ui8PixelFormat = p_ctx->pixel_format;
9803 }
9804
9805 if (p_enc->get_psnr_mode != 3)
9806 {
9807 if (p_enc->get_psnr_mode == 2 && p_ctx->codec_format == NI_CODEC_FORMAT_H265)
9808 {
9809 // h.265 psnr_y is supported by HW for 8-bit & 10-bit, no need to reject setting or disable luma RFC
9812 {
9813 p_enc->get_psnr_mode = 3;
9814 ni_log(NI_LOG_INFO, "Warning h.265 psnr_y is only supported for YUV420P, YUV420P10LE, NV12, and P010LE\n");
9815 }
9816 }
9817 else if (p_enc->get_psnr_mode == 4)
9818 {
9819 p_cfg->ui8compressor = 0;
9821 {
9822 p_enc->get_psnr_mode = 3;
9823 p_cfg->ui8compressor = 3;
9824 ni_log(NI_LOG_INFO, "Warning reconstructed frames only supported for YUV420P, NV12\n");
9825 }
9826 if (p_enc->crop_width || p_enc->crop_height)
9827 {
9828 p_cfg->ui8compressor = 3;
9829 p_enc->get_psnr_mode = 3;
9830 ni_log(NI_LOG_INFO, "Warning reconstructed frames feature is not supported when cropWidth x cropHeight are set\n");
9831 }
9832 }
9833 else
9834 {
9835 p_cfg->ui8compressor = p_enc->get_psnr_mode;
9836 if (p_cfg->ui8PixelFormat != NI_PIX_FMT_YUV420P)
9837 {
9838 p_cfg->ui8compressor = 3;
9839 p_enc->get_psnr_mode = 3;
9840 ni_log(NI_LOG_INFO, "Warning get psnr feature only support YUV420P (except for h.265 psnr_y)\n");
9841 }
9842 if (p_enc->crop_width || p_enc->crop_height)
9843 {
9844 p_cfg->ui8compressor = 3;
9845 p_enc->get_psnr_mode = 3;
9846 ni_log(NI_LOG_INFO, "Warning get psnr feature is not supported when cropWidth x cropHeight are set\n");
9847 }
9848 }
9849 }
9850
9851 if (p_src->zerocopy_mode == -1) // zero copy auto mode - disable zero copy for low resolution
9852 {
9853 bool is_rgba = (p_ctx->pixel_format == NI_PIX_FMT_RGBA ||
9854 p_ctx->pixel_format == NI_PIX_FMT_BGRA ||
9855 p_ctx->pixel_format == NI_PIX_FMT_ARGB ||
9856 p_ctx->pixel_format == NI_PIX_FMT_ABGR) ? true : false;
9857 if (is_rgba ||
9859 "6Q") >= 0) &&
9861 p_src->zerocopy_mode = 1;
9862 else
9863 p_src->zerocopy_mode = 0;
9864 }
9865
9866 if (p_src->zerocopy_mode)
9867 {
9868 p_cfg->ui32lumaLinesize = p_src->luma_linesize;
9869 p_cfg->ui32chromaLinesize = p_src->chroma_linesize;
9870 }
9871 else
9872 {
9873 p_cfg->ui32lumaLinesize = p_src->luma_linesize = 0;
9874 p_cfg->ui32chromaLinesize = p_src->chroma_linesize = 0;
9875 }
9876 // for fast sequence change linesize check
9877 p_ctx->ori_luma_linesize = p_src->luma_linesize;
9878 p_ctx->ori_chroma_linesize = p_src->chroma_linesize;
9879
9880 // calculate number for frames delay for minFramesDelay
9881 int lookAheadEnable = !!p_cfg->ui8LookAheadDepth;
9882
9883 int gopSize = g_map_preset_to_gopsize[lookAheadEnable][p_t408->gop_preset_index + 1];
9884 int mulitcoreDelay = p_cfg->ui8multicoreJointMode ? 3 : 0;
9885
9886 if (p_t408->gop_preset_index == 0) // Custom GOP
9887 gopSize = p_t408->custom_gop_params.custom_gop_size;
9888
9889 if (lookAheadEnable)
9890 {
9891 int firstGopEnd = gopSize + 1 + mulitcoreDelay; // first I-frame gopSize is 1
9892 int lookaheadGopEnd = mulitcoreDelay ?
9893 p_cfg->ui8LookAheadDepth + mulitcoreDelay + (gopSize - ((p_cfg->ui8LookAheadDepth-1+mulitcoreDelay) % gopSize)) :
9894 p_cfg->ui8LookAheadDepth + (gopSize - ((p_cfg->ui8LookAheadDepth-1) % gopSize)); // lookAheadDepth-1 because lookahead queue includes first I-frame
9895 int initialDelayNum = (firstGopEnd > lookaheadGopEnd) ? firstGopEnd : lookaheadGopEnd;
9896 int maxDelayNum = p_cfg->ui8LookAheadDepth + 1 + gopSize / 2 + mulitcoreDelay;
9897 int maxLookaheadQueue = initialDelayNum + (gopSize - 1) + mulitcoreDelay; // assume worst case scenario - gop size changes from initial gop to gop size 1
9898
9899 p_ctx->initial_frame_delay = initialDelayNum + (mulitcoreDelay ? 4 : 0); // for multicore pass-2, need to add 4 more frames before pass-2 could output frame
9900 p_ctx->max_frame_delay = ((maxDelayNum > maxLookaheadQueue) ? maxDelayNum : maxLookaheadQueue) + (mulitcoreDelay ? 4 : 0); // for multicore pass-2, need to add 4 more frames before pass-2 could output frame
9902 "6r2") >= 0)
9903 {
9904 p_ctx->last_gop_size = gopSize; // for adaptive gop, gop size change can happen in pass-1, causing the first non-IDR output to carrry gop size 4 insetad of 8 and increase lookahead queue
9906 "6rX") >= 0)
9907 {
9908 if (p_t408->gop_preset_index == GOP_PRESET_IDX_DEFAULT || mulitcoreDelay) // for adaptive gop or multicore, just set max frame delay to workaround encoding stuck
9909 p_ctx->current_frame_delay = p_ctx->max_frame_delay;
9910 else
9912 }
9913 else
9914 {
9915 p_ctx->current_frame_delay = p_ctx->max_frame_delay;
9916 }
9917 }
9918 else
9919 {
9920 p_ctx->last_gop_size = gopSize;
9921 p_ctx->current_frame_delay = p_ctx->max_frame_delay;
9922 }
9923 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: firstGopEnd %d lookaheadGopEnd %d initialDelayNum %d maxDelayNum %d maxLookaheadQueue %d\n",
9924 __FUNCTION__, firstGopEnd, lookaheadGopEnd, initialDelayNum, maxDelayNum, maxLookaheadQueue);
9925 }
9926 else
9927 {
9928 p_ctx->last_gop_size = gopSize;
9929 p_ctx->initial_frame_delay = p_ctx->max_frame_delay = p_ctx->current_frame_delay = gopSize + mulitcoreDelay;
9930 }
9931
9932 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: preset %d lookAheadDepth %d gopSize %d mulitcoreDelay %d "
9933 "last_gop_size %d linitial_frame_delay %d current_frame_delay %d max_frame_delay %d\n",
9934 __FUNCTION__, p_t408->gop_preset_index, p_cfg->ui8LookAheadDepth, gopSize, mulitcoreDelay,
9936
9937 if (p_enc->crop_width != 0 && p_enc->crop_height != 0)
9938 {
9939 p_cfg->ui32cropWidth = p_enc->crop_width;
9940 p_cfg->ui32cropHeight = p_enc->crop_height;
9941 p_cfg->ui32horOffset = p_enc->hor_offset;
9942 p_cfg->ui32verOffset = p_enc->ver_offset;
9943 }
9944
9945 if (p_enc->crfMax != -1)
9946 {
9947 p_cfg->i8crfMax = (int8_t)(p_enc->crfMax) + 1; // for old libxcoder backward compatibility, use 1 to represent 0
9948 }
9949
9950 if (p_enc->qcomp != (float)0.6)
9951 {
9952 p_cfg->i32qcomp = (int32_t)(p_enc->qcomp * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
9953 }
9954
9955 if (p_enc->noMbtree != 0)
9956 {
9957 p_cfg->ui8noMbtree = p_enc->noMbtree;
9958 }
9959
9960 if (p_enc->noHWMultiPassSupport != 0)
9961 {
9963 }
9964
9965 if (p_enc->cuTreeFactor != 5)
9966 {
9967 p_cfg->i8cuTreeFactor = p_enc->cuTreeFactor;
9968 }
9969
9970 if (p_enc->ipRatio != (float)1.4)
9971 {
9972 p_cfg->i32ipRatio = (int32_t)(p_enc->ipRatio * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
9973 }
9974
9975 if (p_enc->pbRatio != (float)1.3)
9976 {
9977 p_cfg->i32pbRatio = (int32_t)(p_enc->pbRatio * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
9978 }
9979
9980 if (p_enc->cplxDecay != (float)0.5)
9981 {
9982 p_cfg->i32cplxDecay = (int32_t)(p_enc->cplxDecay * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
9983 }
9984
9985 if (p_enc->pps_init_qp != -1)
9986 {
9987 p_cfg->i8ppsInitQp = (int8_t)(p_enc->pps_init_qp) + 1; // for old libxcoder backward compatibility, use 1 to represent 0
9988 }
9989
9990 if (p_enc->bitrateMode != -1)
9991 {
9992 p_cfg->ui8bitrateMode = p_enc->bitrateMode;
9993 }
9994
9995 if (p_enc->pass1_qp != -1)
9996 {
9997 p_cfg->i8pass1Qp = (int8_t)(p_enc->pass1_qp) + 1; // for old libxcoder backward compatibility, use 1 to represent 0
9998 }
9999
10000 if (p_enc->crfFloat != (float)-1.0)
10001 {
10002 // for old libxcoder backward compatibility
10003 p_cfg->i8crf = (int8_t)(p_enc->crfFloat);
10004 p_cfg->i8crfDecimal = (int8_t)((p_enc->crfFloat - (float)p_cfg->i8crf) * 100);
10005 }
10006
10007 if (p_enc->hvsBaseMbComplexity != 15)
10008 {
10009 p_cfg->i8hvsBaseMbComplexity = (int8_t)p_enc->hvsBaseMbComplexity - 15; // for old libxcoder backward compatibility, use -15 to represent 0
10010 }
10011
10012 if (p_enc->enableipRatio != 0 && p_cfg->i32vbvBufferSize != 0) //vbvBufferSize !=0 for CBR not for ABR
10013 {
10014 p_cfg->i8enableipRatio = p_enc->enableipRatio;
10015 }
10016
10017 if (p_enc->crf_max_iframe_enable != 0)
10018 {
10020 }
10021
10022 if (p_enc->vbv_min_rate != 0)
10023 {
10024 p_cfg->ui32vbvMinRate = p_enc->vbv_min_rate;
10025 }
10026
10027 if (p_enc->disableBframeRdoq != 0)
10028 {
10030 }
10031
10032 if (p_enc->forceBframeQpfactor != (float)-1.0)
10033 {
10034 p_cfg->i32forceBframeQpFactor = (int32_t)(p_enc->forceBframeQpfactor * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10035 }
10036
10037 if (p_enc->tune_bframe_visual != 0)
10038 {
10040 }
10041
10044 }
10045
10046 if (p_enc->motionConstrainedMode != 0)
10047 {
10049 }
10050
10051 if(p_enc->encMallocStrategy != 0)
10052 {
10053 p_cfg->ui8mallocStrategy = p_enc->encMallocStrategy;
10054 }
10055
10056 if (p_enc->enable_timecode != 0)
10057 {
10058 p_cfg->ui8enableTimecode = p_enc->enable_timecode;
10059 }
10060
10061 if (p_enc->vbvBufferReencode != 0)
10062 {
10064 }
10065
10066 if (p_enc->totalCuTreeDepth != 0)
10067 {
10068 p_cfg->ui8totalCuTreeDepth = p_enc->totalCuTreeDepth;
10069 }
10070
10071 if (p_enc->adaptiveCuTree != 0)
10072 {
10073 p_cfg->ui8adaptiveCuTree = p_enc->adaptiveCuTree;
10074 }
10075
10076 if (p_enc->preIntraHandling != 1)
10077 {
10078 p_cfg->ui8preIntraHandling = (uint8_t)p_enc->preIntraHandling - 1; // for old libxcoder backward compatibility, use -1 to represent 0
10079 }
10080
10081 if (p_enc->baseLayerOnly != 0)
10082 {
10083 p_cfg->ui8baseLayerOnly = p_enc->baseLayerOnly;
10084 }
10085
10086 if (p_enc->pastFrameMaxIntraRatio != 20)
10087 {
10088 p_cfg->ui8pastFrameMaxIntraRatio = (uint8_t)p_enc->pastFrameMaxIntraRatio - 20; // for old libxcoder backward compatibility, use -20 to represent 0
10089 }
10090
10091 if (p_enc->linkFrameMaxIntraRatio != 40)
10092 {
10093 p_cfg->ui8linkFrameMaxIntraRatio = (uint8_t)p_enc->linkFrameMaxIntraRatio - 40; // for old libxcoder backward compatibility, use -40 to represent 0
10094 }
10095
10096 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
10097 {
10098 if (p_enc->spatialLayerBitrate[i] != 0)
10099 {
10100 p_cfg->i32spatialLayerBitrate[i] = p_enc->spatialLayerBitrate[i];
10101 }
10102 if (p_enc->av1OpLevel[i] != 0)
10103 {
10104 p_cfg->ui8av1OpLevel[i] = p_enc->av1OpLevel[i];
10105 }
10106 }
10107
10108 if (p_enc->disableAv1TimingInfo != 0)
10109 {
10111 }
10112
10113 if (p_enc->qpScaleEnable != 0)
10114 {
10115 p_cfg->ui8qpScaleEnable = p_enc->qpScaleEnable;
10116 }
10117
10118 if (p_enc->getBitstreamFeatures != 0)
10119 {
10120 p_cfg->ui8getCuInfo = 1;
10121 }
10122
10123 ni_log2(p_ctx, NI_LOG_DEBUG, "lowDelay=%d\n", p_src->low_delay_mode);
10124 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8bitstreamFormat=%d\n", p_cfg->ui8bitstreamFormat);
10125 ni_log2(p_ctx, NI_LOG_DEBUG, "i32picWidth=%d\n", p_cfg->i32picWidth);
10126 ni_log2(p_ctx, NI_LOG_DEBUG, "i32picHeight=%d\n", p_cfg->i32picHeight);
10127 ni_log2(p_ctx, NI_LOG_DEBUG, "i32meBlkMode=%d\n", p_cfg->i32meBlkMode);
10128 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8sliceMode=%d\n", p_cfg->ui8sliceMode);
10129 ni_log2(p_ctx, NI_LOG_DEBUG, "i32frameRateInfo=%d\n", p_cfg->i32frameRateInfo);
10130 ni_log2(p_ctx, NI_LOG_DEBUG, "i32vbvBufferSize=%d\n", p_cfg->i32vbvBufferSize);
10131 ni_log2(p_ctx, NI_LOG_DEBUG, "i32userQpMax=%d\n", p_cfg->i32userQpMax);
10132 ni_log2(p_ctx, NI_LOG_DEBUG, "enableSSIM=%d\n", p_cfg->ui8enableSSIM);
10133 // AVC only
10134 ni_log2(p_ctx, NI_LOG_DEBUG, "i32maxIntraSize=%d\n", p_cfg->i32maxIntraSize);
10135 ni_log2(p_ctx, NI_LOG_DEBUG, "i32userMaxDeltaQp=%d\n", p_cfg->i32userMaxDeltaQp);
10136 ni_log2(p_ctx, NI_LOG_DEBUG, "i32userMinDeltaQp=%d\n", p_cfg->i32userMinDeltaQp);
10137 ni_log2(p_ctx, NI_LOG_DEBUG, "i32userQpMin=%d\n", p_cfg->i32userQpMin);
10138 ni_log2(p_ctx, NI_LOG_DEBUG, "i32bitRate=%d\n", p_cfg->i32bitRate);
10139 ni_log2(p_ctx, NI_LOG_DEBUG, "i32bitRateBL=%d\n", p_cfg->i32bitRateBL);
10140 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8rcEnable=%d\n", p_cfg->ui8rcEnable);
10141 ni_log2(p_ctx, NI_LOG_DEBUG, "i32srcBitDepth=%d\n", p_cfg->i32srcBitDepth);
10142 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8enablePTS=%d\n", p_cfg->ui8enablePTS);
10143 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8lowLatencyMode=%d\n", p_cfg->ui8lowLatencyMode);
10144 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32sourceEndian=%u\n", p_cfg->ui32sourceEndian);
10145 ni_log2(p_ctx, NI_LOG_DEBUG, "hdrEnableVUI=%u\n", p_cfg->hdrEnableVUI);
10146 ni_log2(p_ctx, NI_LOG_DEBUG, "i32hwframes=%i\n", p_cfg->i32hwframes);
10147
10148 ni_log2(p_ctx, NI_LOG_DEBUG, "** ni_t408_config_t: \n");
10149 ni_log2(p_ctx, NI_LOG_DEBUG, "profile=%d\n", p_t408->profile);
10150 ni_log2(p_ctx, NI_LOG_DEBUG, "level=%d\n", p_t408->level);
10151 ni_log2(p_ctx, NI_LOG_DEBUG, "tier=%d\n", p_t408->tier);
10152
10153 ni_log2(p_ctx, NI_LOG_DEBUG, "internalBitDepth=%d\n", p_t408->internalBitDepth);
10154 ni_log2(p_ctx, NI_LOG_DEBUG, "losslessEnable=%d\n", p_t408->losslessEnable);
10155 ni_log2(p_ctx, NI_LOG_DEBUG, "constIntraPredFlag=%d\n", p_t408->constIntraPredFlag);
10156
10157 ni_log2(p_ctx, NI_LOG_DEBUG, "decoding_refresh_type=%d\n", p_t408->decoding_refresh_type);
10158 ni_log2(p_ctx, NI_LOG_DEBUG, "intra_qp=%d\n", p_t408->intra_qp);
10159 ni_log2(p_ctx, NI_LOG_DEBUG, "intra_period=%d\n", p_t408->intra_period);
10160 ni_log2(p_ctx, NI_LOG_DEBUG, "roi_enable=%d\n", p_t408->roiEnable);
10161
10162 ni_log2(p_ctx, NI_LOG_DEBUG, "useLongTerm=%u\n", p_t408->useLongTerm);
10163 ni_log2(p_ctx, NI_LOG_DEBUG, "setLongTermInterval=%u\n", p_cfg->ui32setLongTermInterval);
10164 ni_log2(p_ctx, NI_LOG_DEBUG, "setLongTermCount=%u\n", p_cfg->ui8setLongTermCount);
10165
10166 ni_log2(p_ctx, NI_LOG_DEBUG, "conf_win_top=%d\n", p_t408->conf_win_top);
10167 ni_log2(p_ctx, NI_LOG_DEBUG, "conf_win_bottom=%d\n", p_t408->conf_win_bottom);
10168 ni_log2(p_ctx, NI_LOG_DEBUG, "conf_win_left=%d\n", p_t408->conf_win_left);
10169 ni_log2(p_ctx, NI_LOG_DEBUG, "conf_win_right=%d\n", p_t408->conf_win_right);
10170
10171 ni_log2(p_ctx, NI_LOG_DEBUG, "independSliceMode=%d\n", p_t408->independSliceMode);
10172 ni_log2(p_ctx, NI_LOG_DEBUG, "independSliceModeArg=%d\n", p_t408->independSliceModeArg);
10173
10174 ni_log2(p_ctx, NI_LOG_DEBUG, "dependSliceMode=%d\n", p_t408->dependSliceMode);
10175 ni_log2(p_ctx, NI_LOG_DEBUG, "dependSliceModeArg=%d\n", p_t408->dependSliceModeArg);
10176
10177 ni_log2(p_ctx, NI_LOG_DEBUG, "intraRefreshMode=%d\n", p_t408->intraRefreshMode);
10178
10179 ni_log2(p_ctx, NI_LOG_DEBUG, "intraRefreshArg=%d\n", p_t408->intraRefreshArg);
10180
10181 ni_log2(p_ctx, NI_LOG_DEBUG, "use_recommend_enc_params=%d\n", p_t408->use_recommend_enc_params);
10182 ni_log2(p_ctx, NI_LOG_DEBUG, "scalingListEnable=%d\n", p_t408->scalingListEnable);
10183
10184 ni_log2(p_ctx, NI_LOG_DEBUG, "cu_size_mode=%d\n", p_t408->cu_size_mode);
10185 ni_log2(p_ctx, NI_LOG_DEBUG, "tmvpEnable=%d\n", p_t408->tmvpEnable);
10186 ni_log2(p_ctx, NI_LOG_DEBUG, "wppEnable=%d\n", p_t408->wppEnable);
10187 ni_log2(p_ctx, NI_LOG_DEBUG, "max_num_merge=%d\n", p_t408->max_num_merge);
10188 ni_log2(p_ctx, NI_LOG_DEBUG, "disableDeblk=%d\n", p_t408->disableDeblk);
10189 ni_log2(p_ctx, NI_LOG_DEBUG, "lfCrossSliceBoundaryEnable=%d\n", p_t408->lfCrossSliceBoundaryEnable);
10190 ni_log2(p_ctx, NI_LOG_DEBUG, "betaOffsetDiv2=%d\n", p_t408->betaOffsetDiv2);
10191 ni_log2(p_ctx, NI_LOG_DEBUG, "tcOffsetDiv2=%d\n", p_t408->tcOffsetDiv2);
10192 ni_log2(p_ctx, NI_LOG_DEBUG, "skipIntraTrans=%d\n", p_t408->skipIntraTrans);
10193 ni_log2(p_ctx, NI_LOG_DEBUG, "saoEnable=%d\n", p_t408->saoEnable);
10194 ni_log2(p_ctx, NI_LOG_DEBUG, "intraNxNEnable=%d\n", p_t408->intraNxNEnable);
10195 ni_log2(p_ctx, NI_LOG_DEBUG, "bitAllocMode=%d\n", p_t408->bitAllocMode);
10196
10197 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_cu_level_rate_control=%d\n", p_t408->enable_cu_level_rate_control);
10198
10199 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_hvs_qp=%d\n", p_t408->enable_hvs_qp);
10200
10201 ni_log2(p_ctx, NI_LOG_DEBUG, "hvs_qp_scale=%d\n", p_t408->hvs_qp_scale);
10202
10203 ni_log2(p_ctx, NI_LOG_DEBUG, "max_delta_qp=%d\n", p_t408->max_delta_qp);
10204
10205 // CUSTOM_GOP
10206 ni_log2(p_ctx, NI_LOG_DEBUG, "gop_preset_index=%d\n", p_t408->gop_preset_index);
10207#ifndef QUADRA
10208 if (!QUADRA)
10209 {
10211 {
10212 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.custom_gop_size=%d\n", p_t408->custom_gop_params.custom_gop_size);
10213 for (i = 0; i < 8; i++)
10214 //for (i = 0; i < p_t408->custom_gop_params.custom_gop_size; i++)
10215 {
10216 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].pic_type=%d\n", i, p_t408->custom_gop_params.pic_param[i].pic_type);
10217 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].poc_offset=%d\n", i, p_t408->custom_gop_params.pic_param[i].poc_offset);
10218 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].pic_qp=%d\n", i, p_t408->custom_gop_params.pic_param[i].pic_qp);
10219 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].num_ref_pic_L0=%d\n", i, p_t408->custom_gop_params.pic_param[i].num_ref_pic_L0);
10220 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].ref_poc_L0=%d\n", i, p_t408->custom_gop_params.pic_param[i].ref_poc_L0);
10221 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].ref_poc_L1=%d\n", i, p_t408->custom_gop_params.pic_param[i].ref_poc_L1);
10222 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].temporal_id=%d\n", i, p_t408->custom_gop_params.pic_param[i].temporal_id);
10223 }
10224 }
10225 }
10226 else // QUADRA
10227#endif
10228 {
10230 {
10231 int j;
10232 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.custom_gop_size=%d\n", p_t408->custom_gop_params.custom_gop_size);
10233 for (i = 0; i < NI_MAX_GOP_NUM; i++)
10234 {
10235 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].poc_offset=%d\n", i, p_t408->custom_gop_params.pic_param[i].poc_offset);
10236 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].qp_offset=%d\n", i, p_t408->custom_gop_params.pic_param[i].qp_offset);
10237 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].qp_factor=%f\n", i, p_t408->custom_gop_params.pic_param[i].qp_factor);
10238 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].temporal_id=%d\n", i, p_t408->custom_gop_params.pic_param[i].temporal_id);
10239 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].pic_type=%d\n", i, p_t408->custom_gop_params.pic_param[i].pic_type);
10240 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].num_ref_pics=%d\n", i, p_t408->custom_gop_params.pic_param[i].num_ref_pics);
10241 for (j = 0; j < NI_MAX_REF_PIC; j++)
10242 {
10243 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].rps[%d].ref_pic=%d\n", i, j, p_t408->custom_gop_params.pic_param[i].rps[j].ref_pic);
10244 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].rps[%d].ref_pic_used=%d\n", i, j, p_t408->custom_gop_params.pic_param[i].rps[j].ref_pic_used);
10245 }
10246 }
10247 }
10248 }
10249
10250 ni_log2(p_ctx, NI_LOG_DEBUG, "roiEnable=%d\n", p_t408->roiEnable);
10251
10252 ni_log2(p_ctx, NI_LOG_DEBUG, "numUnitsInTick=%u\n", p_t408->numUnitsInTick);
10253 ni_log2(p_ctx, NI_LOG_DEBUG, "timeScale=%u\n", p_t408->timeScale);
10254 ni_log2(p_ctx, NI_LOG_DEBUG, "numTicksPocDiffOne=%u\n", p_t408->numTicksPocDiffOne);
10255
10256 ni_log2(p_ctx, NI_LOG_DEBUG, "chromaCbQpOffset=%d\n", p_t408->chromaCbQpOffset);
10257 ni_log2(p_ctx, NI_LOG_DEBUG, "chromaCrQpOffset=%d\n", p_t408->chromaCrQpOffset);
10258
10259 ni_log2(p_ctx, NI_LOG_DEBUG, "initialRcQp=%d\n", p_t408->initialRcQp);
10260
10261 ni_log2(p_ctx, NI_LOG_DEBUG, "nrYEnable=%u\n", p_t408->nrYEnable);
10262 ni_log2(p_ctx, NI_LOG_DEBUG, "nrCbEnable=%u\n", p_t408->nrCbEnable);
10263 ni_log2(p_ctx, NI_LOG_DEBUG, "nrCrEnable=%u\n", p_t408->nrCrEnable);
10264
10265 // ENC_NR_WEIGHT
10266 ni_log2(p_ctx, NI_LOG_DEBUG, "nrIntraWeightY=%u\n", p_t408->nrIntraWeightY);
10267 ni_log2(p_ctx, NI_LOG_DEBUG, "nrIntraWeightCb=%u\n", p_t408->nrIntraWeightCb);
10268 ni_log2(p_ctx, NI_LOG_DEBUG, "nrIntraWeightCr=%u\n", p_t408->nrIntraWeightCr);
10269 ni_log2(p_ctx, NI_LOG_DEBUG, "nrInterWeightY=%u\n", p_t408->nrInterWeightY);
10270 ni_log2(p_ctx, NI_LOG_DEBUG, "nrInterWeightCb=%u\n", p_t408->nrInterWeightCb);
10271 ni_log2(p_ctx, NI_LOG_DEBUG, "nrInterWeightCr=%u\n", p_t408->nrInterWeightCr);
10272
10273 ni_log2(p_ctx, NI_LOG_DEBUG, "nrNoiseEstEnable=%u\n", p_t408->nrNoiseEstEnable);
10274 ni_log2(p_ctx, NI_LOG_DEBUG, "nrNoiseSigmaY=%u\n", p_t408->nrNoiseSigmaY);
10275 ni_log2(p_ctx, NI_LOG_DEBUG, "nrNoiseSigmaCb=%u\n", p_t408->nrNoiseSigmaCb);
10276 ni_log2(p_ctx, NI_LOG_DEBUG, "nrNoiseSigmaCr=%u\n", p_t408->nrNoiseSigmaCr);
10277
10278 // newly added for T408
10279 ni_log2(p_ctx, NI_LOG_DEBUG, "monochromeEnable=%u\n", p_t408->monochromeEnable);
10280 ni_log2(p_ctx, NI_LOG_DEBUG, "strongIntraSmoothEnable=%u\n",
10281 p_t408->strongIntraSmoothEnable);
10282
10283 ni_log2(p_ctx, NI_LOG_DEBUG, "weightPredEnable=%u\n", p_t408->weightPredEnable);
10284 ni_log2(p_ctx, NI_LOG_DEBUG, "bgDetectEnable=%u\n", p_t408->bgDetectEnable);
10285 ni_log2(p_ctx, NI_LOG_DEBUG, "bgThrDiff=%u\n", p_t408->bgThrDiff);
10286 ni_log2(p_ctx, NI_LOG_DEBUG, "bgThrMeanDiff=%u\n", p_t408->bgThrMeanDiff);
10287 ni_log2(p_ctx, NI_LOG_DEBUG, "bgLambdaQp=%u\n", p_t408->bgLambdaQp);
10288 ni_log2(p_ctx, NI_LOG_DEBUG, "bgDeltaQp=%d\n", p_t408->bgDeltaQp);
10289
10290 ni_log2(p_ctx, NI_LOG_DEBUG, "customLambdaEnable=%u\n", p_t408->customLambdaEnable);
10291 ni_log2(p_ctx, NI_LOG_DEBUG, "customMDEnable=%u\n", p_t408->customMDEnable);
10292 ni_log2(p_ctx, NI_LOG_DEBUG, "pu04DeltaRate=%d\n", p_t408->pu04DeltaRate);
10293 ni_log2(p_ctx, NI_LOG_DEBUG, "pu08DeltaRate=%d\n", p_t408->pu08DeltaRate);
10294 ni_log2(p_ctx, NI_LOG_DEBUG, "pu16DeltaRate=%d\n", p_t408->pu16DeltaRate);
10295 ni_log2(p_ctx, NI_LOG_DEBUG, "pu32DeltaRate=%d\n", p_t408->pu32DeltaRate);
10296 ni_log2(p_ctx, NI_LOG_DEBUG, "pu04IntraPlanarDeltaRate=%d\n", p_t408->pu04IntraPlanarDeltaRate);
10297 ni_log2(p_ctx, NI_LOG_DEBUG, "pu04IntraDcDeltaRate=%d\n", p_t408->pu04IntraDcDeltaRate);
10298 ni_log2(p_ctx, NI_LOG_DEBUG, "pu04IntraAngleDeltaRate=%d\n", p_t408->pu04IntraAngleDeltaRate);
10299 ni_log2(p_ctx, NI_LOG_DEBUG, "pu08IntraPlanarDeltaRate=%d\n", p_t408->pu08IntraPlanarDeltaRate);
10300 ni_log2(p_ctx, NI_LOG_DEBUG, "pu08IntraDcDeltaRate=%d\n", p_t408->pu08IntraDcDeltaRate);
10301 ni_log2(p_ctx, NI_LOG_DEBUG, "pu08IntraAngleDeltaRate=%d\n", p_t408->pu08IntraAngleDeltaRate);
10302 ni_log2(p_ctx, NI_LOG_DEBUG, "pu16IntraPlanarDeltaRate=%d\n", p_t408->pu16IntraPlanarDeltaRate);
10303 ni_log2(p_ctx, NI_LOG_DEBUG, "pu16IntraDcDeltaRate=%d\n", p_t408->pu16IntraDcDeltaRate);
10304 ni_log2(p_ctx, NI_LOG_DEBUG, "pu16IntraAngleDeltaRate=%d\n", p_t408->pu16IntraAngleDeltaRate);
10305 ni_log2(p_ctx, NI_LOG_DEBUG, "pu32IntraPlanarDeltaRate=%d\n", p_t408->pu32IntraPlanarDeltaRate);
10306 ni_log2(p_ctx, NI_LOG_DEBUG, "pu32IntraDcDeltaRate=%d\n", p_t408->pu32IntraDcDeltaRate);
10307 ni_log2(p_ctx, NI_LOG_DEBUG, "pu32IntraAngleDeltaRate=%d\n", p_t408->pu32IntraAngleDeltaRate);
10308 ni_log2(p_ctx, NI_LOG_DEBUG, "cu08IntraDeltaRate=%d\n", p_t408->cu08IntraDeltaRate);
10309 ni_log2(p_ctx, NI_LOG_DEBUG, "cu08InterDeltaRate=%d\n", p_t408->cu08InterDeltaRate);
10310 ni_log2(p_ctx, NI_LOG_DEBUG, "cu08MergeDeltaRate=%d\n", p_t408->cu08MergeDeltaRate);
10311 ni_log2(p_ctx, NI_LOG_DEBUG, "cu16IntraDeltaRate=%d\n", p_t408->cu16IntraDeltaRate);
10312 ni_log2(p_ctx, NI_LOG_DEBUG, "cu16InterDeltaRate=%d\n", p_t408->cu16InterDeltaRate);
10313 ni_log2(p_ctx, NI_LOG_DEBUG, "cu16MergeDeltaRate=%d\n", p_t408->cu16MergeDeltaRate);
10314 ni_log2(p_ctx, NI_LOG_DEBUG, "cu32IntraDeltaRate=%d\n", p_t408->cu32IntraDeltaRate);
10315 ni_log2(p_ctx, NI_LOG_DEBUG, "cu32InterDeltaRate=%d\n", p_t408->cu32InterDeltaRate);
10316 ni_log2(p_ctx, NI_LOG_DEBUG, "cu32MergeDeltaRate=%d\n", p_t408->cu32MergeDeltaRate);
10317 ni_log2(p_ctx, NI_LOG_DEBUG, "coefClearDisable=%d\n", p_t408->coefClearDisable);
10318 ni_log2(p_ctx, NI_LOG_DEBUG, "minQpI=%d\n", p_t408->minQpI);
10319 ni_log2(p_ctx, NI_LOG_DEBUG, "maxQpI=%d\n", p_t408->maxQpI);
10320 ni_log2(p_ctx, NI_LOG_DEBUG, "minQpP=%d\n", p_t408->minQpP);
10321 ni_log2(p_ctx, NI_LOG_DEBUG, "maxQpP=%d\n", p_t408->maxQpP);
10322 ni_log2(p_ctx, NI_LOG_DEBUG, "minQpB=%d\n", p_t408->minQpB);
10323 ni_log2(p_ctx, NI_LOG_DEBUG, "maxQpB=%d\n", p_t408->maxQpB);
10324
10325 // for H.264 on T408
10326 ni_log2(p_ctx, NI_LOG_DEBUG, "avcIdrPeriod=%d\n", p_t408->avcIdrPeriod);
10327 ni_log2(p_ctx, NI_LOG_DEBUG, "rdoSkip=%d\n", p_t408->rdoSkip);
10328 ni_log2(p_ctx, NI_LOG_DEBUG, "lambdaScalingEnable=%d\n", p_t408->lambdaScalingEnable);
10329 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_transform_8x8=%d\n", p_t408->enable_transform_8x8);
10330 ni_log2(p_ctx, NI_LOG_DEBUG, "slice_mode=%d\n", p_t408->slice_mode);
10331 ni_log2(p_ctx, NI_LOG_DEBUG, "slice_arg=%d\n", p_t408->slice_arg);
10332 ni_log2(p_ctx, NI_LOG_DEBUG, "intra_mb_refresh_mode=%d\n", p_t408->intra_mb_refresh_mode);
10333 ni_log2(p_ctx, NI_LOG_DEBUG, "intra_mb_refresh_arg=%d\n", p_t408->intra_mb_refresh_arg);
10334 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_mb_level_rc=%d\n", p_t408->enable_mb_level_rc);
10335 ni_log2(p_ctx, NI_LOG_DEBUG, "entropy_coding_mode=%d\n", p_t408->entropy_coding_mode);
10336 ni_log2(p_ctx, NI_LOG_DEBUG, "forcedHeaderEnable=%u\n", p_t408->forcedHeaderEnable);
10337
10338 //QUADRA
10339 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnableAUD=%d\n", p_cfg->ui8EnableAUD);
10340 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8LookAheadDepth=%d\n", p_cfg->ui8LookAheadDepth);
10341 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8rdoLevel=%d\n", p_cfg->ui8rdoLevel);
10342 ni_log2(p_ctx, NI_LOG_DEBUG, "i8crf=%d\n", p_cfg->i8crf);
10343 ni_log2(p_ctx, NI_LOG_DEBUG, "i8crfDecimal=%d\n", p_cfg->i8crfDecimal);
10344 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16HDR10MaxLight=%d\n", p_cfg->ui16HDR10MaxLight);
10345 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16HDR10AveLight=%d\n", p_cfg->ui16HDR10AveLight);
10346 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8HDR10CLLEnable=%d\n", p_cfg->ui8HDR10CLLEnable);
10347 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnableRdoQuant=%d\n", p_cfg->ui8EnableRdoQuant);
10348 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8ctbRcMode=%d\n", p_cfg->ui8ctbRcMode);
10349 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8gopSize=%d\n", p_cfg->ui8gopSize);
10350 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8useLowDelayPocType=%d\n", p_cfg->ui8useLowDelayPocType);
10351 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8gopLowdelay=%d\n", p_cfg->ui8gopLowdelay);
10352 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16gdrDuration=%d\n", p_cfg->ui16gdrDuration);
10353 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8hrdEnable=%d\n", p_cfg->ui8hrdEnable);
10354 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8colorDescPresent=%d\n", p_cfg->ui8colorDescPresent);
10355 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8colorPrimaries=%d\n", p_cfg->ui8colorPrimaries);
10356 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8colorTrc=%d\n", p_cfg->ui8colorTrc);
10357 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8colorSpace=%d\n", p_cfg->ui8colorSpace);
10358 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16aspectRatioWidth=%d\n", p_cfg->ui16aspectRatioWidth);
10359 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16aspectRatioHeight=%d\n", p_cfg->ui16aspectRatioHeight);
10360 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16rootBufId=%d\n", p_cfg->ui16rootBufId);
10361 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8planarFormat=%d\n", p_cfg->ui8planarFormat);
10362 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8PixelFormat=%d\n", p_cfg->ui8PixelFormat);
10363 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32ltrRefInterval=%u\n", p_cfg->ui32ltrRefInterval);
10364 ni_log2(p_ctx, NI_LOG_DEBUG, "i32ltrRefQpOffset=%d\n", p_cfg->i32ltrRefQpOffset);
10365 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32ltrFirstGap=%u\n", p_cfg->ui32ltrFirstGap);
10366 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32ltrNextInterval=%u\n", p_cfg->ui32ltrNextInterval);
10367 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8multicoreJointMode=%d\n", p_cfg->ui8multicoreJointMode);
10368 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8videoFullRange=%u\n", p_cfg->ui8videoFullRange);
10369 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32QLevel=%u\n", p_cfg->ui32QLevel);
10370 ni_log2(p_ctx, NI_LOG_DEBUG, "i8chromaQpOffset=%d\n", p_cfg->i8chromaQpOffset);
10371 ni_log2(p_ctx, NI_LOG_DEBUG, "i32tolCtbRcInter=0x%x\n", p_cfg->i32tolCtbRcInter);
10372 ni_log2(p_ctx, NI_LOG_DEBUG, "i32tolCtbRcIntra=0x%x\n", p_cfg->i32tolCtbRcIntra);
10373 ni_log2(p_ctx, NI_LOG_DEBUG, "i16bitrateWindow=%d\n", p_cfg->i16bitrateWindow);
10374 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8inLoopDSRatio=%u\n", p_cfg->ui8inLoopDSRatio);
10375 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8blockRCSize=%u\n", p_cfg->ui8blockRCSize);
10376 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8rcQpDeltaRange=%u\n", p_cfg->ui8rcQpDeltaRange);
10377 ni_log2(p_ctx, NI_LOG_DEBUG, "i16ctbRowQpStep=%u\n", p_cfg->i16ctbRowQpStep);
10378 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8NewRCEnable=%u\n", p_cfg->ui8NewRCEnable);
10379 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8LowDelay=%d\n", p_cfg->ui8LowDelay);
10380 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8hdr10_enable=%u\n", p_cfg->ui8hdr10_enable);
10381 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dx0=%u\n", p_cfg->ui16hdr10_dx0);
10382 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dy0=%u\n", p_cfg->ui16hdr10_dy0);
10383 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dx1=%u\n", p_cfg->ui16hdr10_dx1);
10384 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dy1=%u\n", p_cfg->ui16hdr10_dy1);
10385 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dx2=%u\n", p_cfg->ui16hdr10_dx2);
10386 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dy2=%u\n", p_cfg->ui16hdr10_dy2);
10387 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_wx=%u\n", p_cfg->ui16hdr10_wx);
10388 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_wy=%u\n", p_cfg->ui16hdr10_wy);
10389 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32hdr10_maxluma=%u\n", p_cfg->ui32hdr10_maxluma);
10390 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32hdr10_minluma=%u\n", p_cfg->ui32hdr10_minluma);
10391 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8avccHvcc=%u\n", p_cfg->ui8avccHvcc);
10392 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8av1ErrResilientMode=%u\n", p_cfg->ui8av1ErrResilientMode);
10393 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8intraResetRefresh=%d\n", p_cfg->ui8intraResetRefresh);
10394 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8temporalLayersEnable=%u\n", p_cfg->ui8temporalLayersEnable);
10395 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8enable2PassGopPattern=%u\n", p_cfg->ui8enable2PassGopPatern);
10396 ni_log2(p_ctx, NI_LOG_DEBUG, "zerocopy_mode=%d\n", p_src->zerocopy_mode);
10397 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32lumaLinesize=%u\n", p_cfg->ui32lumaLinesize);
10398 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32chromaLinesize=%u\n", p_cfg->ui32chromaLinesize);
10399 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32cropWidth=%u\n", p_cfg->ui32cropWidth);
10400 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32cropHeight=%u\n", p_cfg->ui32cropHeight);
10401 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32horOffset=%u\n", p_cfg->ui32horOffset);
10402 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32verOffset=%u\n", p_cfg->ui32verOffset);
10403 ni_log2(p_ctx, NI_LOG_DEBUG, "i8crfMax=%d\n", p_cfg->i8crfMax);
10404 ni_log2(p_ctx, NI_LOG_DEBUG, "i32qcomp=%d\n", p_cfg->i32qcomp);
10405 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8noMbtree=%u\n", p_cfg->ui8noMbtree);
10406 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8noHWMultiPassSupport=%u\n", p_cfg->ui8noHWMultiPassSupport);
10407 ni_log2(p_ctx, NI_LOG_DEBUG, "i8cuTreeFactor=%d\n", p_cfg->i8cuTreeFactor);
10408 ni_log2(p_ctx, NI_LOG_DEBUG, "i32ipRatio=%d\n", p_cfg->i32ipRatio);
10409 ni_log2(p_ctx, NI_LOG_DEBUG, "i32pbRatio=%d\n", p_cfg->i32pbRatio);
10410 ni_log2(p_ctx, NI_LOG_DEBUG, "i32cplxDecay=%d\n", p_cfg->i32cplxDecay);
10411 ni_log2(p_ctx, NI_LOG_DEBUG, "i8ppsInitQp=%d\n", p_cfg->i8ppsInitQp);
10412 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8bitrateMode=%u\n", p_cfg->ui8bitrateMode);
10413 ni_log2(p_ctx, NI_LOG_DEBUG, "i8pass1Qp=%d\n", p_cfg->i8pass1Qp);
10414 ni_log2(p_ctx, NI_LOG_DEBUG, "i8crfDecimal=%d\n", p_cfg->i8crfDecimal);
10415 ni_log2(p_ctx, NI_LOG_DEBUG, "i8hvsBaseMbComplexity=%u\n", p_cfg->i8hvsBaseMbComplexity);
10416 ni_log2(p_ctx, NI_LOG_DEBUG, "i8enableipRatio=%d\n",p_cfg->i8enableipRatio);
10417 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16iFrameSizeRatio=%u\n",p_cfg->ui16iFrameSizeRatio);
10418 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8crfMaxIframeEnable=%u\n", p_cfg->ui8crfMaxIframeEnable);
10419 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32vbvMinRate=%u\n", p_cfg->ui32vbvMinRate);
10420 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8disableBframeRDOQ=%u\n", p_cfg->ui8disableBframeRDOQ);
10421 ni_log2(p_ctx, NI_LOG_DEBUG, "i32forceBframeQpFactor=%d\n", p_cfg->i32forceBframeQpFactor);
10422 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8tuneBframeVisual=%u\n", p_cfg->ui8tuneBframeVisual);
10423 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnableAcqLimit=%u\n", p_cfg->ui8EnableAcqLimit);
10424 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8compressor=%u\n", p_cfg->ui8compressor);
10425 ni_log2(p_ctx, NI_LOG_DEBUG, "u8customizeRoiQpLevel=%u\n", p_cfg->u8customizeRoiQpLevel);
10426 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8motionConstrainedMode=%d\n", p_cfg->ui8motionConstrainedMode);
10427 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8mallocStrategy=%d\n", p_cfg->ui8mallocStrategy);
10428 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8spatialLayersMinusOne=%d\n", p_cfg->ui8spatialLayersMinusOne);
10429 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8enableTimecode=%d\n", p_cfg->ui8enableTimecode);
10430 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8spatialLayersRefBaseLayer=%d\n", p_cfg->ui8spatialLayersRefBaseLayer);
10431 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8vbvBufferReencode=%d\n", p_cfg->ui8vbvBufferReencode);
10432 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8totalCuTreeDepth=%u\n", p_cfg->ui8totalCuTreeDepth);
10433 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8adaptiveCuTree=%u\n", p_cfg->ui8adaptiveCuTree);
10434 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8preIntraHandling=%u\n", p_cfg->ui8preIntraHandling);
10435 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8baseLayerOnly=%u\n", p_cfg->ui8baseLayerOnly);
10436 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8pastFrameMaxIntraRatio=%u\n", p_cfg->ui8pastFrameMaxIntraRatio);
10437 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8linkFrameMaxIntraRatio=%u\n", p_cfg->ui8linkFrameMaxIntraRatio);
10438 ni_log2(p_ctx, NI_LOG_DEBUG, "i32spatialLayerBitrate=%d,%d,%d,%d\n", p_cfg->i32spatialLayerBitrate[0],
10440 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8disableAv1TimingInfo=%u\n", p_cfg->ui8disableAv1TimingInfo);
10441 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8av1OpLevel=%u,%u,%u,%u\n", p_cfg->ui8av1OpLevel[0],
10442 p_cfg->ui8av1OpLevel[1], p_cfg->ui8av1OpLevel[2], p_cfg->ui8av1OpLevel[3]);
10443 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8adaptiveLamdaMode=%u\n",p_cfg->ui8adaptiveLamdaMode);
10444 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8getCuInfo=%u\n", p_cfg->ui8getCuInfo);
10445 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8adaptiveCrfMode=%u\n",p_cfg->ui8adaptiveCrfMode);
10446 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8cutreeFlushIframe=%u\n",p_cfg->ui8cutreeFlushIframe);
10447 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8qpScaleEnable=%u\n", p_cfg->ui8qpScaleEnable);
10448}
10449
10450/*!******************************************************************************
10451 * \brief Setup and initialize all xcoder configuration to default (Rev. B)
10452 *
10453 * \param
10454 *
10455 * \return
10456 ******************************************************************************/
10458{
10459 int i = 0;
10460
10461 if( (!p_ctx) || (!p_config) )
10462 {
10463 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
10464 __func__);
10465 return;
10466 }
10467
10468 memset(p_config, 0, sizeof(ni_encoder_config_t));
10469
10470 // fill in common attributes values
10471 p_config->i32picWidth = 720;
10472 p_config->i32picHeight = 480;
10473 p_config->i32meBlkMode = 0; // (AVC ONLY) 0 means use all possible block partitions
10474 p_config->ui8sliceMode = 0; // 0 means 1 slice per picture
10475 p_config->i32frameRateInfo = 30;
10476 p_config->i32frameRateDenominator = 1;
10477 p_config->i32vbvBufferSize = 0; //0; parameter is ignored if rate control is off, if rate control is on, 0 means do not check vbv constraints
10478 p_config->i32userQpMax = 51; // this should also be h264-only parameter
10479
10480 // AVC only
10481 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
10482 {
10483 p_config->i32maxIntraSize = 8000000; // how big an intra p_frame can get?
10484 p_config->i32userMaxDeltaQp = 51;
10485 p_config->i32userMinDeltaQp = 51;
10486 p_config->i32userQpMin = 8;
10487 }
10488
10489 p_config->i32bitRate = 0;
10490 p_config->i32bitRateBL = 0;
10491 p_config->ui8rcEnable = 0;
10492 p_config->i32srcBitDepth = p_ctx->src_bit_depth;
10493 p_config->ui8enablePTS = 0;
10494 p_config->ui8lowLatencyMode = 0;
10495
10496 // profiles for H.264: 1 = baseline, 2 = main, 3 = extended, 4 = high
10497 // 5 = high10 (default 8 bit: 4, 10 bit: 5)
10498 // profiles for HEVC: 1 = main, 2 = main10 (default 8 bit: 1, 10 bit: 2)
10499
10500 // bitstream type: H.264 or HEVC
10501 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
10502 {
10503 p_config->ui8bitstreamFormat = STD_AVC;
10504
10505 p_config->niParamT408.profile = 4;
10506 if (10 == p_ctx->src_bit_depth)
10507 {
10508 p_config->niParamT408.profile = 5;
10509 }
10510 } else if (NI_CODEC_FORMAT_JPEG == p_ctx->codec_format)
10511 {
10512 p_config->ui8bitstreamFormat = STD_JPEG;
10513 } else if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
10514 {
10515 p_config->ui8bitstreamFormat = STD_AV1;
10516
10517 p_config->niParamT408.profile = 1;
10518 } else
10519 {
10521
10522 p_config->ui8bitstreamFormat = STD_HEVC;
10523
10524 p_config->niParamT408.profile = 1;
10525 if (10 == p_ctx->src_bit_depth)
10526 {
10527 p_config->niParamT408.profile = 2;
10528 }
10529 }
10530
10531 p_config->hdrEnableVUI = 0;
10532 p_config->ui32sourceEndian = p_ctx->src_endian;
10533
10534 p_config->niParamT408.level = 0;
10535 p_config->niParamT408.tier = 0; // 0 means main tier
10536
10537 p_config->niParamT408.internalBitDepth = p_ctx->src_bit_depth;
10538 p_config->niParamT408.losslessEnable = 0;
10539 p_config->niParamT408.constIntraPredFlag = 0;
10540
10541 if (QUADRA)
10543 else
10545
10546 p_config->niParamT408.decoding_refresh_type = 1;
10547 p_config->niParamT408.intra_qp = 22;
10548 // avcIdrPeriod (H.264 on T408), NOT shared with intra_period
10549 p_config->niParamT408.intra_period = 120;
10550 p_config->niParamT408.avcIdrPeriod = 120;
10551
10552 p_config->niParamT408.conf_win_top = 0;
10553 p_config->niParamT408.conf_win_bottom = 0;
10554 p_config->niParamT408.conf_win_left = 0;
10555 p_config->niParamT408.conf_win_right = 0;
10556
10557 p_config->niParamT408.independSliceMode = 0;
10558 p_config->niParamT408.independSliceModeArg = 0;
10559 p_config->niParamT408.dependSliceMode = 0;
10560 p_config->niParamT408.dependSliceModeArg = 0;
10561 p_config->niParamT408.intraRefreshMode = 0;
10562 p_config->niParamT408.intraRefreshArg = 0;
10563
10564 p_config->niParamT408.use_recommend_enc_params = 0; //1;
10565 p_config->niParamT408.scalingListEnable = 0;
10566
10567 p_config->niParamT408.cu_size_mode = 7;
10568 p_config->niParamT408.tmvpEnable = 1;
10569 p_config->niParamT408.wppEnable = 0;
10570 p_config->niParamT408.max_num_merge = 2;
10571 p_config->niParamT408.disableDeblk = 0;
10573 p_config->niParamT408.betaOffsetDiv2 = 0;
10574 p_config->niParamT408.tcOffsetDiv2 = 0;
10575 p_config->niParamT408.skipIntraTrans = 1;
10576 p_config->niParamT408.saoEnable = 1;
10577 p_config->niParamT408.intraNxNEnable = 1;
10578
10579 p_config->niParamT408.bitAllocMode = 0;
10580
10581 for (i = 0; i < NI_MAX_GOP_NUM; i++)
10582 {
10583 p_config->niParamT408.fixedBitRatio[i] = 1;
10584 }
10585
10586 if (QUADRA)
10588 else
10590
10591 p_config->niParamT408.enable_hvs_qp = 0;
10592 p_config->niParamT408.hvs_qp_scale = 2;
10593
10594 p_config->niParamT408.max_delta_qp = 10;
10595
10596 // CUSTOM_GOP
10598#ifndef QUADRA
10599 if (!QUADRA)
10600 {
10601 for (i = 0; i < p_config->niParamT408.custom_gop_params.custom_gop_size; i++)
10602 {
10605 p_config->niParamT408.custom_gop_params.pic_param[i].pic_qp = 0;
10606 p_config->niParamT408.custom_gop_params.pic_param[i].num_ref_pic_L0 = 0;
10607 p_config->niParamT408.custom_gop_params.pic_param[i].ref_poc_L0 = 0;
10608 p_config->niParamT408.custom_gop_params.pic_param[i].ref_poc_L1 = 0;
10610 }
10611 }
10612 else // QUADRA
10613#endif
10614 {
10615 int j;
10616 for (i = 0; i < NI_MAX_GOP_NUM; i++)
10617 {
10621 (float)0.3; // QP Factor range is between 0.3 and 1, higher values mean lower quality and less bits
10625 for (j = 0; j < NI_MAX_REF_PIC; j++)
10626 {
10629 }
10630 }
10631 }
10632
10633 p_config->niParamT408.roiEnable = 0;
10634
10635 p_config->niParamT408.numUnitsInTick = 1000;
10636 p_config->niParamT408.timeScale = p_config->i32frameRateInfo * 1000;
10637 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
10638 {
10639 p_config->niParamT408.timeScale *= 2;
10640 }
10641
10642 p_config->niParamT408.numTicksPocDiffOne = 0;
10643
10644 p_config->niParamT408.chromaCbQpOffset = 0;
10645 p_config->niParamT408.chromaCrQpOffset = 0;
10646
10647 p_config->niParamT408.initialRcQp = 63; //-1;
10648
10649 p_config->niParamT408.nrYEnable = 0;
10650 p_config->niParamT408.nrCbEnable = 0;
10651 p_config->niParamT408.nrCrEnable = 0;
10652
10653 // ENC_NR_WEIGHT
10654 p_config->niParamT408.nrIntraWeightY = 7;
10655 p_config->niParamT408.nrIntraWeightCb = 7;
10656 p_config->niParamT408.nrIntraWeightCr = 7;
10657 p_config->niParamT408.nrInterWeightY = 4;
10658 p_config->niParamT408.nrInterWeightCb = 4;
10659 p_config->niParamT408.nrInterWeightCr = 4;
10660
10661 p_config->niParamT408.nrNoiseEstEnable = 0;
10662 p_config->niParamT408.nrNoiseSigmaY = 0;
10663 p_config->niParamT408.nrNoiseSigmaCb = 0;
10664 p_config->niParamT408.nrNoiseSigmaCr = 0;
10665
10666 p_config->niParamT408.useLongTerm = 0;
10667
10668 // newly added for T408
10669 p_config->niParamT408.monochromeEnable = 0;
10671
10672 p_config->niParamT408.weightPredEnable = 0;
10673 p_config->niParamT408.bgDetectEnable = 0;
10674 p_config->niParamT408.bgThrDiff = 8; // matching the C-model
10675 p_config->niParamT408.bgThrMeanDiff = 1; // matching the C-model
10676 p_config->niParamT408.bgLambdaQp = 32; // matching the C-model
10677 p_config->niParamT408.bgDeltaQp = 3; // matching the C-model
10678
10679 p_config->niParamT408.customLambdaEnable = 0;
10680 p_config->niParamT408.customMDEnable = 0;
10681 p_config->niParamT408.pu04DeltaRate = 0;
10682 p_config->niParamT408.pu08DeltaRate = 0;
10683 p_config->niParamT408.pu16DeltaRate = 0;
10684 p_config->niParamT408.pu32DeltaRate = 0;
10686 p_config->niParamT408.pu04IntraDcDeltaRate = 0;
10689 p_config->niParamT408.pu08IntraDcDeltaRate = 0;
10692 p_config->niParamT408.pu16IntraDcDeltaRate = 0;
10695 p_config->niParamT408.pu32IntraDcDeltaRate = 0;
10697 p_config->niParamT408.cu08IntraDeltaRate = 0;
10698 p_config->niParamT408.cu08InterDeltaRate = 0;
10699 p_config->niParamT408.cu08MergeDeltaRate = 0;
10700 p_config->niParamT408.cu16IntraDeltaRate = 0;
10701 p_config->niParamT408.cu16InterDeltaRate = 0;
10702 p_config->niParamT408.cu16MergeDeltaRate = 0;
10703 p_config->niParamT408.cu32IntraDeltaRate = 0;
10704 p_config->niParamT408.cu32InterDeltaRate = 0;
10705 p_config->niParamT408.cu32MergeDeltaRate = 0;
10706 p_config->niParamT408.coefClearDisable = 0;
10707 p_config->niParamT408.minQpI = 8;
10708 p_config->niParamT408.maxQpI = 51;
10709 p_config->niParamT408.minQpP = 8;
10710 p_config->niParamT408.maxQpP = 51;
10711 p_config->niParamT408.minQpB = 8;
10712 p_config->niParamT408.maxQpB = 51;
10713
10714 // for H.264 on T408
10715 p_config->niParamT408.rdoSkip = 0;
10716 p_config->niParamT408.lambdaScalingEnable = 0;
10717 p_config->niParamT408.enable_transform_8x8 = 1;
10718 p_config->niParamT408.slice_mode = 0;
10719 p_config->niParamT408.slice_arg = 0;
10720 p_config->niParamT408.intra_mb_refresh_mode = 0;
10721 p_config->niParamT408.intra_mb_refresh_arg = 0;
10722 if (QUADRA)
10723 p_config->niParamT408.enable_mb_level_rc = 0;
10724 else
10725 p_config->niParamT408.enable_mb_level_rc = 1;
10726 p_config->niParamT408.entropy_coding_mode = 1; // 1 means CABAC, make sure profile is main or above, can't have CABAC in baseline
10727 p_config->niParamT408.forcedHeaderEnable = 0; // first IDR frame
10728
10729 //QUADRA
10730 p_config->ui8EnableAUD = 0;
10731 p_config->ui8LookAheadDepth = 0;
10732 p_config->ui8rdoLevel = (NI_CODEC_FORMAT_JPEG == p_ctx->codec_format) ? 0 : 1;
10733 p_config->i8crf = -1;
10734 p_config->ui16HDR10MaxLight = 0;
10735 p_config->ui16HDR10AveLight = 0;
10736 p_config->ui8HDR10CLLEnable = 0;
10737 p_config->ui8EnableRdoQuant = 0;
10738 p_config->ui8ctbRcMode = 0;
10739 p_config->ui8gopSize = 0;
10740 p_config->ui8useLowDelayPocType = 0;
10741 p_config->ui8gopLowdelay = 0;
10742 p_config->ui16gdrDuration = 0;
10743 p_config->ui8hrdEnable = 0;
10744 p_config->ui8colorDescPresent = 0;
10746 p_config->ui8colorPrimaries = 2;
10747 //AVCOL_TRC_UNSPECIFIED
10748 p_config->ui8colorTrc = 2;
10749 //AVCOL_SPC_UNSPECIFIED
10750 p_config->ui8colorSpace = 2;
10751 p_config->ui16aspectRatioWidth = 0;
10752 p_config->ui16aspectRatioHeight = 0;
10755 p_config->ui32ltrRefInterval = 0;
10756 p_config->i32ltrRefQpOffset = 0;
10757 p_config->ui32ltrFirstGap= 0;
10758 p_config->ui32ltrNextInterval = 1;
10759 p_config->ui8multicoreJointMode = 0;
10760 p_config->ui8videoFullRange = 0;
10761 p_config->ui32setLongTermInterval = 0;
10762 p_config->ui8setLongTermCount = 2;
10763 p_config->ui32QLevel = -1;
10764 p_config->i8chromaQpOffset = 0;
10765 p_config->i32tolCtbRcInter = (int32_t)(0.1 * 1000);
10766 p_config->i32tolCtbRcIntra = (int32_t)(0.1 * 1000);
10767 p_config->i16bitrateWindow = -255;
10768 p_config->ui8inLoopDSRatio = 1;
10769 p_config->ui8blockRCSize = 0;
10770 p_config->ui8rcQpDeltaRange = 10;
10771 p_config->i16ctbRowQpStep = 0;
10772 p_config->ui8NewRCEnable = 255;
10773 p_config->ui8LowDelay = 0;
10774 p_config->ui8fixedframerate = 1;
10775 p_config->ui8enableSSIM = 0;
10776 p_config->ui8hdr10_enable = 0;
10777 p_config->ui16hdr10_dx0 = 0;
10778 p_config->ui16hdr10_dy0 = 0;
10779 p_config->ui16hdr10_dx1 = 0;
10780 p_config->ui16hdr10_dy1 = 0;
10781 p_config->ui16hdr10_dx2 = 0;
10782 p_config->ui16hdr10_dy2 = 0;
10783 p_config->ui16hdr10_wx = 0;
10784 p_config->ui16hdr10_wy = 0;
10785 p_config->ui32hdr10_maxluma = 0;
10786 p_config->ui32hdr10_minluma = 0;
10787 p_config->ui8avccHvcc = 0;
10788 p_config->ui8av1ErrResilientMode = 0;
10789 p_config->ui8intraResetRefresh = 0;
10790 p_config->ui8temporalLayersEnable = 0;
10791 p_config->ui8enable2PassGopPatern = 0;
10792 p_config->i8crfMax = (int8_t)(-1) + 1; // for old libxcoder backward compatibility, use 1 to represent 0
10793 p_config->i32qcomp = (int32_t)(0.6 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10794 p_config->ui8noMbtree = 0;
10795 p_config->ui8noHWMultiPassSupport = 0;
10796 p_config->i8cuTreeFactor = 5;
10797 p_config->i32ipRatio = (int32_t)(1.4 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10798 p_config->i32pbRatio = (int32_t)(1.3 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10799 p_config->i32cplxDecay = (int32_t)(0.5 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10800 p_config->ui32vbvMaxRate = 0;
10801 p_config->i8ppsInitQp = (int8_t)(-1) + 1; // for old libxcoder backward compatibility, use 1 to represent 0
10802 p_config->ui8bitrateMode = 0; // bitrateMode 0 = max bitrate (actual bitrate can be lower than bitrate target), bitrateMode 1 = average bitrate (actual bitrate approximately equal to bitrate target)
10803 p_config->i8pass1Qp = (int8_t)(-1) + 1; // for old libxcoder backward compatibility, use 1 to represent 0
10804 p_config->i8crfDecimal = 0;
10805 p_config->i8hvsBaseMbComplexity = (int8_t)(15)-15; // for old libxcoder backward compatibility, use -15 to represent 0
10806 p_config->i8statisticOutputLevel = 0;
10807 p_config->i8enableipRatio = 0;
10808 p_config->ui16iFrameSizeRatio = 100;
10809 p_config->ui8compressor = 3;
10810 p_config->u8skipFrameInterval = 0;
10811 p_config->ui8crfMaxIframeEnable = 0;
10812 p_config->ui32vbvMinRate = 0;
10813 p_config->ui8disableBframeRDOQ = 0;
10814 p_config->i32forceBframeQpFactor = (int32_t)(-1.0 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10815 p_config->ui8tuneBframeVisual = 0;
10816 p_config->ui8EnableAcqLimit = 0;
10818 p_config->ui32cropWidth = 0;
10819 p_config->ui32cropHeight = 0;
10820 p_config->ui32horOffset = 0;
10821 p_config->ui32verOffset = 0;
10822 p_config->ui8motionConstrainedMode = 0;
10823 p_config->ui8stillImageDetectLevel = 0;
10824 p_config->ui8sceneChangeDetectLevel = 0;
10825 p_config->ui8mallocStrategy = 0;
10826 p_config->ui8spatialLayersMinusOne = 0;
10827 p_config->ui8enableTimecode = 0;
10828 p_config->ui8spatialLayersRefBaseLayer = 0;
10829 p_config->ui8vbvBufferReencode = 0;
10830 p_config->ui8totalCuTreeDepth = 0;
10831 p_config->ui8adaptiveCuTree = 0;
10832 p_config->ui8preIntraHandling = (uint8_t)(1)-1; // for old libxcoder backward compatibility, use -1 to represent 0
10833 p_config->ui8baseLayerOnly = 0;
10834 p_config->ui8pastFrameMaxIntraRatio = (uint8_t)(20)-20; // for old libxcoder backward compatibility, use -20 to represent 0
10835 p_config->ui8linkFrameMaxIntraRatio = (uint8_t)(40)-40; // for old libxcoder backward compatibility, use -40 to represent 0
10836 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
10837 {
10838 p_config->i32spatialLayerBitrate[i] = 0;
10839 p_config->ui8av1OpLevel[i] = 0;
10840 }
10841 p_config->ui8disableAv1TimingInfo = 0;
10842 p_config->ui8adaptiveLamdaMode = 0;
10843 p_config->ui8getCuInfo = 0;
10844 p_config->ui8adaptiveCrfMode = 0;
10845 p_config->ui8cutreeFlushIframe = 0;
10846 p_config->ui8qpScaleEnable = 0;
10847}
10848
10849/*!******************************************************************************
10850* \brief Perform validation on custom dec parameters (Rev. B)
10851*
10852* \param
10853*
10854* \return
10855******************************************************************************/
10857 ni_session_context_t *p_ctx,
10858 ni_decoder_config_t *p_cfg,
10859 char *p_param_err,
10860 uint32_t max_err_len)
10861{
10862 ni_retcode_t param_ret = NI_RETCODE_SUCCESS;
10864 int w = p_src->source_width;
10865 int h = p_src->source_height;
10866 char *p_param_warn = NULL;
10867 int i;
10868
10869 if (!p_ctx || !p_cfg || !p_param_err)
10870 {
10871 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
10872 __func__);
10873 param_ret = NI_RETCODE_INVALID_PARAM;
10874 LRETURN;
10875 }
10876
10877 // Zero out the error buffer
10878 p_param_warn = malloc(sizeof(p_ctx->param_err_msg));
10879 if (!p_param_warn)
10880 {
10881 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() p_param_warn malloc failure\n",
10882 NI_ERRNO, __func__);
10883 param_ret = NI_RETCODE_ERROR_MEM_ALOC;
10884 LRETURN;
10885 }
10886
10887 memset(p_param_err, 0, max_err_len);
10888 memset(p_param_warn, 0, max_err_len);
10889
10890
10891 //if (p_cfg->i32bitRate > NI_MAX_BITRATE)
10892 //{
10893 // ni_strncpy(p_param_err, max_err_len, "Invalid i32bitRate: too big", max_err_len - 1);
10894 // param_ret = NI_RETCODE_PARAM_ERROR_BRATE;
10895 // LRETURN;
10896 //}
10897
10898 if (p_cfg->ui8HWFrame == 0 &&
10899 (p_cfg->asOutputConfig[1].ui8Enabled || p_cfg->asOutputConfig[2].ui8Enabled))
10900 {
10901 ni_strncpy(p_param_err, max_err_len, "Incompatible output format: hw frame must be used if out1 or out2 used", max_err_len - 1);
10902 param_ret = NI_RETCODE_INVALID_PARAM;
10903 LRETURN;
10904 }
10905
10906 if (p_src->ddr_priority_mode >= 0)
10907 {
10909 "6e") < 0)
10910 {
10911 ni_strncpy(p_param_err, max_err_len, "ddr_priority_mode not supported on device with FW api version < 6.e",
10912 max_err_len - 1);
10914 LRETURN;
10915 }
10916 }
10917
10919 {
10920 ni_strncpy(p_param_err, max_err_len, "LowDelay is not supported on jpeg/vp9 decoder",
10921 max_err_len - 1);
10923 LRETURN;
10924 }
10925
10926 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
10927 {
10928 //checking cropping param
10930 {
10933 {
10934 ni_strncpy(p_param_err, max_err_len, "Invalid crop offset: extends past 48x48 minimum window", max_err_len - 1);
10935 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
10936 LRETURN;
10937 }
10940 {
10941 ni_strncpy(p_param_err, max_err_len, "Invalid crop w or h: must be at least 48x48 minimum window", max_err_len - 1);
10943 LRETURN;
10944 }
10945 if (p_cfg->asOutputConfig[i].sCroppingRectable.ui16W > w ||
10947 {
10948 ni_strncpy(p_param_err, max_err_len, "Invalid crop w or h: must be smaller than input", max_err_len - 1);
10949 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
10950 LRETURN;
10951 }
10954 {
10955 ni_strncpy(p_param_err, max_err_len, "Invalid crop rect: must fit in input", max_err_len - 1);
10956 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
10957 LRETURN;
10958 }
10959 if (p_cfg->asOutputConfig[i].sCroppingRectable.ui16X & 1 ||
10960 p_cfg->asOutputConfig[i].sCroppingRectable.ui16Y & 1 ||
10961 p_cfg->asOutputConfig[i].sCroppingRectable.ui16W & 1 ||
10963 {
10964 ni_strncpy(p_param_err, max_err_len, "Invalid crop value: even values only", max_err_len - 1);
10966 LRETURN;
10967 }
10968 if (p_cfg->asOutputConfig[i].ui8Enabled == 0)
10969 {
10970 ni_strncpy(p_param_warn, max_err_len, "crop param used but output not enabled!", max_err_len - 1);
10971 warning = NI_RETCODE_PARAM_WARN;
10972 }
10973
10974 }
10975
10976 //checking scaling param
10977 if (p_cfg->asOutputConfig[i].ui8ScaleEnabled)
10978 {
10979 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height == 0 ||
10981 {
10983 {
10984 //may need to revisit if based on cropped input or base input for w/h limit
10985 ni_strncpy(p_param_err, max_err_len, "Invalid scale dimensions: zero", max_err_len - 1);
10987 LRETURN;
10988 }
10989 }
10990 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height & 1 ||
10992 {
10993 ni_strncpy(p_param_err, max_err_len, "Invalid scale value: even values only", max_err_len - 1);
10995 LRETURN;
10996 }
10997
10998 if (p_cfg->asOutputConfig[i].ui8EnablePpuScaleLimit == 1)
10999 {
11000 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Width > w ||
11002 {
11003 ni_strncpy(p_param_err, max_err_len, "Invalid scale value: downscale only", max_err_len - 1);
11005 LRETURN;
11006 }
11007 }
11008
11010 {
11011 //reject if scale dimensions exceed crop dimensions
11014 {
11015 ni_strncpy(p_param_err, max_err_len, "Invalid scale dimensions: downscale only after cropping", max_err_len - 1);
11016 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
11017 LRETURN;
11018 }
11019 }
11020 if (p_cfg->asOutputConfig[i].ui8Enabled == 0)
11021 {
11022 ni_strncpy(p_param_warn, max_err_len, "scale param used but output not enabled!", max_err_len - 1);
11023 warning = NI_RETCODE_PARAM_WARN;
11024 }
11025 }
11026 if (p_cfg->asOutputConfig[i].ui8Enabled == 0)
11027 {
11029 {
11030 ni_strncpy(p_param_warn, max_err_len, "force8bit or semiPlanar used but output not enabled!", max_err_len - 1);
11031 warning = NI_RETCODE_PARAM_WARN;
11032 }
11033 }
11034
11035 //check tiled format compatibility
11037 {
11038 if (p_cfg->asOutputConfig[i].ui8Enabled == 0)
11039 {
11040 continue;
11041 }
11042 if (p_cfg->ui8HWFrame == 0)
11043 {
11044 ni_strncpy(p_param_err, max_err_len,
11045 "Invalid pairing: out=HW must be set with tiled format",
11046 max_err_len - 1);
11048 LRETURN;
11049 }
11050 if (p_ctx->codec_format == NI_CODEC_FORMAT_VP9)
11051 {
11052 ni_strncpy(p_param_err, max_err_len, "Invalid pairing: VP9 not compatible with tiled format",
11053 max_err_len - 1);
11055 LRETURN;
11056 }
11057 if (p_cfg->asOutputConfig[i].ui8ScaleEnabled)
11058 {
11059 //only no need to check crop compat if scale is set
11060 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height % 4 ||
11062 {
11063 ni_strncpy(p_param_err, max_err_len,
11064 "Invalid scale height: mult of 4 only, >= 128",
11065 max_err_len - 1);
11067 LRETURN;
11068 }
11069 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Width % 4 ||
11071 {
11072 //minimum supported dec is 128 but min enc is 144 so round up
11073 ni_strncpy(p_param_err, max_err_len,
11074 "Invalid scale width: mult of 128 only, >= 144",
11075 max_err_len - 1);
11077 LRETURN;
11078 }
11079 }
11081 {
11082 if (p_cfg->asOutputConfig[i].sCroppingRectable.ui16H % 4 ||
11083 p_cfg->asOutputConfig[i].sCroppingRectable.ui16H < 128)
11084 {
11085 ni_strncpy(p_param_err, max_err_len,
11086 "Invalid crop height: mult of 4 only, >= 128",
11087 max_err_len - 1);
11089 LRETURN;
11090 }
11091 if (p_cfg->asOutputConfig[i].sCroppingRectable.ui16W % 4 ||
11093 {
11094 //minimum supported dec is 128 but min enc is 144 so round up
11095 ni_strncpy(p_param_err, max_err_len,
11096 "Invalid crop width: mult of 128 only, >= 144",
11097 max_err_len - 1);
11099 LRETURN;
11100 }
11101 }
11102 if (p_cfg->asOutputConfig[i].ui8Force8Bit)
11103 {
11104 ni_strncpy(p_param_err, max_err_len, "Force 8 bit: not supported with tiled format\n", max_err_len - 1);
11106 LRETURN;
11107 }
11108 }
11109
11110 }//end forloop
11111 if (warning == NI_RETCODE_PARAM_WARN && param_ret == NI_RETCODE_SUCCESS)
11112 {
11113 param_ret = NI_RETCODE_PARAM_WARN;
11114 ni_strncpy(p_param_err, max_err_len, p_param_warn, max_err_len - 1);
11115 }
11116
11117END:
11118
11119 free(p_param_warn);
11120 return param_ret;
11121}
11122
11123// Check encoder level parameters
11124static ni_retcode_t ni_check_level(int level, int codec_id, int *level_index)
11125{
11126 const int l_levels_264[] = {10, 11, 12, 13, 20, 21, 22, 30, 31, 32,
11127 40, 41, 42, 50, 51, 52, 60, 61, 62, 0};
11128 const int l_levels_265[] = {10, 20, 21, 30, 31, 40, 41,
11129 50, 51, 52, 60, 61, 62, 0};
11130 const int l_levels_av1[] = {20, 21, 30, 31, 40, 41, 50, 51, 52, 53, 60, 61, 62, 63, 0};
11131 const int *l_levels = l_levels_264;
11132 int index = 0;
11133
11134 *level_index = -1;
11135
11136 if (level == 0)
11137 {
11138 return NI_RETCODE_SUCCESS;
11139 }
11140
11141 if (codec_id == NI_CODEC_FORMAT_H265)
11142 {
11143 l_levels = l_levels_265;
11144 } else if (codec_id == NI_CODEC_FORMAT_AV1)
11145 {
11146 l_levels = l_levels_av1;
11147 }
11148
11149 while (*l_levels != 0)
11150 {
11151 if (*l_levels == level)
11152 {
11153 *level_index = index;
11154 return NI_RETCODE_SUCCESS;
11155 }
11156 l_levels++;
11157 index++;
11158 }
11159
11160 return NI_RETCODE_FAILURE;
11161}
11162
11163static uint32_t get_max_pic_size( ni_codec_format_t codecFormat , int32_t levelIdx )
11164{
11165 assert( levelIdx >= 0);
11166 int32_t level = MAX(0, levelIdx);
11167 uint32_t maxPicSize = 0;
11168
11169 switch( codecFormat )
11170 {
11172 assert( level < HEVC_LEVEL_NUM );
11173 level = MIN( level, (HEVC_LEVEL_NUM - 1));
11174 maxPicSize = max_pic_size_h265[ level ];
11175 break;
11176
11178 assert( level < H264_LEVEL_NUM );
11179 level = MIN( level, (H264_LEVEL_NUM - 1));
11180 maxPicSize = max_pic_size_h264[ level ];
11181 break;
11182
11184 level = MIN( level, (AV1_LEVEL_NUM - 1));
11185 maxPicSize = max_pic_size_av1[ level ];
11186 break;
11187
11188 default:
11189 break;
11190 }
11191
11192 return maxPicSize;
11193}
11194
11195static uint64_t get_max_sample_rate_second( ni_codec_format_t codecFormat , int32_t levelIdx )
11196{
11197 assert( levelIdx >= 0);
11198 int32_t level = MAX(0, levelIdx);
11199 uint64_t maxSBPS = 0;
11200
11201 switch( codecFormat )
11202 {
11204 assert( level < HEVC_LEVEL_NUM );
11205 level = MIN( level, (HEVC_LEVEL_NUM - 1));
11206 maxSBPS = max_sample_rate_second_h265[ level ];
11207 break;
11208
11210 assert( level < H264_LEVEL_NUM );
11211 level = MIN( level, (H264_LEVEL_NUM - 1));
11212 maxSBPS = max_sample_rate_second_h264[ level ];
11213 break;
11214
11216 level = MIN( level, (AV1_LEVEL_NUM - 1));
11217 maxSBPS = max_sample_rate_second_av1[ level ];
11218 break;
11219
11220 default:
11221 break;
11222 }
11223
11224 return maxSBPS;
11225}
11226
11227// type 0: returns maximum bitrate, type 1: returns maximum vbv buffer size
11228static uint32_t get_max_cpb_bitrate( ni_codec_format_t codecFormat , int32_t levelIdx, int32_t profile, int32_t tier, int32_t type )
11229{
11230 assert( levelIdx >= 0);
11231 int32_t level = MAX(0, levelIdx);
11232 uint32_t maxBR = 0;
11233
11234 switch( codecFormat )
11235 {
11237 assert( level < HEVC_LEVEL_NUM );
11238 level = MIN( level, (HEVC_LEVEL_NUM - 1));
11239 maxBR = (tier == HIGH_TIER) ? max_cpb_hightier_second_h265[ level ] : max_cpb_second_h265[ level ];
11240 break;
11241
11243 assert( level < H264_LEVEL_NUM );
11244 level = MIN( level, (H264_LEVEL_NUM - 1));
11245 float h264_high10_factor = 1;
11246 if(profile == 4) /* High Profile */
11247 h264_high10_factor = 1.25;
11248 else if(profile == 5) /* High 10 Profile */
11249 h264_high10_factor = 3.0;
11250 if(type == 0)
11251 maxBR = (uint32_t)(max_bitrate_h264[ level ] * h264_high10_factor);
11252 else
11253 maxBR = (uint32_t)(max_cpb_second_h264[ level ] * h264_high10_factor);
11254 break;
11255
11257 level = MIN( level, (AV1_LEVEL_NUM - 1));
11258 maxBR = ((level > 7) && (tier == HIGH_TIER)) ? max_cpb_hightier_second_av1[ level ] : max_cpb_second_av1[ level ];
11259 break;
11260
11261 default:
11262 break;
11263 }
11264
11265 return maxBR;
11266}
11267
11268// Check encoder level parameters
11269static ni_retcode_t ni_check_level_tier_compliance(int level,
11270 ni_session_context_t *p_ctx,
11271 ni_encoder_config_t *p_cfg,
11272 ni_xcoder_params_t *p_src,
11273 char *p_param_err,
11274 char* p_param_warn,
11275 uint32_t max_err_len,
11276 ni_retcode_t *warning,
11277 int level_index)
11278{
11279 if( (!p_ctx) || (!p_cfg) || (!p_src) || (!p_param_err) || (!p_param_warn) || (!warning) )
11280 {
11281 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n", __func__);
11283 }
11284
11285 // level and tier check
11286 uint32_t sample_per_picture = p_src->source_width * p_src->source_height;
11287 uint64_t sample_per_second = sample_per_picture * p_cfg->i32frameRateInfo / p_cfg->i32frameRateDenominator;
11288 uint32_t max_pic_size = get_max_pic_size(p_ctx->codec_format, level_index);
11289 uint64_t max_sample_rate_second = get_max_sample_rate_second(p_ctx->codec_format, level_index);
11290 uint32_t max_bitrate = get_max_cpb_bitrate(p_ctx->codec_format, level_index, p_cfg->niParamT408.profile, p_cfg->niParamT408.tier, 0);
11291 uint32_t max_vbv = get_max_cpb_bitrate(p_ctx->codec_format, level_index, p_cfg->niParamT408.profile, p_cfg->niParamT408.tier, 1);
11292
11293 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): sample_per_picture %u sample_per_second %" PRIu64 " fr num %d den %d level_index %d\n",
11294 __func__, sample_per_picture, sample_per_second, p_cfg->i32frameRateInfo, p_cfg->i32frameRateDenominator,
11295 level_index);
11296 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): max_pic_size %d max_sample_rate_second %" PRIu64 " max_bitrate %u\n",
11297 __func__, max_pic_size, max_sample_rate_second, max_bitrate);
11298
11299 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): i8crf %d i32bitRate %d ui32vbvMaxRate %u i32vbvBufferSize %d\n",
11300 __func__, p_cfg->i8crf, p_cfg->i32bitRate, p_cfg->ui32vbvMaxRate, p_cfg->i32vbvBufferSize);
11301
11302 if (p_cfg->i8crf != -1)
11303 {
11304 if(p_cfg->i32vbvBufferSize == 0)
11305 {
11306 snprintf(p_param_warn, max_err_len, "Level (%.1f): Switched crf to capped crf to be compliant with the level",
11307 (float) level/10);
11308 *warning = NI_RETCODE_PARAM_WARN;
11309 p_cfg->ui32vbvMaxRate = p_cfg->i32bitRate = max_bitrate;
11310 p_cfg->i32vbvBufferSize = 1000;
11311 }
11312 }
11313 else if (p_cfg->ui8rcEnable == 0) // enable rate control if fixed QP mode
11314 {
11315 ni_strncpy(p_param_warn, max_err_len, "Enabled rate control because level parameter is used", max_err_len - 1);
11316 *warning = NI_RETCODE_PARAM_WARN;
11318 p_cfg->i32vbvBufferSize = 1000;
11319 }
11320
11321 if(sample_per_picture > max_pic_size)
11322 {
11323 snprintf(p_param_err, max_err_len, "Invalid Encoder Level (%.1f): picture size %u exceeds supported limits %u",
11324 (float) level/10, sample_per_picture, max_pic_size);
11326 }
11327
11328 if(sample_per_second > max_sample_rate_second)
11329 {
11330 snprintf(p_param_err, max_err_len, "Invalid Encoder Level (%.1f): picture sample rate %" PRIu64 " exceeds supported limits %" PRIu64 "",
11331 (float) level/10, sample_per_second, max_sample_rate_second);
11333 }
11334
11335 if(p_cfg->i32bitRate > (int32_t)max_bitrate)
11336 {
11337 snprintf(p_param_warn, max_err_len, "Level (%.1f): bitrate %d exceeds supported limit. Changed it to maximum %u",
11338 (float) level/10, p_cfg->i32bitRate, max_bitrate);
11339 *warning = NI_RETCODE_PARAM_WARN;
11340 p_cfg->i32bitRate = (int32_t)max_bitrate;
11341 }
11342
11343 if(p_cfg->ui32vbvMaxRate > (int32_t)max_vbv)
11344 {
11345 snprintf(p_param_warn, max_err_len, "Level (%.1f): vbvMaxRate %u exceeds supported limit. Changed it to maximum %u",
11346 (float) level/10, p_cfg->ui32vbvMaxRate, max_vbv);
11347 *warning = NI_RETCODE_PARAM_WARN;
11348 p_cfg->ui32vbvMaxRate = (int32_t)max_vbv;
11349 }
11350
11351 return NI_RETCODE_SUCCESS;
11352}
11353
11354/*!******************************************************************************
11355 * \brief Perform validation on custom parameters (Rev. B)
11356 *
11357 * \param
11358 *
11359 * \return
11360 ******************************************************************************/
11362 ni_encoder_config_t *p_cfg,
11363 ni_xcoder_params_t *p_src,
11364 char *p_param_err,
11365 uint32_t max_err_len)
11366{
11367 ni_retcode_t param_ret = NI_RETCODE_SUCCESS;
11369 char* p_param_warn = malloc(sizeof(p_ctx->param_err_msg));
11371 int i;
11372 int level_index = 0;
11373
11374 if( (!p_ctx) || (!p_cfg) || (!p_src) || (!p_param_err) )
11375 {
11376 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
11377 __func__);
11378 param_ret = NI_RETCODE_INVALID_PARAM;
11379 LRETURN;
11380 }
11381
11382 //Zero out the error buffer
11383 p_enc = &p_src->cfg_enc_params;
11384 memset(p_param_err, 0, max_err_len);
11385 memset(p_param_warn, 0, max_err_len);
11386
11387 if (0 == p_cfg->i32frameRateInfo)
11388 {
11389 ni_strncpy(p_param_err, max_err_len, "Invalid frame_rate of 0 value", max_err_len - 1);
11390 param_ret = NI_RETCODE_PARAM_ERROR_FRATE;
11391 LRETURN;
11392 }
11393
11394 if (((p_cfg->i32frameRateInfo + p_cfg->i32frameRateDenominator - 1) /
11396 {
11397 ni_strncpy(p_param_err, max_err_len, "Invalid i32frameRateInfo: too big", max_err_len - 1);
11398 param_ret = NI_RETCODE_PARAM_ERROR_FRATE;
11399 LRETURN;
11400 }
11401
11402 if (p_cfg->i32bitRate <=
11403 ((p_cfg->i32frameRateInfo + p_cfg->i32frameRateDenominator - 1) / p_cfg->i32frameRateDenominator))
11404 {
11405 ni_strncpy(p_param_err, max_err_len, "Invalid i32bitRate: smaller than or equal to frame rate", max_err_len - 1);
11406 param_ret = NI_RETCODE_PARAM_ERROR_BRATE;
11407 LRETURN;
11408 }
11409
11410 if (p_cfg->i32bitRate > NI_MAX_BITRATE)
11411 {
11412 ni_strncpy(p_param_err, max_err_len, "Invalid i32bitRate: too big", max_err_len - 1);
11413 param_ret = NI_RETCODE_PARAM_ERROR_BRATE;
11414 LRETURN;
11415 }
11416
11417 if (p_cfg->i32bitRate < NI_MIN_BITRATE )
11418 {
11419 ni_strncpy(p_param_err, max_err_len, "Invalid i32bitRate: too low", max_err_len - 1);
11420 param_ret = NI_RETCODE_PARAM_ERROR_BRATE;
11421 LRETURN;
11422 }
11423
11425 {
11426 ni_strncpy(p_param_err, max_err_len, "Invalid Picture Width: too small", max_err_len - 1);
11428 LRETURN;
11429 }
11430
11432 {
11433 ni_strncpy(p_param_err, max_err_len, "Invalid Picture Width: too big", max_err_len - 1);
11435 LRETURN;
11436 }
11437
11439 {
11440 ni_strncpy(p_param_err, max_err_len, "Invalid Picture Height: too small", max_err_len - 1);
11442 LRETURN;
11443 }
11444
11446 {
11447 ni_strncpy(p_param_err, max_err_len, "Invalid Picture Height: too big", max_err_len - 1);
11449 LRETURN;
11450 }
11451
11452 if (p_cfg->ui32cropWidth || p_cfg->ui32cropHeight)
11453 {
11454 // check cropping width & height are both non-zero
11455 if (!p_cfg->ui32cropWidth || !p_cfg->ui32cropHeight)
11456 {
11457 snprintf(p_param_err, max_err_len, "Invalid Crop Width x Height (%u x %u): both need to be specified",
11458 p_cfg->ui32cropWidth, p_cfg->ui32cropHeight);
11459 param_ret = NI_RETCODE_INVALID_PARAM;
11460 LRETURN;
11461 }
11462 // check cropping width & height are even
11463 if ((p_cfg->ui32cropWidth % 2) || (p_cfg->ui32cropHeight % 2))
11464 {
11465 snprintf(p_param_err, max_err_len, "Invalid Crop Width x Height (%u x %uu): must be even",
11466 p_cfg->ui32cropWidth, p_cfg->ui32cropHeight);
11467 param_ret = NI_RETCODE_INVALID_PARAM;
11468 LRETURN;
11469 }
11470 // check cropping width & height meet resoultion constraint (including AV1 max resoultion)
11471 if (p_cfg->ui32cropWidth < NI_MIN_WIDTH)
11472 {
11473 snprintf(p_param_err, max_err_len, "Invalid Crop Width: less than %d",
11474 NI_MIN_WIDTH);
11476 LRETURN;
11477 }
11478 if (p_cfg->ui32cropHeight < NI_MIN_HEIGHT)
11479 {
11480 snprintf(p_param_err, max_err_len, "Invalid Crop Height: less than %d",
11483 LRETURN;
11484 }
11485 if (p_cfg->ui32cropWidth > NI_PARAM_MAX_WIDTH)
11486 {
11487 snprintf(p_param_err, max_err_len, "Invalid Crop Width: exceeds %d",
11490 LRETURN;
11491 }
11493 {
11494 snprintf(p_param_err, max_err_len, "Invalid Crop Height: exceeds %d",
11497 LRETURN;
11498 }
11500 {
11501 snprintf(p_param_err, max_err_len, "Invalid Crop Width x Height: exceeds %d",
11504 LRETURN;
11505 }
11506
11507 if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
11508 {
11510 {
11511 snprintf(p_param_err, max_err_len, "Invalid Crop Width: exceeds %d",
11514 LRETURN;
11515 }
11517 {
11518 snprintf(p_param_err, max_err_len, "Invalid Crop Height: exceeds %d",
11521 LRETURN;
11522 }
11524 {
11525 snprintf(p_param_err, max_err_len, "Invalid Crop Width x Height: exceeds %d",
11528 LRETURN;
11529 }
11530 }
11531
11532 // check cropping horOffset & verOffset are even
11533 if ((p_cfg->ui32horOffset % 2) || (p_cfg->ui32verOffset % 2))
11534 {
11535 snprintf(p_param_err, max_err_len, "Invalid Crop horOffset %u and/or verOffset %u: must be even",
11536 p_cfg->ui32horOffset, p_cfg->ui32verOffset);
11537 param_ret = NI_RETCODE_INVALID_PARAM;
11538 LRETURN;
11539 }
11540
11541 if (p_src->source_width < (int)(p_cfg->ui32horOffset + p_cfg->ui32cropWidth))
11542 {
11543 snprintf(p_param_err, max_err_len, "Invalid Crop Width: offset %u + crop width %u too big > %d",
11544 p_cfg->ui32horOffset, p_cfg->ui32cropWidth, p_src->source_width);
11546 LRETURN;
11547 }
11548 if (p_src->source_height < (int)(p_cfg->ui32verOffset + p_cfg->ui32cropHeight))
11549 {
11550 snprintf(p_param_err, max_err_len, "Invalid Crop Height: offset %u + crop height %u too big > %d",
11551 p_cfg->ui32verOffset, p_cfg->ui32cropHeight, p_src->source_height);
11553 LRETURN;
11554 }
11555 if (p_enc->roi_enable)
11556 {
11557 snprintf(p_param_err, max_err_len, "roiEnable must disabled when Crop Width > 0 || Crop Height > 0");
11558 param_ret = NI_RETCODE_INVALID_PARAM;
11559 LRETURN;
11560 }
11561 }
11562 else // check source width / height meet AV1 max resoultion constraint if cropping not specified
11563 {
11564 if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
11565 {
11567 {
11568 snprintf(p_param_err, max_err_len, "Invalid Picture Width: exceeds %d",
11571 LRETURN;
11572 }
11574 {
11575 snprintf(p_param_err, max_err_len, "Invalid Picture Height: exceeds %d",
11578 LRETURN;
11579 }
11580 if (p_src->source_width * p_src->source_height > NI_PARAM_AV1_MAX_AREA)
11581 {
11582 snprintf(p_param_err, max_err_len, "Invalid Picture Width x Height: exceeds %d",
11585 LRETURN;
11586 }
11587 }
11588 }
11589
11591 {
11592 ni_strncpy(p_param_err, max_err_len, "Invalid input planar format: out of range", max_err_len - 1);
11593 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
11594 LRETURN;
11595 }
11597 {
11599 "68") < 0)
11600 {
11601 ni_strncpy(p_param_err, max_err_len, "Invalid input planar format for device with FW api version < 6.8",
11602 max_err_len - 1);
11604 LRETURN;
11605 }
11606 if (p_ctx->auto_dl_handle)
11607 {
11608 ni_strncpy(p_param_err, max_err_len, "Invalid Encoder Selected: Tiled format must be on same device",
11609 max_err_len - 1);
11611 LRETURN;
11612 }
11613 if (p_src->source_height % 4 != 0)
11614 {
11615 ni_strncpy(p_param_err, max_err_len,
11616 "Invalid Picture Height: tiled format only supports "
11617 "multiples of 4",
11618 max_err_len - 1);
11620 LRETURN;
11621 }
11622 if (p_src->source_width % 4 != 0)
11623 {
11624 ni_strncpy(p_param_err, max_err_len,
11625 "Invalid Picture Width: tiled format only supports "
11626 "multiples of 4",
11627 max_err_len - 1);
11629 LRETURN;
11630 }
11631 }
11632
11633 if (p_cfg->ui8PixelFormat == NI_PIX_FMT_RGBA ||
11634 p_cfg->ui8PixelFormat == NI_PIX_FMT_BGRA ||
11635 p_cfg->ui8PixelFormat == NI_PIX_FMT_ABGR ||
11637 {
11638 if (p_src->zerocopy_mode == 0)
11639 {
11640 ni_strncpy(p_param_err, max_err_len, "zeroCopyMode must not be disabled for RGBA / BGRA / ABGR / ARGB pixel formats", max_err_len - 1);
11641 param_ret = NI_RETCODE_INVALID_PARAM;
11642 LRETURN;
11643 }
11644 if (p_cfg->ui8PixelFormat == NI_PIX_FMT_RGBA ||
11646 {
11648 "6Y") < 0)
11649 {
11650 ni_strncpy(p_param_err, max_err_len, "RGBA / BGRA pixel formats not supported on device with FW api version < 6.Y",
11651 max_err_len - 1);
11653 LRETURN;
11654 }
11655 }
11656 }
11657 else if (p_cfg->ui8PixelFormat != NI_PIX_FMT_YUV420P &&
11659 p_cfg->ui8PixelFormat != NI_PIX_FMT_NV12 &&
11663 {
11664 snprintf(p_param_err, max_err_len, "Unsupported pixel format %d in encoder", p_cfg->ui8PixelFormat);
11665 param_ret = NI_RETCODE_INVALID_PARAM;
11666 LRETURN;
11667 }
11668
11669 if (p_src->ddr_priority_mode >= 0)
11670 {
11672 "6e") < 0)
11673 {
11674 ni_strncpy(p_param_err, max_err_len, "ddr_priority_mode not supported on device with FW api version < 6.e",
11675 max_err_len - 1);
11677 LRETURN;
11678 }
11679 }
11680
11681 if (p_src->cfg_enc_params.level_idc)
11682 {
11683 if (NI_RETCODE_SUCCESS !=
11684 ni_check_level(p_src->cfg_enc_params.level_idc, p_ctx->codec_format, &level_index))
11685 {
11686 ni_strncpy(p_param_err, max_err_len, "Invalid Encoder Level: out of range", max_err_len - 1);
11687 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
11688 LRETURN;
11689 }
11690
11691 param_ret = ni_check_level_tier_compliance(
11692 p_src->cfg_enc_params.level_idc, p_ctx, p_cfg, p_src, p_param_err, p_param_warn, max_err_len, &warning, level_index);
11693 if(param_ret != NI_RETCODE_SUCCESS)
11694 {
11695 LRETURN;
11696 }
11697 }
11698
11699 if ((p_src->cfg_enc_params.intra_mb_refresh_mode < 0 ||
11703 {
11704 ni_strncpy(p_param_err, max_err_len, "Invalid intra_mb_refresh_mode: out of range",
11705 max_err_len - 1);
11706 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
11707 LRETURN;
11708 }
11709
11710 if (!QUADRA)
11711 {
11713 {
11715 {
11716 ni_strncpy(p_param_err, max_err_len, "Invalid custom GOP paramaters: custom_gop_size too small", max_err_len - 1);
11718 LRETURN;
11719 }
11722 {
11723 ni_strncpy(p_param_err, max_err_len, "Invalid custom GOP paramaters: custom_gop_size too big", max_err_len - 1);
11725 LRETURN;
11726 }
11727 }
11728 }
11729 else // QUADRA
11730 {
11732 {
11734 {
11735 ni_strncpy(p_param_err, max_err_len,
11736 "Invalid custom GOP paramaters: custom gop size must > 0",
11737 max_err_len - 1);
11739 LRETURN;
11740 }
11741 }
11743 {
11746 {
11747 ni_strncpy(p_param_err, max_err_len,
11748 "Invalid custom GOP paramaters: selected gopPresetIdx is "
11749 "not compatible with custom gop",
11750 max_err_len - 1);
11752 LRETURN;
11753 }
11755 {
11756 ni_strncpy(p_param_err, max_err_len, "Invalid custom GOP paramaters: custom_gop_size too small", max_err_len - 1);
11758 LRETURN;
11759 }
11762 {
11763 ni_strncpy(p_param_err, max_err_len, "Invalid custom GOP paramaters: custom_gop_size too big", max_err_len - 1);
11765 LRETURN;
11766 }
11767
11768 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size; i++)
11769 {
11772 {
11773 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: poc_offset larger"
11774 " than GOP size", max_err_len - 1);
11776 LRETURN;
11777 }
11778 }
11779 }
11780
11781 if(p_cfg->ui8useLowDelayPocType != 0)
11782 {
11783 if (NI_CODEC_FORMAT_H264 != p_ctx->codec_format)
11784 {
11785 p_cfg->ui8useLowDelayPocType = 0;
11786 ni_strncpy(p_param_warn, max_err_len, "useLowDelayPocType is only supported for H.264. Change useLowDelayPocType to 0", max_err_len - 1);
11787 warning = NI_RETCODE_PARAM_WARN;
11788 }
11789 }
11790 if(p_cfg->niParamT408.entropy_coding_mode != 1)
11791 {
11792 if (NI_CODEC_FORMAT_H264 != p_ctx->codec_format)
11793 {
11794 ni_strncpy(p_param_err, max_err_len,
11795 "entropyCodingMode is only supported for H.264.",
11796 max_err_len - 1);
11798 LRETURN;
11799 }
11800 }
11801 if (p_cfg->ui8av1ErrResilientMode)
11802 {
11803 if (NI_CODEC_FORMAT_AV1 != p_ctx->codec_format)
11804 {
11805 ni_strncpy(p_param_err, max_err_len,
11806 "av1ErrorResilientMode is only supported for AV1.",
11807 max_err_len - 1);
11809 LRETURN;
11810 }
11811 }
11812 if (0 != p_src->enable_ai_enhance)
11813 {
11814 if (NI_CODEC_FORMAT_JPEG == p_ctx->codec_format)
11815 {
11816 snprintf(p_param_err, max_err_len, "%s is not supported for JPEG.",
11817 ((p_src->enable_ai_enhance == 2) ? "enableHVSPlus" : "enableAIEnhance"));
11819 LRETURN;
11820 }
11821 }
11822 if (-1 != p_cfg->ui32QLevel)
11823 {
11824 if (NI_CODEC_FORMAT_JPEG != p_ctx->codec_format)
11825 {
11826 ni_strncpy(p_param_err, max_err_len, "qLevel is only supported for JPEG.",
11827 max_err_len - 1);
11829 LRETURN;
11830 }
11831 }
11832
11833 if(p_cfg->ui8enableSSIM != 0)
11834 {
11836 "62") < 0 || NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
11837 {
11838 p_cfg->ui8enableSSIM = 0;
11839 ni_strncpy(p_param_warn, max_err_len, "enableSSIM only supported on device with FW api version < 6.2 "
11840 "and the encoder is not av1_ni_quadra_enc. Reported ssim will be 0.", max_err_len - 1);
11841 warning = NI_RETCODE_PARAM_WARN;
11842 }
11843 }
11844
11845 if (p_cfg->niParamT408.slice_mode || p_cfg->niParamT408.slice_arg)
11846 {
11848 {
11849 ni_strncpy(p_param_err, max_err_len, "sliceMode/sliceArg is only supported for H.264 or H.265.",
11850 max_err_len - 1);
11852 LRETURN;
11853 }
11854
11855 if (p_cfg->niParamT408.slice_mode)
11856 {
11857 int ctu_mb_size = (NI_CODEC_FORMAT_H264 == p_ctx->codec_format) ? 16 : 64;
11858 int max_num_ctu_mb_row = (p_src->source_height + ctu_mb_size - 1) / ctu_mb_size;
11859 if (p_cfg->niParamT408.slice_arg < 1 || p_cfg->niParamT408.slice_arg > max_num_ctu_mb_row ||
11861 {
11862 snprintf(p_param_err, max_err_len, "Invalid number of rows per slice: should be between 1 and %d",
11863 max_num_ctu_mb_row < NI_MAX_SLICE_SIZE ? max_num_ctu_mb_row : NI_MAX_SLICE_SIZE);
11865 LRETURN;
11866 }
11867 }
11868 }
11869 if (p_src->use_low_delay_poc_type)
11870 {
11871 if (NI_CODEC_FORMAT_H264 != p_ctx->codec_format)
11872 {
11873 ni_strncpy(p_param_err, max_err_len, "useLowDelayPocType is only supported for H.264.",
11874 max_err_len - 1);
11876 LRETURN;
11877 }
11878 }
11879
11880 if(p_cfg->ui8enableCompensateQp != 0)
11881 {
11882 if (ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6ru") < 0 ||
11883 NI_CODEC_FORMAT_AV1 == p_ctx->codec_format || p_cfg->ui16maxFrameSize == 0)
11884 {
11885 p_cfg->ui8enableCompensateQp = 0;
11886 ni_strncpy(p_param_warn, max_err_len, "ui8enableCompensateQp only supported when device with FW api version < 6rt "
11887 "and the encoder is not av1_ni_quadra_enc and ui16maxFrameSize > 0. Reported enableCompensateQp will be 0.", max_err_len - 1);
11888 warning = NI_RETCODE_PARAM_WARN;
11889 }
11890 }
11891
11892 if (p_cfg->ui8enableTimecode != 0)
11893 {
11894 if (NI_CODEC_FORMAT_H264 != p_ctx->codec_format)
11895 {
11896 p_cfg->ui8enableTimecode = 0;
11897 if (NI_CODEC_FORMAT_H265 == p_ctx->codec_format)
11898 {
11899 ni_strncpy(p_param_warn, max_err_len, "enableTimecode does not need to be set for H.265. Use ni_enc_insert_timecode API"
11900 "from libxcoder directly to insert time code SEI", max_err_len - 1);
11901 }
11902 else
11903 {
11904 ni_strncpy(p_param_warn, max_err_len, "enableTimecode not supported for the codec used. Forcing value to 0.", max_err_len - 1);
11905 }
11906 warning = NI_RETCODE_PARAM_WARN;
11907 }
11908 }
11909 }
11910
11911 if (QUADRA)
11912 {
11913 if (p_cfg->ui8LookAheadDepth != 0 || p_cfg->i8crf >= 0)
11914 {
11915 if ((1 == p_cfg->niParamT408.gop_preset_index && p_cfg->ui8LookAheadDepth != 0) ||
11916 3 == p_cfg->niParamT408.gop_preset_index ||
11917 7 == p_cfg->niParamT408.gop_preset_index ||
11918 10 == p_cfg->niParamT408.gop_preset_index ||
11919 15 == p_cfg->niParamT408.gop_preset_index)
11920 {
11921 ni_strncpy(p_param_err, max_err_len,
11922 "this gopPreset is not supported for lookahead and/or CRF",
11923 max_err_len - 1);
11925 LRETURN;
11926 }
11927
11929 {
11930 bool bIsgopLowdelay = true;
11931 // lookahead does not support gopLowDelay (all B-frames, encode in order) gop patterns
11932 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size;
11933 i++)
11934 {
11935 // check if all frames are B-frames
11937 {
11938 bIsgopLowdelay = false;
11939 break;
11940 }
11941 // check if all frames are encoded in display order
11942 if (p_cfg->niParamT408.custom_gop_params.pic_param[i].poc_offset != (i+1))
11943 {
11944 bIsgopLowdelay = false;
11945 break;
11946 }
11947 }
11948 if (bIsgopLowdelay)
11949 {
11950 ni_strncpy(p_param_err, max_err_len, "B-frames low delay custom gop is not supported for "
11951 "lookahead and/or CRF", max_err_len - 1);
11952 param_ret = NI_RETCODE_INVALID_PARAM;
11953 LRETURN;
11954 }
11955 }
11956
11957 if (p_enc->bitrateMode != -1)
11958 {
11959 ni_strncpy(p_param_err, max_err_len,
11960 "bitrateMode is invalid when lookahead is enabled (or in CRF mode)",
11961 max_err_len - 1);
11963 LRETURN;
11964 }
11965 }
11966
11967 if (p_cfg->ui8totalCuTreeDepth != 0)
11968 {
11969 if (p_cfg->ui8LookAheadDepth == 0 || p_cfg->ui8LookAheadDepth == 1)
11970 {
11971 ni_strncpy(p_param_err, max_err_len,
11972 "totalCuTreeDepth is invalid without lookahead",
11973 max_err_len - 1);
11975 LRETURN;
11976 }
11977
11978 if (p_cfg->ui8totalCuTreeDepth <= p_cfg->ui8LookAheadDepth)
11979 {
11980 ni_strncpy(p_param_warn, max_err_len, "totalCuTreeDepth does not take effects when its value <= lookahead depth", max_err_len - 1);
11981 warning = NI_RETCODE_PARAM_WARN;
11982 p_cfg->ui8totalCuTreeDepth = 0;
11983 }
11984 else
11985 {
11986 if (p_cfg->ui8multicoreJointMode != 0)
11987 {
11988 ni_strncpy(p_param_err, max_err_len,
11989 "totalCuTreeDepth is not supported in multicoreJointMode",
11990 max_err_len - 1);
11992 LRETURN;
11993 }
11994 }
11995 }
11996
11997 if (p_cfg->ui8qpScaleEnable != 0)
11998 {
11999 if (p_cfg->ui8LookAheadDepth == 0 || p_cfg->ui8LookAheadDepth == 1)
12000 {
12001 ni_strncpy(p_param_err, max_err_len,
12002 "qpScaleEnable is invalid without lookahead",
12003 max_err_len - 1);
12005 LRETURN;
12006 }
12007
12008 if (p_cfg->i8crf < 0)
12009 {
12010 ni_strncpy(p_param_err, max_err_len,
12011 "qpScaleEnable is only supported in CRF or Capped CRF modes",
12012 max_err_len - 1);
12013 param_ret = NI_RETCODE_INVALID_PARAM;
12014 LRETURN;
12015 }
12016
12017 if (p_cfg->ui8adaptiveCrfMode != 0)
12018 {
12019 ni_strncpy(p_param_err, max_err_len,
12020 "adaptiveCrfMode is invalid when qpScaleEnable",
12021 max_err_len - 1);
12022 param_ret = NI_RETCODE_INVALID_PARAM;
12023 LRETURN;
12024 }
12025 }
12026
12028 {
12029 // when gop_preset_index = -1 (default), gop pattern is decided by gopSize and gopLowdelay
12030 //p_cfg->ui8gopSize = 0;
12031 //p_cfg->ui8gopLowdelay = 0;
12032 }
12033 if (1 == p_cfg->niParamT408.gop_preset_index)
12034 {
12035 p_cfg->niParamT408.intra_period = 1;
12036 p_cfg->niParamT408.avcIdrPeriod = 1;
12037 p_cfg->ui8gopSize = 1;
12038 p_cfg->ui16gdrDuration = 0;
12039 }
12040 if (2 == p_cfg->niParamT408.gop_preset_index)
12041 {
12042 ni_strncpy(p_param_err, max_err_len,
12043 "gopPresetIdx 2 is obsolete, suggest to use gopPresetIdx 9 "
12044 "instead",
12045 max_err_len - 1);
12047 LRETURN;
12048 }
12049 if (3 == p_cfg->niParamT408.gop_preset_index)
12050 {
12051 p_cfg->ui8gopSize = 1;
12052 p_cfg->ui8gopLowdelay = 1;
12053 }
12054 if (4 == p_cfg->niParamT408.gop_preset_index)
12055 {
12056 p_cfg->ui8gopSize = 2;
12057 p_cfg->ui8gopLowdelay = 0;
12058 }
12059 if (5 == p_cfg->niParamT408.gop_preset_index)
12060 {
12061 p_cfg->ui8gopSize = 4;
12062 p_cfg->ui8gopLowdelay = 0;
12063 }
12064 if (6 == p_cfg->niParamT408.gop_preset_index)
12065 {
12066 ni_strncpy(p_param_err, max_err_len,
12067 "gopPresetIdx 6 is obsolete, suggest to use gopPresetIdx 7 "
12068 "instead",
12069 max_err_len - 1);
12071 LRETURN;
12072 }
12073 if (7 == p_cfg->niParamT408.gop_preset_index)
12074 {
12075 p_cfg->ui8gopSize = 4;
12076 p_cfg->ui8gopLowdelay = 1;
12077 }
12078 if (8 == p_cfg->niParamT408.gop_preset_index)
12079 {
12080 p_cfg->ui8gopSize = 8;
12081 p_cfg->ui8gopLowdelay = 0;
12082 }
12083 if (9 == p_cfg->niParamT408.gop_preset_index)
12084 {
12085 p_cfg->ui8gopSize = 1;
12086 p_cfg->ui8gopLowdelay = 0;
12087 }
12088 if (10 == p_cfg->niParamT408.gop_preset_index)
12089 {
12090 p_cfg->ui8gopSize = 4;
12091 p_cfg->ui8gopLowdelay = 0;
12092 }
12093 if (15 == p_cfg->niParamT408.gop_preset_index)
12094 {
12095 p_cfg->ui8gopSize = 16;
12096 p_cfg->ui8gopLowdelay = 0;
12097 }
12098
12099 if (p_cfg->ui8LookAheadDepth != 0
12100 || p_cfg->ui8bitrateMode == 1
12101 || p_cfg->ui32vbvMaxRate
12102 || p_cfg->ui32vbvMinRate
12103 || p_cfg->i8enableipRatio)
12104 {
12105 ni_log2(p_ctx, NI_LOG_DEBUG, "Force newRcEnable to 0 in 2-pass encode or in 1-pass average bitrate mode, with ipRatio, VbvMaxRate, or VbvMinRate\n");
12106 p_cfg->ui8NewRCEnable = 0;
12107 }
12108 else if (p_cfg->ui8NewRCEnable == 255)
12109 {
12110 if ((p_cfg->ui8gopSize > 1 || p_cfg->ui8gopSize == 0) && p_cfg->ui8gopLowdelay == 0)
12111 {
12112 ni_log2(p_ctx, NI_LOG_DEBUG, "Set newRcEnable to 0 in non low delay gop preset\n");
12113 p_cfg->ui8NewRCEnable = 0;
12114 }
12115 else if (p_cfg->i32spatialLayerBitrate[0] > 0)
12116 {
12117 ni_log2(p_ctx, NI_LOG_DEBUG, "Set newRcEnable to 0 in spatial layer separated rate control mode\n");
12118 p_cfg->ui8NewRCEnable = 0;
12119 }
12120 else if (p_cfg->niParamT408.intra_period == 1 || p_cfg->niParamT408.avcIdrPeriod == 1)
12121 {
12122 ni_log2(p_ctx, NI_LOG_DEBUG, "Set newRcEnable to 0 in intra only mode\n");
12123 p_cfg->ui8NewRCEnable = 0;
12124 }
12125 }
12126
12127 if ((p_cfg->ui8stillImageDetectLevel != 0 || p_cfg->ui8sceneChangeDetectLevel != 0) &&
12129 {
12130 ni_strncpy(p_param_warn, max_err_len, "StillImageDetect or SceneChangeDetect only support gopPresetIdx=9 with FW > 6rm\n", max_err_len - 1);
12131 warning = NI_RETCODE_PARAM_WARN;
12132 p_cfg->ui8stillImageDetectLevel = 0;
12133 p_cfg->ui8sceneChangeDetectLevel = 0;
12134 }
12135
12136 if (p_cfg->ui8spatialLayersMinusOne > 0 || p_cfg->i32spatialLayerBitrate[0] > 0)
12137 {
12139 {
12140 ni_strncpy(p_param_err, max_err_len,
12141 "currently do not support gop preset in multi spatial layers encode or spatial layer separated rate control mode",
12142 max_err_len - 1);
12144 LRETURN;
12145 }
12146 p_cfg->ui8gopSize = p_cfg->ui8spatialLayersMinusOne + 1;
12147 p_cfg->ui8gopLowdelay = 0;
12148 }
12149
12150 if (p_cfg->ui8spatialLayersRefBaseLayer != 0)
12151 {
12152 if (p_cfg->ui8spatialLayersMinusOne == 0)
12153 {
12154 ni_strncpy(p_param_err, max_err_len,
12155 "higher spatial layers referencing base layer is only supported in multi spatial layers encode",
12156 max_err_len - 1);
12158 LRETURN;
12159 }
12160 }
12161
12162 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
12163 {
12164 if (p_cfg->i32spatialLayerBitrate[i] == 0)
12165 {
12166 break;
12167 }
12168 }
12169 if (i > 0)
12170 {
12171 if (p_cfg->ui8spatialLayersMinusOne + 1 != i)
12172 {
12173 ni_strncpy(p_param_err, max_err_len, "number of values specified in spatialLayerBitrate must match the total number of spatial layers", max_err_len - 1);
12174 param_ret = NI_RETCODE_INVALID_PARAM;
12175 LRETURN;
12176 }
12177 if (p_cfg->ui8multicoreJointMode != 0)
12178 {
12181 "6sD") < 0)
12182 {
12183 ni_strncpy(p_param_err, max_err_len, "spatialLayerBitrate is not supported in multicoreJointMode for FW api version < 6sD", max_err_len - 1);
12185 LRETURN;
12186 }
12187 }
12188 }
12189
12190 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
12191 {
12192 if (p_cfg->ui8av1OpLevel[i] == 0)
12193 {
12194 break;
12195 }
12196 else
12197 {
12198 if (NI_RETCODE_SUCCESS !=
12199 ni_check_level((int)p_cfg->ui8av1OpLevel[i], p_ctx->codec_format, &level_index))
12200 {
12201 ni_strncpy(p_param_err, max_err_len, "Invalid av1OpLevel: out of range", max_err_len - 1);
12202 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
12203 LRETURN;
12204 }
12205
12206 param_ret = ni_check_level_tier_compliance(
12207 p_cfg->ui8av1OpLevel[i], p_ctx, p_cfg, p_src, p_param_err, p_param_warn, max_err_len, &warning, level_index);
12208 if(param_ret != NI_RETCODE_SUCCESS)
12209 {
12210 LRETURN;
12211 }
12212 }
12213 }
12214 if (i > 0)
12215 {
12216 if (p_cfg->niParamT408.level != 0)
12217 {
12218 ni_strncpy(p_param_err, max_err_len, "av1OpLevel and level cannot be both specified", max_err_len - 1);
12219 param_ret = NI_RETCODE_INVALID_PARAM;
12220 LRETURN;
12221 }
12222
12223 if (p_cfg->ui8spatialLayersMinusOne + 1 != i)
12224 {
12225 ni_strncpy(p_param_err, max_err_len, "number of values specified in av1OpLevel must match the total number of spatial layers", max_err_len - 1);
12226 param_ret = NI_RETCODE_INVALID_PARAM;
12227 LRETURN;
12228 }
12229 }
12230
12231 if (p_cfg->ui8crfMaxIframeEnable > 0)
12232 {
12233 if (p_cfg->i8crf < 0 || p_cfg->i32vbvBufferSize == 0 || p_cfg->ui8LookAheadDepth == 0)
12234 {
12235 ni_strncpy(p_param_err, max_err_len,
12236 "crfMaxIframeEnable is only supported in Capped CRF mode with lookahead enabled",
12237 max_err_len - 1);
12238 param_ret = NI_RETCODE_INVALID_PARAM;
12239 LRETURN;
12240 }
12241 }
12242 }
12243
12244 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
12245 {
12246 if (!QUADRA)
12247 {
12248 if (10 == p_ctx->src_bit_depth)
12249 {
12250 if (p_cfg->niParamT408.profile != 5)
12251 {
12252 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 5 (high10)",
12253 max_err_len - 1);
12254 param_ret = NI_RETCODE_INVALID_PARAM;
12255 LRETURN;
12256 }
12257 }
12258 else
12259 {
12260 if (p_cfg->niParamT408.profile < 1 || p_cfg->niParamT408.profile > 5)
12261 {
12262 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (baseline), 2 (main),"
12263 " 3 (extended), 4 (high), or 5 (high10)", max_err_len - 1);
12264 param_ret = NI_RETCODE_INVALID_PARAM;
12265 LRETURN;
12266 }
12267 }
12268 if (1 == p_cfg->niParamT408.profile &&
12269 ! (0 == p_cfg->niParamT408.gop_preset_index ||
12270 1 == p_cfg->niParamT408.gop_preset_index ||
12271 2 == p_cfg->niParamT408.gop_preset_index ||
12272 6 == p_cfg->niParamT408.gop_preset_index))
12273 {
12274 ni_strncpy(p_param_err, max_err_len, "Invalid gopPresetIdx for H.264 baseline profile:"
12275 " must be 1, 2, 6 or 0 (custom with no B frames)", max_err_len - 1);
12276 param_ret = NI_RETCODE_INVALID_PARAM;
12277 LRETURN;
12278 }
12279 if (1 == p_cfg->niParamT408.profile &&
12281 {
12282 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size;
12283 i++)
12284 {
12286 {
12287 ni_strncpy(p_param_err, max_err_len, "H.264 baseline profile: custom GOP can not "
12288 "have B frames", max_err_len - 1);
12289 param_ret = NI_RETCODE_INVALID_PARAM;
12290 LRETURN;
12291 }
12292 }
12293 }
12294 }
12295 else // QUADRA
12296 {
12297 if (p_cfg->niParamT408.profile < 1 || p_cfg->niParamT408.profile > 5 || p_cfg->niParamT408.profile == 3)
12298 {
12299 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (baseline), 2 (main),"
12300 " 4 (high), or 5 (high10)", max_err_len - 1);
12301 param_ret = NI_RETCODE_INVALID_PARAM;
12302 LRETURN;
12303 }
12304 if (10 == p_ctx->src_bit_depth && p_cfg->niParamT408.profile != 5)
12305 {
12306 ni_strncpy(p_param_warn, max_err_len, "AVC Baseline/Main/High Profile do not support 10-bit, auto convert to 8-bit", max_err_len - 1);
12307 warning = NI_RETCODE_PARAM_WARN;
12308 }
12309 if (1 == p_cfg->niParamT408.profile)
12310 {
12312 {
12313 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size; i++)
12314 {
12316 {
12317 ni_strncpy(p_param_err, max_err_len, "H.264 baseline profile: custom GOP can not "
12318 "have B frames", max_err_len - 1);
12319 param_ret = NI_RETCODE_INVALID_PARAM;
12320 LRETURN;
12321 }
12322 }
12323 } else if (((p_cfg->ui8gopSize != 1 || p_cfg->ui8gopLowdelay)) &&
12324 (p_cfg->niParamT408.intra_period != 1) &&
12326 {
12328 p_cfg->ui8gopSize != 0 ||
12329 p_cfg
12330 ->ui8gopLowdelay) // if gopSize is 0 (default / adapative gop), autoset to 1
12331 {
12332 ni_strncpy(p_param_err, max_err_len,
12333 "Must use gopPresetIdx 1,9,10 (no "
12334 "B frames) for profile 1",
12335 max_err_len - 1);
12336 param_ret = NI_RETCODE_INVALID_PARAM;
12337 LRETURN;
12338 }
12339 p_cfg->ui8gopSize = 1; //autoset to 1
12340 }
12341 }
12342 if (p_cfg->niParamT408.tier)
12343 {
12344 ni_strncpy(p_param_err, max_err_len, "Tier is not supported for H.264", max_err_len - 1);
12345 param_ret = NI_RETCODE_INVALID_PARAM;
12346 LRETURN;
12347 }
12348 if (p_cfg->ui8spatialLayersMinusOne > 0)
12349 {
12350 ni_strncpy(p_param_err, max_err_len,
12351 "spatialLayers is not supported for h.264 encode",
12352 max_err_len - 1);
12354 LRETURN;
12355 }
12356 if (p_cfg->ui8disableAv1TimingInfo != 0)
12357 {
12358 ni_strncpy(p_param_err, max_err_len, "disableAv1TimingInfo is not supported for h.264",
12359 max_err_len - 1);
12361 LRETURN;
12362 }
12363 if (p_cfg->ui8av1OpLevel[0] != 0)
12364 {
12365 ni_strncpy(p_param_err, max_err_len, "av1OpLevel is not supported for h.264",
12366 max_err_len - 1);
12368 LRETURN;
12369 }
12370 }
12371 }
12372 else if (NI_CODEC_FORMAT_H265 == p_ctx->codec_format)
12373 {
12374 if (!QUADRA)
12375 {
12376 if (10 == p_ctx->src_bit_depth)
12377 {
12378 if (p_cfg->niParamT408.profile != 2)
12379 {
12380 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 2 (main10)",
12381 max_err_len - 1);
12382 param_ret = NI_RETCODE_INVALID_PARAM;
12383 LRETURN;
12384 }
12385 }
12386 else
12387 {
12388 if (p_cfg->niParamT408.profile < 1 || p_cfg->niParamT408.profile > 2)
12389 {
12390 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (main) or 2 (main10)",
12391 max_err_len - 1);
12392 param_ret = NI_RETCODE_INVALID_PARAM;
12393 LRETURN;
12394 }
12395 }
12396 }
12397 else // QUADRA
12398 {
12399 if (p_cfg->niParamT408.profile < 1 || p_cfg->niParamT408.profile > 2)
12400 {
12401 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (main) or 2 (main10)",
12402 max_err_len - 1);
12403 param_ret = NI_RETCODE_INVALID_PARAM;
12404 LRETURN;
12405 }
12406 if (10 == p_ctx->src_bit_depth && p_cfg->niParamT408.profile != 2)
12407 {
12408 ni_strncpy(p_param_warn, max_err_len, "HEVC Main Profile does not support 10-bit, auto convert to 8-bit", max_err_len - 1);
12409 warning = NI_RETCODE_PARAM_WARN;
12410 }
12411 if (p_cfg->ui8spatialLayersMinusOne > 0)
12412 {
12413 ni_strncpy(p_param_err, max_err_len,
12414 "spatialLayers is not supported for h.265 encode",
12415 max_err_len - 1);
12417 LRETURN;
12418 }
12419 if (p_cfg->ui8disableAv1TimingInfo != 0)
12420 {
12421 ni_strncpy(p_param_err, max_err_len, "disableAv1TimingInfo is not supported for h.265",
12422 max_err_len - 1);
12424 LRETURN;
12425 }
12426 if (p_cfg->ui8av1OpLevel[0] != 0)
12427 {
12428 ni_strncpy(p_param_err, max_err_len, "av1OpLevel is not supported for h.265",
12429 max_err_len - 1);
12431 LRETURN;
12432 }
12433 if (p_enc->getBitstreamFeatures)
12434 {
12435 ni_strncpy(p_param_err, max_err_len, "getBitstreamFeatures is not supported for h.265 encoder",
12436 max_err_len - 1);
12438 LRETURN;
12439 }
12440 }
12441 } else if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
12442 {
12444 {
12445 ni_strncpy(p_param_err, max_err_len, "TuneBframeVisual MEDIUM is not supported for AV1", max_err_len - 1);
12446 param_ret = NI_RETCODE_INVALID_PARAM;
12447 LRETURN;
12448 }
12449 if (p_cfg->niParamT408.profile != 1)
12450 {
12451 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (main)",
12452 max_err_len - 1);
12453 param_ret = NI_RETCODE_INVALID_PARAM;
12454 LRETURN;
12455 }
12456 if (p_cfg->niParamT408.level) // 0 means auto level
12457 {
12458 if (p_cfg->niParamT408.level < 20)
12459 {
12460 p_cfg->niParamT408.level = 20;
12461 ni_strncpy(p_param_warn, max_err_len,
12462 "AV1 level < 2.0 is not supported, change to level 2.0",
12463 max_err_len - 1);
12464 warning = NI_RETCODE_PARAM_WARN;
12465 } else if (p_cfg->niParamT408.level > 63)
12466 {
12467 p_cfg->niParamT408.level = 63;
12468 ni_strncpy(p_param_warn, max_err_len,
12469 "AV1 level > 6.3 is not supported, change to level 6.3",
12470 max_err_len - 1);
12471 warning = NI_RETCODE_PARAM_WARN;
12472 }
12473 }
12474
12475 if (p_cfg->niParamT408.conf_win_top != 0)
12476 {
12478 0;
12479 ni_strncpy(p_param_warn, max_err_len, "confWinTop is not supported in AV1",
12480 max_err_len - 1);
12481 warning = NI_RETCODE_PARAM_WARN;
12482 }
12483 if (p_cfg->niParamT408.conf_win_bottom != 0)
12484 {
12487 ni_strncpy(p_param_warn, max_err_len, "confWinBottom is not supported in AV1",
12488 max_err_len - 1);
12489 warning = NI_RETCODE_PARAM_WARN;
12490 }
12491 if (p_cfg->niParamT408.conf_win_left != 0)
12492 {
12493 p_cfg->niParamT408.conf_win_left =
12494 p_src->cfg_enc_params.conf_win_left = 0;
12495 ni_strncpy(p_param_warn, max_err_len, "confWinLeft is not supported in AV1",
12496 max_err_len - 1);
12497 warning = NI_RETCODE_PARAM_WARN;
12498 }
12499 if (p_cfg->niParamT408.conf_win_right != 0)
12500 {
12502 p_src->cfg_enc_params.conf_win_right = 0;
12503 ni_strncpy(p_param_warn, max_err_len, "confWinRight is not supported in AV1",
12504 max_err_len - 1);
12505 warning = NI_RETCODE_PARAM_WARN;
12506 }
12507 if (p_cfg->ui8hdr10_enable)
12508 {
12509 ni_strncpy(p_param_err, max_err_len,
12510 "masterDisplay not supported for AV1",
12511 max_err_len - 1);
12512 warning = NI_RETCODE_PARAM_WARN;
12513 }
12514 if (p_cfg->ui8hrdEnable)
12515 {
12516 ni_strncpy(p_param_err, max_err_len, "hrdEnable is not supported on av1 encoder",
12517 max_err_len - 1);
12519 LRETURN;
12520 }
12521 if (p_cfg->ui8EnableAUD)
12522 {
12523 ni_strncpy(p_param_err, max_err_len, "enableAUD is not supported on av1 encoder",
12524 max_err_len - 1);
12526 LRETURN;
12527 }
12528 if (p_cfg->ui8HDR10CLLEnable)
12529 {
12530 ni_strncpy(p_param_err, max_err_len, "maxCLL is not supported on av1 encoder",
12531 max_err_len - 1);
12533 LRETURN;
12534 }
12535 if (p_cfg->ui8repeatHeaders)
12536 {
12537 ni_strncpy(p_param_err, max_err_len, "repeatHeaders is not supported on av1 encoder",
12538 max_err_len - 1);
12539 warning = NI_RETCODE_PARAM_WARN;
12540 }
12541 if (p_cfg->ui8enableSSIM)
12542 {
12543 ni_strncpy(p_param_err, max_err_len, "enableSSIM is not supported on av1 encoder",
12544 max_err_len - 1);
12546 LRETURN;
12547 }
12548 if (p_cfg->ui8EnableRdoQuant)
12549 {
12550 ni_strncpy(p_param_err, max_err_len, "EnableRdoQuant is not supported on av1 encoder",
12551 max_err_len - 1);
12553 LRETURN;
12554 }
12555 if (p_cfg->ui8fillerEnable)
12556 {
12557 ni_strncpy(p_param_err, max_err_len, "fillerEnable is not supported on av1 encoder",
12558 max_err_len - 1);
12560 LRETURN;
12561 }
12562 if (p_cfg->i8ppsInitQp)
12563 {
12564 ni_strncpy(p_param_err, max_err_len, "ppsInitQp is not supported for av1 encoder",
12565 max_err_len - 1);
12567 LRETURN;
12568 }
12569 if (p_cfg->ui8vbvBufferReencode && p_cfg->ui8multicoreJointMode)
12570 {
12571 ni_strncpy(p_param_err, max_err_len, "vbvBufferReencode is not supported for av1 multicoreJointMode", max_err_len - 1);
12573 LRETURN;
12574 }
12575 if (p_enc->getBitstreamFeatures)
12576 {
12577 ni_strncpy(p_param_err, max_err_len, "getBitstreamFeatures is not supported for av1 encoder",
12578 max_err_len - 1);
12580 LRETURN;
12581 }
12582 } else if (NI_CODEC_FORMAT_JPEG == p_ctx->codec_format)
12583 {
12584 if (p_cfg->ui32cropWidth || p_cfg->ui32cropHeight || p_cfg->ui32horOffset || p_cfg->ui32verOffset)
12585 {
12586 ni_strncpy(p_param_err, max_err_len, "crop Parameters not supported for JPEG", max_err_len - 1);
12588 LRETURN;
12589 }
12590 if (p_cfg->niParamT408.tier)
12591 {
12592 ni_strncpy(p_param_err, max_err_len, "Tier is not supported for JPEG", max_err_len - 1);
12594 LRETURN;
12595 }
12596 if (p_cfg->ui8tuneBframeVisual)
12597 {
12598 ni_strncpy(p_param_err, max_err_len, "TuneBframeVisual is not supported for JPEG", max_err_len - 1);
12600 LRETURN;
12601 }
12602 if (p_cfg->ui8hdr10_enable)
12603 {
12604 ni_strncpy(p_param_err, max_err_len,
12605 "masterDisplay not supported for jpeg",
12606 max_err_len - 1);
12607 warning = NI_RETCODE_PARAM_WARN;
12608 }
12609 if (p_cfg->niParamT408.conf_win_top != 0)
12610 {
12611 ni_strncpy(p_param_err, max_err_len, "confWinTop is not supported in jpeg",
12612 max_err_len - 1);
12614 LRETURN;
12615 }
12616 if (p_cfg->niParamT408.conf_win_bottom != 0)
12617 {
12618 ni_strncpy(p_param_err, max_err_len, "confWinBottom is not supported in jpeg",
12619 max_err_len - 1);
12621 LRETURN;
12622 }
12623 if (p_cfg->niParamT408.conf_win_left != 0)
12624 {
12625 ni_strncpy(p_param_err, max_err_len, "confWinLeft is not supported in jpeg",
12626 max_err_len - 1);
12628 LRETURN;
12629 }
12630 if (p_cfg->niParamT408.conf_win_right != 0)
12631 {
12632 ni_strncpy(p_param_err, max_err_len, "confWinRight is not supported in jpeg",
12633 max_err_len - 1);
12635 LRETURN;
12636 }
12637 if (p_cfg->ui8hrdEnable)
12638 {
12639 ni_strncpy(p_param_err, max_err_len, "hrdEnable is not supported on jpeg encoder",
12640 max_err_len - 1);
12642 LRETURN;
12643 }
12644 if (p_cfg->ui8EnableAUD)
12645 {
12646 ni_strncpy(p_param_err, max_err_len, "enableAUD is not supported on jpeg encoder",
12647 max_err_len - 1);
12649 LRETURN;
12650 }
12651 if (p_cfg->ui8repeatHeaders)
12652 {
12653 ni_strncpy(p_param_err, max_err_len, "repeatHeaders is not supported on jpeg encoder",
12654 max_err_len - 1);
12656 LRETURN;
12657 }
12659 {
12660 ni_strncpy(p_param_err, max_err_len, "prefTRC is not supported on jpeg encoder",
12661 max_err_len - 1);
12663 LRETURN;
12664 }
12665 if (p_cfg->ui8HDR10CLLEnable)
12666 {
12667 ni_strncpy(p_param_err, max_err_len, "maxCLL is not supported on jpeg encoder",
12668 max_err_len - 1);
12670 LRETURN;
12671 }
12672 if (p_cfg->ui8colorPrimaries != 2)
12673 {
12674 ni_strncpy(p_param_err, max_err_len, "colorPri is not supported on jpeg encoder",
12675 max_err_len - 1);
12677 LRETURN;
12678 }
12679 if (p_cfg->ui8colorTrc != 2)
12680 {
12681 ni_strncpy(p_param_err, max_err_len, "colorTrc is not supported on jpeg encoder",
12682 max_err_len - 1);
12684 LRETURN;
12685 }
12686 if (p_cfg->ui8colorSpace != 2)
12687 {
12688 ni_strncpy(p_param_err, max_err_len, "colorSpc is not supported on jpeg encoder",
12689 max_err_len - 1);
12691 LRETURN;
12692 }
12693 if (p_src->sar_num)
12694 {
12695 ni_strncpy(p_param_err, max_err_len, "sarNum is not supported on jpeg encoder",
12696 max_err_len - 1);
12698 LRETURN;
12699 }
12700 if (p_src->sar_denom != 1)
12701 {
12702 ni_strncpy(p_param_err, max_err_len, "sarDenom is not supported on jpeg encoder",
12703 max_err_len - 1);
12705 LRETURN;
12706 }
12707 if (p_src->video_full_range_flag != -1)
12708 {
12709 ni_strncpy(p_param_err, max_err_len,
12710 "videoFullRangeFlag is not supported on jpeg encoder",
12711 max_err_len - 1);
12713 LRETURN;
12714 }
12715 if (p_cfg->ui8temporalLayersEnable)
12716 {
12717 ni_strncpy(p_param_err, max_err_len,
12718 "temporalLayersEnable is not supported on jpeg encoder",
12719 max_err_len - 1);
12721 LRETURN;
12722 }
12723 if (p_cfg->ui8spatialLayersMinusOne > 0)
12724 {
12725 ni_strncpy(p_param_err, max_err_len,
12726 "spatialLayers is not supported for jpeg encode",
12727 max_err_len - 1);
12729 LRETURN;
12730 }
12731 if (p_cfg->ui8LowDelay)
12732 {
12733 ni_strncpy(p_param_err, max_err_len, "LowDelay is not supported on jpeg encoder",
12734 max_err_len - 1);
12736 LRETURN;
12737 }
12738 if (p_cfg->ui8rdoLevel)
12739 {
12740 ni_strncpy(p_param_err, max_err_len, "rdoLevel is not supported on jpeg encoder",
12741 max_err_len - 1);
12743 LRETURN;
12744 }
12745 if (p_cfg->ui8EnableRdoQuant)
12746 {
12747 ni_strncpy(p_param_err, max_err_len, "EnableRdoQuant is not supported on jpeg encoder",
12748 max_err_len - 1);
12750 LRETURN;
12751 }
12752 if (p_cfg->ui8enable2PassGopPatern)
12753 {
12754 ni_strncpy(p_param_err, max_err_len,
12755 "enable2PassGop is not supported on jpeg encoder",
12756 max_err_len - 1);
12758 LRETURN;
12759 }
12760 if (p_cfg->ui8LookAheadDepth)
12761 {
12762 ni_strncpy(p_param_err, max_err_len,
12763 "lookAheadDepth is not supported on jpeg encoder",
12764 max_err_len - 1);
12766 LRETURN;
12767 }
12769 {
12770 ni_strncpy(p_param_err, max_err_len,
12771 "gopPresetIdx is not supported on jpeg encoder",
12772 max_err_len - 1);
12774 LRETURN;
12775 }
12776 if (p_cfg->niParamT408.roiEnable)
12777 {
12778 ni_strncpy(p_param_err, max_err_len, "roiEnable is not supported on jpeg encoder",
12779 max_err_len - 1);
12781 LRETURN;
12782 }
12783 if(p_src->roi_demo_mode)
12784 {
12785 ni_strncpy(p_param_err, max_err_len,
12786 "RoiDemoMode is not supported on jpeg encoder",
12787 max_err_len - 1);
12789 LRETURN;
12790 }
12791 if (p_src->cacheRoi)
12792 {
12793 ni_strncpy(p_param_err, max_err_len, "cacheRoi is not supported on jpeg encoder",
12794 max_err_len - 1);
12796 LRETURN;
12797 }
12799 {
12800 ni_strncpy(p_param_err, max_err_len,
12801 "ReconfDemoMode is not supported on jpeg encoder",
12802 max_err_len - 1);
12804 LRETURN;
12805 }
12806 if (p_cfg->niParamT408.intraRefreshMode)
12807 {
12808 ni_strncpy(p_param_err, max_err_len,
12809 "intraRefreshMode is not supported on jpeg encoder",
12810 max_err_len - 1);
12812 LRETURN;
12813 }
12814 if (p_cfg->niParamT408.intraRefreshArg)
12815 {
12816 ni_strncpy(p_param_err, max_err_len,
12817 "intraRefreshArg is not supported on jpeg encoder",
12818 max_err_len - 1);
12820 LRETURN;
12821 }
12822 if (p_cfg->niParamT408.intra_period != 120)
12823 {
12824 ni_strncpy(p_param_err, max_err_len,
12825 "intraPeriod is not supported on jpeg encoder",
12826 max_err_len - 1);
12828 LRETURN;
12829 }
12830 if (p_cfg->ui8intraResetRefresh)
12831 {
12832 ni_strncpy(
12833 p_param_err, max_err_len,
12834 "IntraRefreshResetOnForceIDR is not supported on jpeg encoder",
12835 max_err_len - 1);
12837 LRETURN;
12838 }
12839 if (p_cfg->niParamT408.useLongTerm)
12840 {
12841 ni_strncpy(p_param_err, max_err_len,
12842 "longTermReferenceEnable is not supported on jpeg encoder",
12843 max_err_len - 1);
12845 LRETURN;
12846 }
12847 if (p_cfg->ui32setLongTermInterval)
12848 {
12849 ni_strncpy(p_param_err, max_err_len,
12850 "longTermReferenceInterval is not supported on jpeg encoder",
12851 max_err_len - 1);
12853 LRETURN;
12854 }
12855 if (p_cfg->ui8setLongTermCount != 2)
12856 {
12857 ni_strncpy(p_param_err, max_err_len,
12858 "longTermReferenceCount is not supported on jpeg encoder",
12859 max_err_len - 1);
12861 LRETURN;
12862 }
12863 if (p_cfg->ui8multicoreJointMode)
12864 {
12865 ni_strncpy(p_param_err, max_err_len,
12866 "multicoreJointMode is not supported on jpeg encoder",
12867 max_err_len - 1);
12869 LRETURN;
12870 }
12871 if (p_cfg->ui8enableSSIM)
12872 {
12873 ni_strncpy(p_param_err, max_err_len, "enableSSIM is not supported on jpeg encoder",
12874 max_err_len - 1);
12876 LRETURN;
12877 }
12878 if (p_enc->rc.vbv_buffer_size != -1)
12879 {
12880 ni_strncpy(p_param_err, max_err_len,
12881 "vbvBufferSize is not supported on jpeg encoder",
12882 max_err_len - 1);
12884 LRETURN;
12885 }
12886 if (p_cfg->ui8fillerEnable)
12887 {
12888 ni_strncpy(p_param_err, max_err_len,
12889 "fillerEnable is not supported on jpeg encoder",
12890 max_err_len - 1);
12892 LRETURN;
12893 }
12894 if (p_cfg->ui8picSkipEnable)
12895 {
12896 ni_strncpy(p_param_err, max_err_len, "picSkip is not supported on jpeg encoder",
12897 max_err_len - 1);
12899 LRETURN;
12900 }
12901 if (p_cfg->ui16maxFrameSize)
12902 {
12903 ni_strncpy(p_param_err, max_err_len, "maxFrameSize is not supported on jpeg encoder",
12904 max_err_len - 1);
12906 LRETURN;
12907 }
12909 {
12910 ni_strncpy(p_param_err, max_err_len,
12911 "cuLevelRCEnable is not supported on jpeg encoder",
12912 max_err_len - 1);
12914 LRETURN;
12915 }
12916 if (p_cfg->niParamT408.enable_hvs_qp)
12917 {
12918 ni_strncpy(p_param_err, max_err_len, "hvsQPEnable is not supported on jpeg encoder",
12919 max_err_len - 1);
12921 LRETURN;
12922 }
12923 if (p_cfg->niParamT408.profile)
12924 {
12925 ni_strncpy(p_param_err, max_err_len, "profile is not supported on jpeg encoder",
12926 max_err_len - 1);
12928 LRETURN;
12929 }
12931 {
12932 ni_strncpy(p_param_err, max_err_len, "intraRefreshMode or intraRefreshArg is not supported on jpeg encoder",
12933 max_err_len - 1);
12935 LRETURN;
12936 }
12937 if (p_cfg->i8crf != -1)
12938 {
12939 ni_strncpy(p_param_err, max_err_len, "crf is not supported on jpeg encoder",
12940 max_err_len - 1);
12942 LRETURN;
12943 }
12944 if (p_cfg->i32tolCtbRcInter != (int32_t)(0.1 * 1000))
12945 {
12946 ni_strncpy(p_param_err, max_err_len, "tolCtbRcInter is not supported on jpeg encoder",
12947 max_err_len - 1);
12949 LRETURN;
12950 }
12951 if (p_cfg->i32tolCtbRcIntra != (int32_t)(0.1 * 1000))
12952 {
12953 ni_strncpy(p_param_err, max_err_len, "tolCtbRcIntra is not supported on jpeg encoder",
12954 max_err_len - 1);
12956 LRETURN;
12957 }
12958 if (p_cfg->ui8rcQpDeltaRange != 10)
12959 {
12960 ni_strncpy(p_param_err, max_err_len,
12961 "rcQpDeltaRange is not supported on jpeg encoder",
12962 max_err_len - 1);
12964 LRETURN;
12965 }
12966 if (p_cfg->i16bitrateWindow != -255)
12967 {
12968 ni_strncpy(p_param_err, max_err_len, "bitrateWindow is not supported on jpeg encoder",
12969 max_err_len - 1);
12971 LRETURN;
12972 }
12973 if (p_cfg->i16ctbRowQpStep)
12974 {
12975 ni_strncpy(p_param_err, max_err_len, "ctbRowQpStep is not supported on jpeg encoder",
12976 max_err_len - 1);
12978 LRETURN;
12979 }
12980 if (p_cfg->ui8AiEnhanceMode)
12981 {
12982 ni_strncpy(p_param_err, max_err_len,
12983 "enableAIEnhance is not supported on jpeg encoder",
12984 max_err_len - 1);
12986 LRETURN;
12987 }
12988 if (p_cfg->i8ppsInitQp)
12989 {
12990 ni_strncpy(p_param_err, max_err_len, "ppsInitQp is not supported for jpeg encoder",
12991 max_err_len - 1);
12993 LRETURN;
12994 }
12995 if (p_cfg->i8pass1Qp)
12996 {
12997 ni_strncpy(p_param_err, max_err_len, "pass1Qp is not supported for jpeg encoder",
12998 max_err_len - 1);
13000 LRETURN;
13001 }
13002 if (p_enc->bitrateMode != -1)
13003 {
13004 ni_strncpy(p_param_err, max_err_len, "bitrateMode is not supported for jpeg encoder",
13005 max_err_len - 1);
13007 LRETURN;
13008 }
13009 if (p_cfg->ui8vbvBufferReencode)
13010 {
13011 ni_strncpy(p_param_err, max_err_len,
13012 "vbvBufferReencode is not supported on jpeg encoder",
13013 max_err_len - 1);
13015 LRETURN;
13016 }
13017 if (p_enc->get_psnr_mode != 3)
13018 {
13019 ni_strncpy(p_param_err, max_err_len,
13020 "getPsnrMode or getReconstructedMode is not supported on jpeg encoder",
13021 max_err_len - 1);
13023 LRETURN;
13024 }
13025 if (p_cfg->ui8spatialLayersMinusOne > 0)
13026 {
13027 ni_strncpy(p_param_err, max_err_len,
13028 "spatialLayers is not supported for Jpeg encode",
13029 max_err_len - 1);
13031 LRETURN;
13032 }
13033 if (p_cfg->ui8disableAv1TimingInfo != 0)
13034 {
13035 ni_strncpy(p_param_err, max_err_len, "disableAv1TimingInfo is not supported for Jpeg",
13036 max_err_len - 1);
13038 LRETURN;
13039 }
13040 if (p_cfg->ui8av1OpLevel[0] != 0)
13041 {
13042 ni_strncpy(p_param_err, max_err_len, "av1OpLevel is not supported for Jpeg",
13043 max_err_len - 1);
13045 LRETURN;
13046 }
13047 if (p_enc->getBitstreamFeatures != 0)
13048 {
13049 ni_strncpy(p_param_err, max_err_len,
13050 "getBitstreamFeatures is not supported for jpeg encoder",
13051 max_err_len - 1);
13053 LRETURN;
13054 }
13055 }
13056
13057 if (p_src->force_frame_type != 0 && p_src->force_frame_type != 1)
13058 {
13059 ni_strncpy(p_param_err, max_err_len, "Invalid forceFrameType: out of range",
13060 max_err_len - 1);
13061 param_ret = NI_RETCODE_INVALID_PARAM;
13062 LRETURN;
13063 }
13064
13065 if (p_cfg->niParamT408.forcedHeaderEnable > 2)
13066 {
13067 ni_strncpy(p_param_err, max_err_len, "Invalid forcedHeaderEnable: out of range",
13068 max_err_len - 1);
13070 LRETURN;
13071 }
13072
13073 if (p_cfg->niParamT408.decoding_refresh_type < 0 ||
13075 {
13076 ni_strncpy(p_param_err, max_err_len, "Invalid decoding_refresh_type: out of range", max_err_len - 1);
13078 LRETURN;
13079 }
13080
13081 if (!QUADRA)
13082 {
13083 if (p_cfg->niParamT408.gop_preset_index < 0 ||
13084 p_cfg->niParamT408.gop_preset_index > 8)
13085 {
13086 ni_strcpy(p_param_err, max_err_len, "Invalid gop_preset_index: out of range");
13088 LRETURN;
13089 }
13090
13091 if (p_src->low_delay_mode && 1 != p_cfg->niParamT408.gop_preset_index &&
13092 2 != p_cfg->niParamT408.gop_preset_index &&
13093 3 != p_cfg->niParamT408.gop_preset_index &&
13094 6 != p_cfg->niParamT408.gop_preset_index &&
13095 7 != p_cfg->niParamT408.gop_preset_index &&
13096 !(0 == p_cfg->niParamT408.gop_preset_index &&
13098 {
13099 ni_strcpy(p_param_err, max_err_len, "GOP size must be 1 when lowDelay is enabled");
13101 LRETURN;
13102 }
13103 }
13104 else // QUADRA
13105 {
13106 if (p_cfg->ui8gopSize > 16)
13107 {
13108 ni_strncpy(p_param_err, max_err_len, "Invalid gopSize out of range", max_err_len - 1);
13110 LRETURN;
13111 }
13112
13113 if (p_cfg->ui8gopLowdelay &&
13114 p_cfg->ui8gopSize > 4)
13115 {
13116 ni_strncpy(p_param_err, max_err_len, "GOP size must be <= 4 for low delay GOP", max_err_len - 1);
13118 LRETURN;
13119 }
13120
13121 if (p_cfg->ui8LookAheadDepth)
13122 {
13123 if (p_cfg->ui8LookAheadDepth < 4 || p_cfg->ui8LookAheadDepth > 40)
13124 {
13125 ni_strncpy(p_param_err, max_err_len, "Invalid LookAheadDepth: out of range. <[4-40]>", max_err_len - 1);
13127 LRETURN;
13128 }
13129 if (p_cfg->ui8gopLowdelay)
13130 {
13131 ni_strncpy(p_param_err, max_err_len, "2-pass encode does not support low delay GOP", max_err_len - 1);
13133 LRETURN;
13134 }
13136 {
13137 ni_strncpy(p_param_err, max_err_len, "2-pass encode does not support tile4x4 format",
13138 max_err_len - 1);
13140 LRETURN;
13141 }
13142 if (p_cfg->ui8spatialLayersMinusOne > 0)
13143 {
13144 ni_strncpy(p_param_err, max_err_len, "currently do not support lookahead encode with multi spatial layers", max_err_len - 1);
13146 LRETURN;
13147 }
13148 }
13149
13150 if (p_src->low_delay_mode || p_cfg->ui8picSkipEnable)
13151 {
13153 {
13154 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size; i++)
13155 {
13156 if (p_cfg->niParamT408.custom_gop_params.pic_param[i].poc_offset != (i+1))
13157 {
13158 if (p_src->low_delay_mode)
13159 ni_strncpy(p_param_err, max_err_len, "Custom GOP must not include backward prediction when lowDelay is enabled", max_err_len - 1);
13160 else
13161 ni_strncpy(p_param_err, max_err_len, "Custom GOP must not include backward prediction when picSkip is enabled", max_err_len - 1);
13162 param_ret = NI_RETCODE_INVALID_PARAM;
13163 LRETURN;
13164 }
13165 }
13166 } else if (1 != p_cfg->ui8gopSize && !p_cfg->ui8gopLowdelay &&
13167 p_cfg->niParamT408.intra_period != 1 &&
13169 {
13170 if (p_src->low_delay_mode)
13171 {
13172 if (p_cfg->ui8spatialLayersMinusOne == 0)
13173 {
13174 ni_strncpy(p_param_err, max_err_len, "Must use low delay GOP (gopPresetIdx 1,3,7,9,10) when lowDelay is enabled", max_err_len - 1);
13176 LRETURN;
13177 }
13178 }
13179 else
13180 {
13181 ni_strncpy(p_param_err, max_err_len, "Must use low delay GOP (gopPresetIdx 1,3,7,9,10) when picSkip is enabled", max_err_len - 1);
13183 LRETURN;
13184 }
13185 } else if ((p_cfg->ui8LookAheadDepth != 0) && (!p_cfg->ui8useLowDelayPocType))
13186 {
13187 if (p_src->low_delay_mode)
13188 ni_strncpy(p_param_err, max_err_len, "lookAheadDepth must be 0 when lowDelay is enabled", max_err_len - 1);
13189 else
13190 ni_strncpy(p_param_err, max_err_len, "lookAheadDepth must be 0 when picSkip is enabled", max_err_len - 1);
13191 param_ret = NI_RETCODE_INVALID_PARAM;
13192 LRETURN;
13193 }
13194
13195 if (p_cfg->ui8multicoreJointMode)
13196 {
13197 if (p_src->low_delay_mode)
13198 ni_strncpy(p_param_err, max_err_len,
13199 "Cannot use multicoreJointMode when lowDelay is enabled",
13200 max_err_len - 1);
13201 else
13202 ni_strncpy(p_param_err, max_err_len,
13203 "Cannot use multicoreJointMode when picSkip is enabled",
13204 max_err_len - 1);
13205 param_ret = NI_RETCODE_INVALID_PARAM;
13206 LRETURN;
13207 }
13208
13209 if (p_src->minFramesDelay)
13210 {
13211 if (p_src->low_delay_mode)
13212 ni_strncpy(p_param_err, max_err_len,
13213 "Cannot enable minFramesDelay when lowDelay is enabled",
13214 max_err_len - 1);
13215 else
13216 ni_strncpy(p_param_err, max_err_len,
13217 "Cannot enable minFramesDelay when picSkip is enabled",
13218 max_err_len - 1);
13219 param_ret = NI_RETCODE_INVALID_PARAM;
13220 LRETURN;
13221 }
13222 }
13223
13224 if (p_cfg->ui8spatialLayersMinusOne > 0)
13225 {
13226 int intra_period_in_frames = p_cfg->niParamT408.intra_period * (p_cfg->ui8spatialLayersMinusOne+1);
13227 p_cfg->niParamT408.intra_period = p_cfg->niParamT408.avcIdrPeriod = intra_period_in_frames;
13228 }
13229
13230 if (p_cfg->ui8useLowDelayPocType)
13231 {
13233 {
13234 ni_strncpy(p_param_err, max_err_len, "Custom GOP size must be 1 when useLowDelayPocType is enabled", max_err_len - 1);
13235 param_ret = NI_RETCODE_INVALID_PARAM;
13236 LRETURN;
13237 } else if (1 != p_cfg->ui8gopSize && !p_cfg->ui8gopLowdelay &&
13238 p_cfg->niParamT408.intra_period != 1)
13239 {
13240 ni_strncpy(p_param_err, max_err_len, "Must use GOP with all frames as reference frames (gopPresetIdx 1,3,7,9) when useLowDelayPocType is enabled", max_err_len - 1);
13242 LRETURN;
13243 }
13244 }
13245
13246 if (p_src->low_delay_mode)
13247 {
13248 // minimum acceptable value of maxFrameSize is bitrate / framerate in bytes
13249 uint32_t min_maxFrameSize = p_cfg->i32bitRate / p_cfg->i32frameRateInfo * p_cfg->i32frameRateDenominator / 8;
13250
13251 if (p_cfg->ui16maxFrameSize == 0)
13252 {
13253 if (p_enc->maxFrameSizeRatio > 0)
13254 {
13255 if (min_maxFrameSize * p_enc->maxFrameSizeRatio > NI_MAX_FRAME_SIZE)
13256 {
13257 p_cfg->ui16maxFrameSize = NI_MAX_FRAME_SIZE / 2000;
13258 } else
13259 {
13260 p_cfg->ui16maxFrameSize = min_maxFrameSize * p_enc->maxFrameSizeRatio / 2000;
13261 }
13262 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: Set maxFrameSize to %d times the "
13263 "minimum frame size %d bytes in low delay mode\n", __func__,
13264 p_enc->maxFrameSizeRatio, p_cfg->ui16maxFrameSize * 2000);
13265 } else
13266 {
13267 p_cfg->ui16maxFrameSize = ((p_src->source_width * p_src->source_height * 3 / 4) * p_ctx->bit_depth_factor) / 2000;
13268 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: maxFrameSize is not set in low delay "
13269 "mode. Set it to half of the maximum frame size %d bytes\n",
13270 __func__, p_cfg->ui16maxFrameSize*2000);
13271 }
13272 }
13273
13274 if (p_cfg->ui16maxFrameSize < min_maxFrameSize / 2000)
13275 {
13276 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: maxFrameSize %u is too small. Changed to minimum value (bitrate/framerate in byte): %u\n",
13277 __func__, p_cfg->ui16maxFrameSize*2000, min_maxFrameSize);
13278 p_cfg->ui16maxFrameSize = min_maxFrameSize / 2000;
13279 }
13280 }
13281 else
13282 {
13283 if (p_cfg->ui16maxFrameSize != 0 || p_enc->maxFrameSizeRatio > 0)
13284 {
13285 ni_strncpy(p_param_err, max_err_len, "maxFrameSize can only be used when lowDelay is enabled", max_err_len - 1);
13286 param_ret = NI_RETCODE_INVALID_PARAM;
13287 LRETURN;
13288 }
13289 }
13290 }
13291
13292 if (QUADRA)
13293 {
13294 if (p_cfg->ui16gdrDuration)
13295 {
13297 {
13298 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size; i++)
13299 {
13301 {
13302 ni_strncpy(p_param_err, max_err_len, "Custom GOP can not have B frames for intra refresh", max_err_len - 1);
13303 param_ret = NI_RETCODE_INVALID_PARAM;
13304 LRETURN;
13305 }
13306 }
13307 }
13308 else if (p_cfg->ui8gopSize != 1 || p_cfg->ui8gopLowdelay)
13309 {
13311 {
13312 ni_strncpy(p_param_err, max_err_len,
13313 "Must use gopPresetIdx 9 (consecutive P frame) for intra refresh",
13314 max_err_len - 1);
13315 param_ret = NI_RETCODE_INVALID_PARAM;
13316 LRETURN;
13317 }
13318 ni_strncpy(p_param_warn, max_err_len, "GOP size forced to 1 and low delay GOP force disabled (no B frames) for intra refresh", max_err_len - 1);
13319 warning = NI_RETCODE_PARAM_WARN;
13320 p_cfg->ui8gopSize = 1;
13321 p_cfg->ui8gopLowdelay = 0;
13322 }
13323 if (p_cfg->ui16gdrDuration == 1)
13324 {
13325 ni_strncpy(p_param_err, max_err_len,
13326 "intra refresh cycle (height / intraRefreshArg MB or CTU) must > 1",
13327 max_err_len - 1);
13328 param_ret = NI_RETCODE_INVALID_PARAM;
13329 LRETURN;
13330 }
13331 if (p_cfg->ui8LookAheadDepth != 0)
13332 {
13333 ni_strncpy(p_param_err, max_err_len, "lookaheadDepth must be 0 for intra refresh", max_err_len - 1);
13334 param_ret = NI_RETCODE_INVALID_PARAM;
13335 LRETURN;
13336 }
13337 if (STD_HEVC == p_cfg->ui8bitstreamFormat ||
13338 STD_AV1 == p_cfg->ui8bitstreamFormat)
13339 {
13340 if (p_cfg->niParamT408.intra_period < p_cfg->ui16gdrDuration)
13341 {
13342 ni_strncpy(p_param_warn, max_err_len, "intraPeriod forced to match intra refersh cycle (intraPeriod must >= intra refersh cycle)", max_err_len - 1);
13343 warning = NI_RETCODE_PARAM_WARN;
13345 }
13346 }
13347 else if (STD_AVC == p_cfg->ui8bitstreamFormat)
13348 {
13349 if (p_cfg->niParamT408.avcIdrPeriod < p_cfg->ui16gdrDuration)
13350 {
13351 ni_strncpy(p_param_warn, max_err_len, "intraPeriod forced to match intra refersh cycle (intraPeriod must >= intra refersh cycle)", max_err_len - 1);
13352 warning = NI_RETCODE_PARAM_WARN;
13354 }
13355 }
13356 }
13357
13358 if (p_cfg->ui8multicoreJointMode)
13359 {
13360 if (p_cfg->ui8hrdEnable)
13361 {
13362 ni_strncpy(p_param_warn, max_err_len, "HRD conformance is not guaranteed in multicoreJointMode", max_err_len - 1);
13363 warning = NI_RETCODE_PARAM_WARN;
13364 }
13365 }
13366
13367 if (p_cfg->ui8temporalLayersEnable)
13368 {
13369 if (p_cfg->ui8hrdEnable)
13370 {
13371 snprintf(p_param_err, max_err_len, "HRD conformance with multiple temporal layers is currently not supported");
13373 LRETURN;
13374 }
13375 }
13376
13377 if ((p_cfg->ui8hrdEnable) || (p_cfg->ui8fillerEnable))
13378 {
13379 // enable rate control
13380 if (p_cfg->ui8rcEnable == 0)
13381 {
13383 }
13384
13385 // enable hrd if it is off
13386 if (p_cfg->i32vbvBufferSize == 0)
13387 {
13388 p_cfg->i32vbvBufferSize = 3000;
13389 }
13390 }
13391
13392 // maxrate must >= bitrate
13393 if (p_cfg->ui32vbvMaxRate != 0)
13394 {
13395 if ((int)p_cfg->ui32vbvMaxRate < p_cfg->i32bitRate)
13396 {
13397 snprintf(p_param_err, max_err_len, "vbvMaxRate %u cannot be smaller than bitrate %d",
13398 p_cfg->ui32vbvMaxRate, p_cfg->i32bitRate);
13400 LRETURN;
13401 }
13402 }
13403
13404 // minrate must <= bitrate
13405 if (p_cfg->ui32vbvMinRate != 0)
13406 {
13407 if ((int)p_cfg->ui32vbvMinRate > p_cfg->i32bitRate)
13408 {
13409 snprintf(p_param_err, max_err_len, "vbvMinRate %u cannot be larger than bitrate %d",
13410 p_cfg->ui32vbvMinRate, p_cfg->i32bitRate);
13412 LRETURN;
13413 }
13414 }
13415
13416 // The supported range of vbvBufferSize are 0, or 1/framerate to 3000. If the vbvBufferSize is not 0.
13417 // The minimum vbvBufferSize in msec is 1/framerate. The actual minimum in bits is bitrate/framerate.
13418 if (p_cfg->i32vbvBufferSize != 0)
13419 {
13420 // check buffer size compatible to bitrate
13421 int32_t minVbvBufferSize = p_cfg->i32frameRateDenominator * 1000 / p_cfg->i32frameRateInfo;
13422 if (p_cfg->i32vbvBufferSize < minVbvBufferSize)
13423 {
13424 snprintf(p_param_err, max_err_len, "vbvBufferSize must be greater than the average frame size. Minimum is %d msec for framerate %d fps",
13425 minVbvBufferSize, (p_cfg->i32frameRateInfo / p_cfg->i32frameRateDenominator));
13427 LRETURN;
13428 }
13429
13430 // check buffer size compatible to maxrate
13431 if (p_cfg->ui32vbvMaxRate != 0)
13432 {
13433 int32_t maxRateMinVbvBufferSize = ((int64_t)p_cfg->i32frameRateDenominator * 1000 / p_cfg->i32frameRateInfo) * p_cfg->ui32vbvMaxRate / p_cfg->i32bitRate;
13434 if (p_cfg->i32vbvBufferSize < maxRateMinVbvBufferSize)
13435 {
13436 snprintf(p_param_warn, max_err_len, "vbvBufferSize cannot be smaller than one frame size based on vbvMaxRate, force vbvBufferSize to %d msec for bitrate %d vbvMaxRate %u and framerate %d fps",
13437 maxRateMinVbvBufferSize, p_cfg->i32bitRate, p_cfg->ui32vbvMaxRate, (p_cfg->i32frameRateInfo / p_cfg->i32frameRateDenominator));
13438 warning = NI_RETCODE_PARAM_WARN;
13439 p_cfg->i32vbvBufferSize = maxRateMinVbvBufferSize;
13440 }
13441 }
13442 // check buffer size compatible to minrate (capped CRF may set minrate without maxrate)
13443 else if (p_cfg->ui32vbvMinRate != 0)
13444 {
13445 int32_t minRateMinVbvBufferSize = ((int64_t)p_cfg->i32frameRateDenominator * 1000 / p_cfg->i32frameRateInfo) * p_cfg->ui32vbvMinRate / p_cfg->i32bitRate;
13446 if (p_cfg->i32vbvBufferSize < minRateMinVbvBufferSize)
13447 {
13448 snprintf(p_param_warn, max_err_len, "vbvBufferSize cannot be smaller than one frame size based on vbvMinRate, force vbvBufferSize to %d msec for bitrate %d vbvMinRate %u and framerate %d fps",
13449 minRateMinVbvBufferSize, p_cfg->i32bitRate, p_cfg->ui32vbvMinRate, (p_cfg->i32frameRateInfo / p_cfg->i32frameRateDenominator));
13450 warning = NI_RETCODE_PARAM_WARN;
13451 p_cfg->i32vbvBufferSize = minRateMinVbvBufferSize;
13452 }
13453 }
13454 }
13455 else
13456 {
13457 // check buffer size compatible to maxrate and/or minrate
13458 if ( p_cfg->ui32vbvMaxRate != 0 || p_cfg->ui32vbvMinRate != 0 )
13459 {
13460 snprintf(p_param_warn, max_err_len, "vbvMaxRate %u vbvMinRate %u does not take effect when vbvBufferSize is 0, force vbvMaxRate vbvMinRate to 0",
13461 p_cfg->ui32vbvMaxRate, p_cfg->ui32vbvMinRate);
13462 warning = NI_RETCODE_PARAM_WARN;
13463 p_cfg->ui32vbvMaxRate = 0;
13464 p_cfg->ui32vbvMinRate = 0;
13465 }
13466 }
13467
13468 if (p_cfg->ui32ltrRefInterval || p_cfg->niParamT408.useLongTerm)
13469 {
13470 if (p_cfg->ui32ltrRefInterval && p_cfg->niParamT408.useLongTerm)
13471 {
13472 ni_strncpy(p_param_err, max_err_len,
13473 "Can't enable ltrRefInterval and longTermReferenceEnable "
13474 "at same time",
13475 max_err_len - 1);
13476 param_ret = NI_RETCODE_INVALID_PARAM;
13477 LRETURN;
13478 }
13479
13481 {
13483 {
13484 ni_strncpy(p_param_err, max_err_len, "Custom GOP size can not be > 1 for long term reference", max_err_len - 1);
13485 param_ret = NI_RETCODE_INVALID_PARAM;
13486 LRETURN;
13487 }
13488 } else if ((p_cfg->ui8gopSize != 1) && (p_cfg->ui8gopLowdelay == 0) &&
13489 (p_cfg->niParamT408.intra_period != 1))
13490 {
13492 {
13493 ni_strncpy(p_param_err, max_err_len,
13494 "Must use low delay GOP (gopPresetIdx 1,3,7,9) for long term reference",
13495 max_err_len - 1);
13496 param_ret = NI_RETCODE_INVALID_PARAM;
13497 LRETURN;
13498 }
13499 ni_strncpy(p_param_warn, max_err_len, "GOP size forced to 1 for long term reference", max_err_len - 1);
13500 warning = NI_RETCODE_PARAM_WARN;
13501 p_cfg->ui8gopSize = 1;
13502 }
13503
13504 if (p_cfg->ui8LookAheadDepth != 0)
13505 {
13506 ni_strncpy(p_param_err, max_err_len, "lookaheadDepth must be 0 for long term reference", max_err_len - 1);
13507 param_ret = NI_RETCODE_INVALID_PARAM;
13508 LRETURN;
13509 }
13510 if (p_cfg->i8crf >= 0)
13511 {
13512 ni_strncpy(p_param_err, max_err_len, "crf must < 0 for long term reference", max_err_len - 1);
13513 param_ret = NI_RETCODE_INVALID_PARAM;
13514 LRETURN;
13515 }
13516 }
13517
13518 if (p_cfg->ui32setLongTermInterval && (p_cfg->niParamT408.useLongTerm == 0))
13519 {
13520 ni_strncpy(
13521 p_param_err, max_err_len,
13522 "Must set longTermReferenceEnable for longTermReferenceInterval",
13523 max_err_len - 1);
13524 param_ret = NI_RETCODE_INVALID_PARAM;
13525 LRETURN;
13526 }
13527
13528 if (p_cfg->ui8av1ErrResilientMode)
13529 {
13530 if (STD_AV1 != p_cfg->ui8bitstreamFormat)
13531 {
13532 ni_strncpy(p_param_warn, max_err_len, "AV1 err resilient mode forced to 0 when using other codecs", max_err_len - 1);
13533 warning = NI_RETCODE_PARAM_WARN;
13534 p_cfg->ui8av1ErrResilientMode = 0;
13535 }
13536 }
13537
13538 if (p_cfg->ui8motionConstrainedMode)
13539 {
13540 if (STD_HEVC != p_cfg->ui8bitstreamFormat)
13541 {
13542 ni_strncpy(p_param_warn, max_err_len, "Motion Constrained mode force disabled for codecs other than HEVC", max_err_len - 1);
13543 warning = NI_RETCODE_PARAM_WARN;
13544 p_cfg->ui8motionConstrainedMode = 0;
13545 }
13546 else
13547 {
13548 if (p_cfg->ui8rdoLevel != 1)
13549 {
13550 ni_strncpy(
13551 p_param_err, max_err_len,
13552 "rdoLevel must be 1 for Motion Constrained mode 1 or 2",
13553 max_err_len - 1);
13554 param_ret = NI_RETCODE_INVALID_PARAM;
13555 LRETURN;
13556 }
13557
13559 {
13560 if (p_cfg->ui8multicoreJointMode)
13561 {
13562 ni_strncpy(
13563 p_param_err, max_err_len,
13564 "multicoreJointMode must be 0 for Motion Constrained mode 2",
13565 max_err_len - 1);
13566 param_ret = NI_RETCODE_INVALID_PARAM;
13567 LRETURN;
13568 }
13569 if (p_src->source_width % 64 || p_src->source_height % 64)
13570 {
13571 if (!p_cfg->ui32cropWidth || !p_cfg->ui32cropHeight ||
13572 p_cfg->ui32cropWidth % 64 || p_cfg->ui32cropHeight % 64)
13573 {
13574 ni_strncpy(
13575 p_param_err, max_err_len,
13576 "input resolution (or cropping window) must be 64x64 aligned for Motion Constrained mode 2",
13577 max_err_len - 1);
13578 param_ret = NI_RETCODE_INVALID_PARAM;
13579 LRETURN;
13580 }
13581 }
13582 }
13583 }
13584 }
13585
13586 if (p_cfg->ui8avccHvcc)
13587 {
13588 if ((STD_AVC != p_cfg->ui8bitstreamFormat) && (STD_HEVC != p_cfg->ui8bitstreamFormat))
13589 {
13590 ni_strncpy(p_param_warn, max_err_len, "AVCC HVCC forced to 0 for codecs other than AVC HEVC", max_err_len - 1);
13591 warning = NI_RETCODE_PARAM_WARN;
13592 p_cfg->ui8avccHvcc = 0;
13593 }
13594 }
13595
13596 if (p_enc->getBitstreamFeatures)
13597 {
13598 if(1 != p_cfg->niParamT408.gop_preset_index &&
13599 3 != p_cfg->niParamT408.gop_preset_index &&
13600 7 != p_cfg->niParamT408.gop_preset_index &&
13601 9 != p_cfg->niParamT408.gop_preset_index)
13602 {
13603 ni_strncpy(p_param_err, max_err_len,
13604 "getBitstreamFeatures is only supported for gopPresetIndex 1, 3, 7, 9",
13605 max_err_len - 1);
13607 LRETURN;
13608 }
13609
13610 if (p_cfg->ui32cropWidth || p_cfg->ui32cropHeight)
13611 {
13612 ni_strncpy(p_param_err, max_err_len,
13613 "getBitstreamFeatures is not supported when Crop Width > 0 || Crop Height > 0",
13614 max_err_len - 1);
13615 param_ret = NI_RETCODE_INVALID_PARAM;
13616 LRETURN;
13617 }
13618
13621 "6sM") < 0)
13622 {
13623 ni_strncpy(p_param_err, max_err_len,
13624 "getBitstreamFeatures is not supported in FW API version < 6sM\n",
13625 max_err_len - 1);
13626 param_ret = NI_RETCODE_INVALID_PARAM;
13627 LRETURN;
13628 }
13629 }
13630 }
13631
13632 if (p_cfg->niParamT408.cu_size_mode < 0 ||
13633 p_cfg->niParamT408.cu_size_mode > 7)
13634 {
13635 ni_strncpy(p_param_err, max_err_len, "Invalid cu_size_mode: out of range", max_err_len - 1);
13637 LRETURN;
13638 }
13639
13640
13641
13642 if (p_cfg->niParamT408.use_recommend_enc_params < 0 ||
13644 {
13645 ni_strncpy(p_param_err, max_err_len, "Invalid use_recommend_enc_params: out of range", max_err_len - 1);
13647 LRETURN;
13648 }
13649
13651 {
13652 case 0:
13653 case 2:
13654 case 3:
13655 {
13656 if (p_cfg->niParamT408.use_recommend_enc_params != 3)
13657 {
13658 // in FAST mode (recommendEncParam==3), max_num_merge value will be
13659 // decided in FW
13660 if (p_cfg->niParamT408.max_num_merge < 0 ||
13661 p_cfg->niParamT408.max_num_merge > 3)
13662 {
13663 ni_strncpy(p_param_err, max_err_len, "Invalid max_num_merge: out of range", max_err_len - 1);
13665 LRETURN;
13666 }
13667 }
13668 break;
13669 }
13670
13671 default: break;
13672 }
13673
13674 if ( p_cfg->niParamT408.intra_qp < -1 ||
13675 p_cfg->niParamT408.intra_qp > 51 )
13676 {
13677 ni_strncpy(p_param_err, max_err_len, "Invalid intra_qp: out of range", max_err_len - 1);
13679 LRETURN;
13680 }
13681
13682 if (QUADRA)
13683 {
13684 if (p_cfg->i8crf >= 0 && p_cfg->i8crf <= 51)
13685 {
13686 if (p_cfg->ui8LookAheadDepth < 4 || p_cfg->ui8LookAheadDepth > 40)
13687 {
13689 "6X") < 0)
13690 {
13691 ni_strncpy(p_param_err, max_err_len, "CRF requres LookAheadDepth <[4-40]>", max_err_len - 1);
13693 LRETURN;
13694 }
13695 else
13696 {
13697 p_cfg->ui8LookAheadDepth = 1;
13698 p_cfg->ui8noMbtree = 1;
13699 ni_strncpy(p_param_warn, max_err_len, "enable lookahead of current frame", max_err_len - 1);
13700 warning = NI_RETCODE_PARAM_WARN;
13701 }
13702 }
13703
13704 if (p_cfg->ui8rcEnable == 1)
13705 {
13706 ni_strncpy(p_param_err, max_err_len, "CRF requires RcEnable 0", max_err_len - 1);
13708 LRETURN;
13709 }
13710 #if 0
13711 if (p_cfg->ui8ctbRcMode > 0)
13712 {
13713 ni_strncpy(p_param_warn, sizeof(p_param_warn), "Lookahead with cuLevelRCEnable or hvsQPEnable may degrade quality", max_err_len - 1);
13714 warning = NI_RETCODE_PARAM_WARN;
13715 //LRETURN;
13716 }
13717 #endif
13718 }
13719
13721 {
13722 if (p_cfg->ui8LookAheadDepth == 0)
13723 {
13724 ni_strncpy(p_param_err, max_err_len, "tuneBframeVisual level 1 (medium) requires lookahead or crf encode", max_err_len - 1);
13726 LRETURN;
13727 }
13728 }
13729 }
13730
13731 if ( p_cfg->niParamT408.enable_mb_level_rc != 1 &&
13732 p_cfg->niParamT408.enable_mb_level_rc != 0 )
13733 {
13734 ni_strncpy(p_param_err, max_err_len, "Invalid enable_mb_level_rc: out of range", max_err_len - 1);
13736 LRETURN;
13737 }
13738
13739 {
13740 if ( p_cfg->niParamT408.minQpI < 0 ||
13741 p_cfg->niParamT408.minQpI > 51 )
13742 {
13743 ni_strncpy(p_param_err, max_err_len, "Invalid min_qp: out of range", max_err_len - 1);
13744 param_ret = NI_RETCODE_PARAM_ERROR_MN_QP;
13745 LRETURN;
13746 }
13747
13748 if ( p_cfg->niParamT408.maxQpI < 0 ||
13749 p_cfg->niParamT408.maxQpI > 51 )
13750 {
13751 ni_strncpy(p_param_err, max_err_len, "Invalid max_qp: out of range", max_err_len - 1);
13752 param_ret = NI_RETCODE_PARAM_ERROR_MX_QP;
13753 LRETURN;
13754 }
13755
13756 if ( p_cfg->niParamT408.enable_cu_level_rate_control != 1 &&
13758 {
13759 ni_strncpy(p_param_err, max_err_len, "Invalid enable_cu_level_rate_control: out of range", max_err_len - 1);
13761 LRETURN;
13762 }
13763
13764 //if (p_cfg->niParamT408.enable_cu_level_rate_control == 1)
13765 {
13766 if ( p_cfg->niParamT408.enable_hvs_qp != 1 &&
13767 p_cfg->niParamT408.enable_hvs_qp != 0 )
13768 {
13769 ni_strncpy(p_param_err, max_err_len, "Invalid enable_hvs_qp: out of range", max_err_len - 1);
13771 LRETURN;
13772 }
13773
13774 if (p_cfg->niParamT408.enable_hvs_qp)
13775 {
13776 if ( p_cfg->niParamT408.max_delta_qp < 0 ||
13777 p_cfg->niParamT408.max_delta_qp > 51 )
13778 {
13779 ni_strncpy(p_param_err, max_err_len, "Invalid max_delta_qp: out of range", max_err_len - 1);
13781 LRETURN;
13782 }
13783 }
13784 }
13785 // hrd is off when i32vbvBufferSize is 0
13786 if ((p_cfg->i32vbvBufferSize < 10 && p_cfg->i32vbvBufferSize != 0) || p_cfg->i32vbvBufferSize > 3000)
13787 {
13788 ni_strncpy(p_param_err, max_err_len, "Invalid i32vbvBufferSize: out of range", max_err_len - 1);
13790 LRETURN;
13791 }
13792 }
13793
13794 // check valid for common param
13795 param_ret = ni_check_common_params(&p_cfg->niParamT408, p_src, p_param_err, max_err_len - 1);
13796 if (param_ret != NI_RETCODE_SUCCESS)
13797 {
13798 LRETURN;
13799 }
13800
13801 // check valid for RC param
13802 param_ret = ni_check_ratecontrol_params(p_cfg, p_param_err, max_err_len - 1);
13803 if (param_ret != NI_RETCODE_SUCCESS)
13804 {
13805 LRETURN;
13806 }
13807
13808 if (warning == NI_RETCODE_PARAM_WARN && param_ret == NI_RETCODE_SUCCESS)
13809 {
13810 param_ret = NI_RETCODE_PARAM_WARN;
13811 ni_strncpy(p_param_err, max_err_len, p_param_warn, max_err_len - 1);
13812 }
13813
13814END:
13815 free(p_param_warn);
13816 return param_ret;
13817}
13818
13820 ni_xcoder_params_t *p_src,
13821 char *p_param_err, uint32_t max_err_len)
13822{
13824 int32_t low_delay = 0;
13825 int32_t intra_period_gop_step_size;
13826 int32_t i, j;
13827
13828 if (!p_param || !p_src || !p_param_err)
13829 {
13830 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
13831 __func__);
13833 LRETURN;
13834 }
13835
13836 //Zero out the error buffer
13837 memset(p_param_err, 0, max_err_len - 1);
13838
13839 // check low-delay gop structure
13840 if (!QUADRA)
13841 {
13842 if (0 == p_param->gop_preset_index) // common gop
13843 {
13844 if (p_param->custom_gop_params.custom_gop_size > 1)
13845 {
13846 int minVal = p_param->custom_gop_params.pic_param[0].poc_offset;
13847 low_delay = 1;
13848 for (i = 1; i < p_param->custom_gop_params.custom_gop_size; i++)
13849 {
13850 if (minVal > p_param->custom_gop_params.pic_param[i].poc_offset)
13851 {
13852 low_delay = 0;
13853 break;
13854 } else
13855 {
13856 minVal = p_param->custom_gop_params.pic_param[i].poc_offset;
13857 }
13858 }
13859 }
13860 }
13861 else if (p_param->gop_preset_index == 2 ||
13862 p_param->gop_preset_index == 3 ||
13863 p_param->gop_preset_index == 6 ||
13864 p_param->gop_preset_index == 7) // low-delay case (IPPP, IBBB)
13865 {
13866 low_delay = 1;
13867 }
13868
13869 if (low_delay)
13870 {
13871 intra_period_gop_step_size = 1;
13872 }
13873 else
13874 {
13876 {
13877 intra_period_gop_step_size = p_param->custom_gop_params.custom_gop_size;
13878 }
13879 else
13880 {
13881 intra_period_gop_step_size = presetGopSize[p_param->gop_preset_index];
13882 }
13883 }
13884
13885 if (((p_param->intra_period != 0) && ((p_param->intra_period < intra_period_gop_step_size+1) == 1)) ||
13886 ((p_param->avcIdrPeriod != 0) && ((p_param->avcIdrPeriod < intra_period_gop_step_size+1) == 1)))
13887 {
13888 ni_strncpy(p_param_err, max_err_len, "Invalid intra_period and gop_preset_index: gop structure is larger than intra period", max_err_len - 1);
13890 LRETURN;
13891 }
13892
13893 if (((!low_delay) && (p_param->intra_period != 0) && ((p_param->intra_period % intra_period_gop_step_size) != 0)) ||
13894 ((!low_delay) && (p_param->avcIdrPeriod != 0) && ((p_param->avcIdrPeriod % intra_period_gop_step_size) != 0)))
13895 {
13896 ni_strncpy(p_param_err, max_err_len, "Invalid intra_period and gop_preset_index: intra period is not a multiple of gop structure size", max_err_len - 1);
13898 LRETURN;
13899 }
13900
13902 {
13903 int temp_poc[NI_MAX_GOP_NUM];
13904 int min_poc = p_param->custom_gop_params.pic_param[0].poc_offset;
13905 for (i = 0; i < p_param->custom_gop_params.custom_gop_size; i++)
13906 {
13908 {
13909 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: temporal_id larger than 7", max_err_len - 1);
13911 LRETURN;
13912 }
13913
13914 if (p_param->custom_gop_params.pic_param[i].temporal_id < 0)
13915 {
13916 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: temporal_id is zero or negative", max_err_len - 1);
13918 LRETURN;
13919 }
13920 temp_poc[i] = p_param->custom_gop_params.pic_param[i].poc_offset;
13921 if (min_poc > temp_poc[i])
13922 {
13923 min_poc = temp_poc[i];
13924 }
13925 }
13926 int count_pos = 0;
13927 for (i = 0; i < p_param->custom_gop_params.custom_gop_size; i++)
13928 {
13929 for (j = 0; j < p_param->custom_gop_params.custom_gop_size; j++)
13930 {
13931 if (temp_poc[j] == min_poc)
13932 {
13933 count_pos++;
13934 min_poc++;
13935 }
13936 }
13937 }
13938 if (count_pos != p_param->custom_gop_params.custom_gop_size)
13939 {
13940 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: poc_offset is invalid", max_err_len - 1);
13942 LRETURN;
13943 }
13944 }
13945 }
13946 else // QUADRA
13947 {
13949 {
13950 int temp_poc[NI_MAX_GOP_NUM];
13951 int min_poc = p_param->custom_gop_params.pic_param[0].poc_offset;
13952 for (i = 0; i < p_param->custom_gop_params.custom_gop_size; i++)
13953 {
13955 {
13956 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: temporal_id larger than 7", max_err_len - 1);
13958 LRETURN;
13959 }
13960
13961 if (p_param->custom_gop_params.pic_param[i].temporal_id < 0)
13962 {
13963 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: temporal_id is negative", max_err_len - 1);
13965 LRETURN;
13966 }
13967
13968 for (j = 0; j < p_param->custom_gop_params.pic_param[i].num_ref_pics; j++)
13969 {
13970 if (p_param->custom_gop_params.pic_param[i].rps[j].ref_pic == 0)
13971 {
13972 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: ref pic delta cannot be 0", max_err_len - 1);
13974 LRETURN;
13975 }
13976 }
13977
13978 for (j = 0; j < NI_MAX_REF_PIC; j++)
13979 {
13980 if (p_param->custom_gop_params.pic_param[i].rps[j].ref_pic != 0 &&
13981 p_param->custom_gop_params.pic_param[i].rps[j].ref_pic_used == -1)
13982 {
13983 ni_log(NI_LOG_ERROR,"g%drefPic%d specified without g%drefPic%dUsed specified!\n", i, j, i, j);
13985 LRETURN;
13986 }
13987 }
13988
13989 temp_poc[i] = p_param->custom_gop_params.pic_param[i].poc_offset;
13990 if (min_poc > temp_poc[i])
13991 {
13992 min_poc = temp_poc[i];
13993 }
13994 }
13995 int count_pos = 0;
13996 for (i = 0; i < p_param->custom_gop_params.custom_gop_size; i++)
13997 {
13998 for (j = 0; j < p_param->custom_gop_params.custom_gop_size; j++)
13999 {
14000 if (temp_poc[j] == min_poc)
14001 {
14002 count_pos++;
14003 min_poc++;
14004 }
14005 }
14006 }
14007 if (count_pos != p_param->custom_gop_params.custom_gop_size)
14008 {
14009 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: poc_offset is invalid", max_err_len - 1);
14011 LRETURN;
14012 }
14013 }
14014 }
14015
14016 if (0 == p_param->use_recommend_enc_params)
14017 {
14018 // RDO
14019 {
14020 int align_32_width_flag = p_src->source_width % 32;
14021 int align_16_width_flag = p_src->source_width % 16;
14022 int align_8_width_flag = p_src->source_width % 8;
14023 int align_32_height_flag = p_src->source_height % 32;
14024 int align_16_height_flag = p_src->source_height % 16;
14025 int align_8_height_flag = p_src->source_height % 8;
14026
14027 if (((p_param->cu_size_mode & 0x1) == 0) && ((align_8_width_flag != 0) || (align_8_height_flag != 0)))
14028 {
14029 ni_strncpy(p_param_err, max_err_len, "Invalid use_recommend_enc_params and cu_size_mode: picture width and height must be aligned with 8 pixels when enable CU8x8 of cu_size_mode. Recommend to set cu_size_mode |= 0x1 (CU8x8)", max_err_len - 1);
14031 LRETURN;
14032 }
14033 else if (((p_param->cu_size_mode & 0x1) == 0) && ((p_param->cu_size_mode & 0x2) == 0) && ((align_16_width_flag != 0) || (align_16_height_flag != 0)))
14034 {
14035 ni_strncpy(p_param_err, max_err_len, "Invalid use_recommend_enc_params and cu_size_mode: picture width and height must be aligned with 16 pixels when enable CU16x16 of cu_size_mode. Recommend to set cu_size_mode |= 0x2 (CU16x16)", max_err_len - 1);
14037 LRETURN;
14038 }
14039 else if (((p_param->cu_size_mode & 0x1) == 0) && ((p_param->cu_size_mode & 0x2) == 0) && ((p_param->cu_size_mode & 0x4) == 0) && ((align_32_width_flag != 0) || (align_32_height_flag != 0)))
14040 {
14041 ni_strncpy(p_param_err, max_err_len, "Invalid use_recommend_enc_params and cu_size_mode: picture width and height must be aligned with 32 pixels when enable CU32x32 of cu_size_mode. Recommend to set cu_size_mode |= 0x4 (CU32x32)", max_err_len - 1);
14043 LRETURN;
14044 }
14045 }
14046 }
14047
14048 if ((p_param->conf_win_top < 0) || (p_param->conf_win_top > 8192))
14049 {
14050 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_top: out of range", max_err_len - 1);
14052 LRETURN;
14053 }
14054 if (p_param->conf_win_top % 2)
14055 {
14056 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_top: not multiple of 2", max_err_len - 1);
14058 LRETURN;
14059 }
14060
14061 if ((p_param->conf_win_bottom < 0) || (p_param->conf_win_bottom > 8192))
14062 {
14063 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_bottom: out of range", max_err_len - 1);
14065 LRETURN;
14066 }
14067 if (p_param->conf_win_bottom % 2)
14068 {
14069 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_bottom: not multiple of 2", max_err_len - 1);
14071 LRETURN;
14072 }
14073
14074 if ((p_param->conf_win_left < 0) || (p_param->conf_win_left > 8192))
14075 {
14076 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_left: out of range", max_err_len - 1);
14078 LRETURN;
14079 }
14080 if (p_param->conf_win_left % 2)
14081 {
14082 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_left: not multiple of 2", max_err_len - 1);
14084 LRETURN;
14085 }
14086
14087 if (p_param->conf_win_right < 0 || p_param->conf_win_right > 8192)
14088 {
14089 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_right: out of range", max_err_len - 1);
14091 LRETURN;
14092 }
14093 if (p_param->conf_win_right % 2)
14094 {
14095 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_right: not multiple of 2", max_err_len - 1);
14097 }
14098
14099END:
14100
14101 return ret;
14102}
14103
14104ni_retcode_t ni_check_ratecontrol_params(ni_encoder_config_t* p_cfg, char* p_param_err, uint32_t max_err_len)
14105{
14107 ni_t408_config_t* p_param = NULL;
14108
14109 if( (!p_cfg) || (!p_param_err) )
14110 {
14111 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
14112 __func__);
14114 LRETURN;
14115 }
14116 p_param = &p_cfg->niParamT408;
14117
14118 //Zero out the error buffer
14119 memset(p_param_err, 0, max_err_len - 1);
14120
14121 if (p_param->roiEnable != 0 && p_param->roiEnable != 1)
14122 {
14123 ni_strncpy(p_param_err, max_err_len, "Invalid roiEnable: out of range", max_err_len - 1);
14125 LRETURN;
14126 }
14127
14128 if (p_param->roiEnable && p_param->enable_hvs_qp)
14129 {
14130 ni_strncpy(p_param_err, max_err_len, "hvsQPEnable and roiEnable: not mutually exclusive", max_err_len - 1);
14132 LRETURN;
14133 }
14134
14135 if (p_cfg->ui8rcEnable == 1)
14136 {
14137 if (p_param->minQpP > p_param->maxQpP || p_param->minQpB > p_param->maxQpB)
14138 {
14139 ni_strncpy(p_param_err, max_err_len, "Invalid min_qp(P/B) and max_qp(P/B): min_qp cannot be larger than max_qp", max_err_len - 1);
14141 LRETURN;
14142 }
14143 }
14144
14145END:
14146
14147 return ret;
14148}
14149
14150
14151/*!******************************************************************************
14152 * \brief Print xcoder user configurations
14153 *
14154 * \param
14155 *
14156 * \return
14157 *******************************************************************************/
14158void ni_params_print(ni_xcoder_params_t *const p_encoder_params)
14159{
14160 if (!p_encoder_params)
14161 {
14162 return;
14163 }
14164
14165 ni_encoder_cfg_params_t *p_enc = &p_encoder_params->cfg_enc_params;
14166
14167 ni_log(NI_LOG_DEBUG, "XCoder Params:\n");
14168
14169 ni_log(NI_LOG_DEBUG, "preset=%d\n", p_encoder_params->preset);
14170 ni_log(NI_LOG_DEBUG, "fps_number / fps_denominator=%u / %u\n",
14171 p_encoder_params->fps_number,
14172 p_encoder_params->fps_denominator);
14173
14174 ni_log(NI_LOG_DEBUG, "source_width x source_height=%dx%d\n", p_encoder_params->source_width, p_encoder_params->source_height);
14175 ni_log(NI_LOG_DEBUG, "bitrate=%d\n", p_encoder_params->bitrate);
14176
14177 ni_log(NI_LOG_DEBUG, "profile=%d\n", p_enc->profile);
14178 ni_log(NI_LOG_DEBUG, "level_idc=%d\n", p_enc->level_idc);
14179 ni_log(NI_LOG_DEBUG, "high_tier=%d\n", p_enc->high_tier);
14180
14181 ni_log(NI_LOG_DEBUG, "frame_rate=%d\n", p_enc->frame_rate);
14182
14183 ni_log(NI_LOG_DEBUG, "use_recommend_enc_params=%d\n", p_enc->use_recommend_enc_params);
14184 ni_log(NI_LOG_DEBUG, "cu_size_mode=%d\n", p_enc->cu_size_mode);
14185 ni_log(NI_LOG_DEBUG, "max_num_merge=%d\n", p_enc->max_num_merge);
14186 ni_log(NI_LOG_DEBUG, "enable_dynamic_8x8_merge=%d\n", p_enc->enable_dynamic_8x8_merge);
14187 ni_log(NI_LOG_DEBUG, "enable_dynamic_16x16_merge=%d\n", p_enc->enable_dynamic_16x16_merge);
14188 ni_log(NI_LOG_DEBUG, "enable_dynamic_32x32_merge=%d\n", p_enc->enable_dynamic_32x32_merge);
14189 // trans_rate not available in Rev B
14190 ni_log(NI_LOG_DEBUG, "enable_rate_control=%d\n", p_enc->rc.enable_rate_control);
14191 ni_log(NI_LOG_DEBUG, "enable_cu_level_rate_control=%d\n", p_enc->rc.enable_cu_level_rate_control);
14192 ni_log(NI_LOG_DEBUG, "enable_hvs_qp=%d\n", p_enc->rc.enable_hvs_qp);
14193 ni_log(NI_LOG_DEBUG, "enable_hvs_qp_scale=%d\n", p_enc->rc.enable_hvs_qp_scale);
14194 ni_log(NI_LOG_DEBUG, "hvs_qp_scale=%d\n", p_enc->rc.hvs_qp_scale);
14195 ni_log(NI_LOG_DEBUG, "min_qp=%d\n", p_enc->rc.min_qp);
14196 ni_log(NI_LOG_DEBUG, "max_qp=%d\n", p_enc->rc.max_qp);
14197 ni_log(NI_LOG_DEBUG, "max_delta_qp=%d\n", p_enc->rc.max_delta_qp);
14198 ni_log(NI_LOG_DEBUG, "vbv_buffer_size=%d\n", p_enc->rc.vbv_buffer_size);
14199 ni_log(NI_LOG_DEBUG, "enable_filler=%d\n", p_enc->rc.enable_filler);
14200 ni_log(NI_LOG_DEBUG, "enable_pic_skip=%d\n", p_enc->rc.enable_pic_skip);
14201
14202 ni_log(NI_LOG_DEBUG, "forcedHeaderEnable=%d\n", p_enc->forced_header_enable);
14203 ni_log(NI_LOG_DEBUG, "roi_enable=%d\n", p_enc->roi_enable);
14204 ni_log(NI_LOG_DEBUG, "long_term_ref_enable=%d\n", p_enc->long_term_ref_enable);
14205 ni_log(NI_LOG_DEBUG, "long_term_ref_interval=%d\n", p_enc->long_term_ref_interval);
14206 ni_log(NI_LOG_DEBUG, "long_term_ref_count=%d\n", p_enc->long_term_ref_count);
14207 ni_log(NI_LOG_DEBUG, "conf_win_top=%d\n", p_enc->conf_win_top);
14208 ni_log(NI_LOG_DEBUG, "conf_win_bottom=%d\n", p_enc->conf_win_bottom);
14209 ni_log(NI_LOG_DEBUG, "conf_win_left=%d\n", p_enc->conf_win_left);
14210 ni_log(NI_LOG_DEBUG, "conf_win_right=%d\n", p_enc->conf_win_right);
14211
14212 ni_log(NI_LOG_DEBUG, "intra_qp=%d\n", p_enc->rc.intra_qp);
14213 ni_log(NI_LOG_DEBUG, "enable_mb_level_rc=%d\n", p_enc->rc.enable_mb_level_rc);
14214
14215 ni_log(NI_LOG_DEBUG, "intra_period=%d\n", p_enc->intra_period);
14216 ni_log(NI_LOG_DEBUG, "decoding_refresh_type=%d\n", p_enc->decoding_refresh_type);
14217
14218 // Rev. B: H.264 only or HEVC-shared parameters, in ni_t408_config_t
14219 ni_log(NI_LOG_DEBUG, "enable_transform_8x8=%d\n", p_enc->enable_transform_8x8);
14220 ni_log(NI_LOG_DEBUG, "slice_mode=%d\n", p_enc->slice_mode);
14221 ni_log(NI_LOG_DEBUG, "slice_arg=%d\n", p_enc->slice_arg);
14222 ni_log(NI_LOG_DEBUG, "entropy_coding_mode=%d\n", p_enc->entropy_coding_mode);
14223 ni_log(NI_LOG_DEBUG, "intra_mb_refresh_mode=%d\n", p_enc->intra_mb_refresh_mode);
14224 ni_log(NI_LOG_DEBUG, "intra_mb_refresh_arg=%d\n", p_enc->intra_mb_refresh_arg);
14225 ni_log(NI_LOG_DEBUG, "intra_reset_refresh=%d\n", p_enc->intra_reset_refresh);
14226
14227 ni_log(NI_LOG_DEBUG, "gop_preset_index=%d\n", p_enc->gop_preset_index);
14228#ifndef QUADRA
14229 if (!QUADRA)
14230 {
14232 {
14233 int i;
14234 ni_log(NI_LOG_DEBUG, "custom_gop_params.custom_gop_size=%d\n", p_enc->custom_gop_params.custom_gop_size);
14235 for (i = 0; i < p_enc->custom_gop_params.custom_gop_size; i++)
14236 {
14237 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].pic_type=%d\n", i, p_enc->custom_gop_params.pic_param[i].pic_type);
14238 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].poc_offset=%d\n", i, p_enc->custom_gop_params.pic_param[i].poc_offset);
14239 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].pic_qp=%d\n", i, p_enc->custom_gop_params.pic_param[i].pic_qp);
14240 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].num_ref_pic_L0=%d\n", i, p_enc->custom_gop_params.pic_param[i].num_ref_pic_L0);
14241 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].ref_poc_L0=%d\n", i, p_enc->custom_gop_params.pic_param[i].ref_poc_L0);
14242 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].ref_poc_L1=%d\n", i, p_enc->custom_gop_params.pic_param[i].ref_poc_L1);
14243 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].temporal_id=%d\n", i, p_enc->custom_gop_params.pic_param[i].temporal_id);
14244 }
14245 }
14246 }
14247 else // QUADRA
14248#endif
14249 {
14251 {
14252 int i, j;
14253 ni_log(NI_LOG_DEBUG, "custom_gop_params.custom_gop_size=%d\n", p_enc->custom_gop_params.custom_gop_size);
14254 for (i = 0; i < NI_MAX_GOP_NUM; i++)
14255 {
14256 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].poc_offset=%d\n", i, p_enc->custom_gop_params.pic_param[i].poc_offset);
14257 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].qp_offset=%d\n", i, p_enc->custom_gop_params.pic_param[i].qp_offset);
14258 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].qp_factor=%lf\n", i, p_enc->custom_gop_params.pic_param[i].qp_factor);
14259 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].temporal_id=%d\n", i, p_enc->custom_gop_params.pic_param[i].temporal_id);
14260 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].pic_type=%d\n", i, p_enc->custom_gop_params.pic_param[i].pic_type);
14261 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].num_ref_pics=%d\n", i, p_enc->custom_gop_params.pic_param[i].num_ref_pics);
14262 for (j = 0; j < NI_MAX_REF_PIC; j++)
14263 {
14264 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].rps[%d].ref_pic=%d\n", i, j, p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic);
14265 ni_log(NI_LOG_DEBUG, "custom_gop_params.pic_param[%d].rps[%d].ref_pic_used=%d\n", i, j, p_enc->custom_gop_params.pic_param[i].rps[j].ref_pic_used);
14266 }
14267 }
14268 }
14269 }
14270
14271 return;
14272}
14273
14274/*!******************************************************************************
14275 * \brief decoder keep alive thread function triggers every 1 second
14276 *
14277 * \param void thread args
14278 *
14279 * \return void
14280 *******************************************************************************/
14281void *ni_session_keep_alive_thread(void *arguments)
14282{
14285 ni_session_stats_t inst_info = {0};
14286 ni_session_context_t *session_ctx = NULL;
14287 uint64_t endtime = ni_gettime_ns();
14288 uint64_t current_time;
14289 ni_pthread_mutex_t *p_mutex;
14290 //interval(nanoseconds) is equals to ctx.keep_alive_timeout/3(330,000,000ns approximately equal to 1/3 second).
14291 uint64_t interval = args->keep_alive_timeout * 330000000LL;
14292#ifndef _ANDROID
14293#ifdef __linux__
14294 struct sched_param sched_param;
14295
14296 // Linux has a wide variety of signals, Windows has a few.
14297 // A large number of signals will interrupt the thread, which will cause heartbeat command interval more than 1 second.
14298 // So just mask the unuseful signals in Linux
14299 sigset_t signal;
14300 sigfillset(&signal);
14301 ni_pthread_sigmask(SIG_BLOCK, &signal, NULL);
14302
14303 /* set up schedule priority
14304 * first try to run with RR mode.
14305 * if fails, try to set nice value.
14306 * if fails either, ignore it and run with default priority.
14307 * Note: Scheduling requires root permission. App is probably exectued
14308 * without root so the priority for this thread might just end up
14309 * being default.
14310 */
14311 if (((sched_param.sched_priority = sched_get_priority_max(SCHED_RR)) ==
14312 -1) ||
14313 sched_setscheduler(syscall(SYS_gettid), SCHED_RR, &sched_param) < 0)
14314 {
14315 char errmsg[NI_ERRNO_LEN] = {0};
14317 ni_log(NI_LOG_DEBUG, "%s cannot set scheduler: %s\n", __func__,
14318 errmsg);
14319 if (setpriority(PRIO_PROCESS, 0, -20) != 0)
14320 {
14322 ni_log(NI_LOG_DEBUG, "%s cannot set nice value: %s\n", __func__,
14323 errmsg);
14324 }
14325 }
14326
14327#elif defined(_WIN32)
14328 /* set up schedule priority.
14329 * try to set the current thread to time critical level which is the highest prioriy
14330 * level.
14331 */
14332 if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) ==
14333 0)
14334 {
14335 ni_log(NI_LOG_DEBUG, "%s cannot set priority: %d.\n", __func__,
14336 GetLastError());
14337 }
14338#endif
14339#endif
14340#ifndef _WIN32
14341 // Set thread name, name is KAT + hw_id + session_id
14342 // hw_id need at most 2 bytes, session_id at most 4 bytes.
14343 char name[16] = {0};
14344 snprintf(name, sizeof(name), "%s%.2x%.4x", "KAT", args->hw_id, args->session_id);
14345#if __linux__
14346 prctl(PR_SET_NAME, name);
14347#elif __APPLE__
14348 pthread_setname_np(name);
14349#endif
14350#endif
14351 // Initializes the session context variables that keep alive command and query status command need.
14353 if (!session_ctx)
14354 {
14356 LRETURN;
14357 }
14358 session_ctx->last_access_time = endtime;
14359 session_ctx->hw_id = args->hw_id;
14360 session_ctx->session_id = args->session_id;
14361 session_ctx->session_timestamp = args->session_timestamp;
14362 session_ctx->device_type = args->device_type;
14363 session_ctx->blk_io_handle = args->device_handle;
14364 session_ctx->event_handle = args->thread_event_handle;
14365 session_ctx->p_all_zero_buf = args->p_buffer;
14366 session_ctx->keep_alive_timeout = args->keep_alive_timeout;
14367 volatile uint64_t * plast_access_time = args->plast_access_time;
14368 if((session_ctx->last_access_time - *plast_access_time) >=
14369 (uint64_t)(session_ctx->keep_alive_timeout * 1000000000LL))
14370 {
14372 "%s creation timeout. session_id=0x%X requested timeout: %" PRIu64
14373 "ns, ping time delta: %" PRIu64 "ns\n ",
14374 __func__, session_ctx->session_id,
14375 (uint64_t)session_ctx->keep_alive_timeout * 1000000000LL,
14376 session_ctx->last_access_time - *plast_access_time);
14377 }
14378 ni_log(NI_LOG_DEBUG, "%s ctx.keep_alive_timeout: %us.\n", __func__,
14379 session_ctx->keep_alive_timeout);
14380 p_mutex = args->p_mutex;
14381
14382 for (;;)
14383 {
14384 ni_pthread_mutex_lock(p_mutex);
14385
14386 retval =
14388 session_ctx->blk_io_handle,
14389 session_ctx->event_handle,
14390 session_ctx->p_all_zero_buf);
14391
14392 retval = ni_query_session_stats(session_ctx,
14393 session_ctx->device_type,
14394 &inst_info,
14395 retval,
14397
14398 if (NI_RETCODE_SUCCESS == retval)
14399 {
14402 session_ctx->device_type,
14403 session_ctx->hw_id,
14404 &(session_ctx->session_id));
14405 }
14406
14407 ni_pthread_mutex_unlock(p_mutex);
14408
14409 if(retval)
14410 {
14411 uint32_t error_status = inst_info.ui32LastTransactionCompletionStatus;
14412 if(error_status == NI_RETCODE_SUCCESS)
14413 {
14414 /* QDFWSH-971: Error is sometimes captured by keep_alive_thread
14415 but LastTransactionCompletionStatus may be overwrited and cause
14416 incorrect log. In this case, check LastErrorStatus.*/
14417 ni_log(NI_LOG_ERROR, "session_no 0x%x inst_err_no may be overwrited!\n",
14418 session_ctx->session_id);
14421 session_ctx->device_type,
14422 session_ctx->hw_id,
14423 &(session_ctx->session_id));
14424 error_status = inst_info.ui32LastErrorStatus;
14425 }
14427 "Persistent failures detected, %s() line-%d: session_no 0x%x sess_err_no %u "
14428 "inst_err_no %u\n",
14429 __func__, __LINE__, session_ctx->session_id, inst_info.ui16ErrorCount, error_status);
14430 LRETURN;
14431 }
14433 /*If the interval between two heartbeats is greater then expected(interval) or
14434 acceptable(timeout) then the thread might have been blocked.*/
14435 if ((current_time - session_ctx->last_access_time) >= (2 * interval) || //*2 is for safety
14436 (current_time - session_ctx->last_access_time) >=
14437 (uint64_t)(args->keep_alive_timeout * 1000000000LL))
14438 {
14439 ni_log(
14441 "%s was possibly blocked. session_id=0x%X requested timeout: %" PRIu64
14442 "ns, ping time delta: %" PRIu64 "ns\n ",
14443 __func__, session_ctx->session_id,
14444 (uint64_t)session_ctx->keep_alive_timeout * 1000000000LL,
14445 current_time - session_ctx->last_access_time);
14446 }
14447 *plast_access_time = session_ctx->last_access_time = current_time;
14448 if (session_ctx->session_id == NI_INVALID_SESSION_ID)
14449 {
14451 }
14452
14453 // 1. If received failure, set the close_thread flag to TRUE, and exit,
14454 // then main thread will check this flag and return failure directly;
14455 // 2. skip checking VPU recovery.
14456 // If keep_alive thread detect the VPU RECOVERY before main thread,
14457 // the close_thread flag may damage the vpu recovery handling process.
14458 if ((NI_RETCODE_SUCCESS != retval) &&
14460 {
14461 LRETURN;
14462 }
14463 endtime += interval;
14464 while (ni_gettime_ns() < endtime)
14465 {
14466 if (args->close_thread)
14467 {
14468 LRETURN;
14469 }
14470 ni_usleep(10000); // 10ms per loop
14471 }
14472 }
14473
14474END:
14475
14476 if (NI_RETCODE_SUCCESS != retval)
14477 {
14478 ni_log(NI_LOG_ERROR, "%s abnormal closed:%d\n", __func__, retval);
14479 // changing the value to be True here means the thread has been closed.
14480 args->close_thread = true;
14481 }
14482
14483 ni_device_session_context_free(session_ctx);
14484
14485 ni_log(NI_LOG_DEBUG, "%s(): exit\n", __func__);
14486
14487 return NULL;
14488}
14489
14490/*!******************************************************************************
14491* \brief Open a xcoder upload instance
14492*
14493* \param p_ctx - pointer to caller allocated uploader session context
14494*
14495* \return
14496* On success
14497* NI_RETCODE_SUCCESS
14498*
14499* On failure
14500* NI_RETCODE_INVALID_PARAM
14501* NI_RETCODE_ERROR_MEM_ALOC
14502* NI_RETCODE_ERROR_INVALID_SESSION
14503* NI_RETCODE_FAILURE
14504*******************************************************************************/
14506{
14508 void * p_buffer = NULL;
14509 uint32_t ui32LBA = 0;
14510 uint32_t modelled_load;
14511
14512 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
14513
14514 if (!p_ctx)
14515 {
14516 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n",
14517 __func__);
14518 retval = NI_RETCODE_INVALID_PARAM;
14519 LRETURN;
14520 }
14521
14522 //Create the session if the create session flag is set
14523 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
14524 {
14526 p_ctx->pts_table = NULL;
14527 p_ctx->dts_queue = NULL;
14528 p_ctx->p_leftover = NULL;
14529 p_ctx->buffer_pool = NULL;
14530 p_ctx->prev_size = 0;
14531 p_ctx->sent_size = 0;
14532 p_ctx->status = 0;
14533 p_ctx->key_frame_type = 0;
14534 p_ctx->ready_to_close = 0;
14535 p_ctx->rc_error_count = 0;
14536 p_ctx->frame_num = 0;
14537 p_ctx->pkt_num = 0;
14538 p_ctx->pkt_index = 0;
14539
14540 //malloc zero data buffer
14541 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
14543 {
14544 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc all zero buffer failed\n",
14545 NI_ERRNO, __func__);
14547 LRETURN;
14548 }
14549 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
14550
14551 //malloc data buffer
14552 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
14553 {
14554 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
14555 NI_ERRNO, __func__);
14557 LRETURN;
14558 }
14559 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
14560
14561 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
14562 //In case we can open sesison, the session id would become valid.
14563 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
14564 (uint16_t)NI_INVALID_SESSION_ID;
14565
14566 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
14567 ui32LBA = OPEN_SESSION_CODEC(NI_DEVICE_TYPE_ENCODER, ni_htonl(p_ctx->codec_format), 1/*1 for uploadMode*/);
14568 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
14569 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
14570 if (retval != NI_RETCODE_SUCCESS)
14571 {
14572 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR ni_nvme_send_read_cmd\n");
14573 LRETURN;
14574 }
14575 //Open will return a session status structure with a valid session id if it worked.
14576 //Otherwise the invalid session id set before the open command will stay
14577 p_ctx->session_id = ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
14578 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
14579 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
14580 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
14581 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
14582 {
14583 ni_log2(p_ctx, NI_LOG_ERROR,
14584 "ERROR %s(): p_ctx->device_handle=%" PRIx64
14585 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
14586 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
14587 p_ctx->session_id);
14588 ni_encoder_session_close(p_ctx, 0);
14590 LRETURN;
14591 }
14592 ni_log2(p_ctx, NI_LOG_DEBUG,
14593 "Uploader open session ID:0x%x,timestamp:%" PRIu64 "\n",
14594 p_ctx->session_id, p_ctx->session_timestamp);
14595
14596 //Send keep alive timeout Info
14597 uint64_t keep_alive_timeout =
14598 p_ctx->keep_alive_timeout * 1000000; //send us to FW
14599 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
14600 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
14601 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
14602 keep_alive_timeout);
14604 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
14605 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
14606 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
14607 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
14608 CHECK_VPU_RECOVERY(retval);
14609
14610 if (NI_RETCODE_SUCCESS != retval)
14611 {
14612 ni_log2(p_ctx, NI_LOG_ERROR,
14613 "ERROR %s(): nvme write keep_alive_timeout command "
14614 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
14615 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
14617 LRETURN;
14618 }
14619
14620 // only update firmware with pixel rate if firmware >= 6rf
14622 (char *) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rf") >= 0)
14623 {
14624 /* Add the modelled load of the hwuploader */
14625 if (p_ctx->framerate.framerate_denom == 0)
14626 {
14627 // unknown or variable frame rate. Assume 25 fps
14628 modelled_load = (p_ctx->active_video_width * p_ctx->active_video_height) * 25;
14629 }
14630 else
14631 {
14632 modelled_load = (p_ctx->active_video_width * p_ctx->active_video_height *
14634 }
14635
14636 // modelled_load can overflow a 4-byte value so we will downscale it to
14637 // kilopixels per sec by shifting the modelled load down by 10 bits.
14638 modelled_load >>= 10;
14639
14641
14642 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
14643 memcpy(p_buffer, &modelled_load, 4);
14644
14645 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
14646 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
14647
14648 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
14649 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
14650 CHECK_VPU_RECOVERY(retval);
14651
14652 if (NI_RETCODE_SUCCESS != retval)
14653 {
14655 LRETURN;
14656 }
14657 }
14658
14659 ni_log2(p_ctx, NI_LOG_DEBUG, "Open session completed\n");
14660 }
14661
14662 // init for frame pts calculation
14663 p_ctx->is_first_frame = 1;
14664 p_ctx->last_pts = 0;
14665 p_ctx->last_dts = 0;
14666
14667 ni_timestamp_init(p_ctx, &p_ctx->pts_table, "dec_pts");
14668 ni_timestamp_init(p_ctx, &p_ctx->dts_queue, "dec_dts");
14669
14670 //p_ctx->active_video_width = 0;
14671 //p_ctx->active_video_height = 0;
14672
14673 ni_log2(p_ctx, NI_LOG_DEBUG,
14674 "%s(): p_ctx->device_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
14675 "p_ctx->session_id=%d\n",
14676 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
14677 p_ctx->session_id);
14678
14679 p_ctx->hw_action = NI_CODEC_HW_NONE;
14680#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OPEN_HARMONY__) && !defined(_ANDROID)
14681 // If this is a P2P upload session, open the Netint kernel driver
14682 if (p_ctx->isP2P)
14683 {
14684 retval = p2p_fill_pcie_address(p_ctx);
14685 if(retval != NI_RETCODE_SUCCESS)
14686 {
14687 LRETURN;
14688 }
14689 }
14690#endif
14691
14692END:
14693
14694 ni_aligned_free(p_buffer);
14695 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
14696 return retval;
14697}
14698
14699/*!******************************************************************************
14700* \brief Copy a xcoder decoder worker thread info
14701*
14702* \param
14703*
14704* \return
14705*******************************************************************************/
14707{
14708 if (!src_p_ctx || !dst_p_ctx)
14709 {
14710 ni_log(NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n", __func__);
14712 }
14713
14714 dst_p_ctx->pext_mutex = src_p_ctx->pext_mutex; //for hwdl
14715 dst_p_ctx->max_nvme_io_size = src_p_ctx->max_nvme_io_size;
14716 dst_p_ctx->device_handle = src_p_ctx->device_handle;
14717 dst_p_ctx->blk_io_handle = src_p_ctx->blk_io_handle;
14718 dst_p_ctx->hw_id = src_p_ctx->hw_id;
14719 dst_p_ctx->session_timestamp = src_p_ctx->session_timestamp;
14720 memcpy(dst_p_ctx->fw_rev, src_p_ctx->fw_rev, sizeof(src_p_ctx->fw_rev));
14721 if (src_p_ctx->isP2P)
14722 {
14723 dst_p_ctx->isP2P = src_p_ctx->isP2P;
14724 dst_p_ctx->ddr_config = src_p_ctx->ddr_config;
14725 dst_p_ctx->domain = src_p_ctx->domain;
14726 dst_p_ctx->bus = src_p_ctx->bus;
14727 dst_p_ctx->dev = src_p_ctx->dev;
14728 dst_p_ctx->fn = src_p_ctx->fn;
14729 dst_p_ctx->netint_fd = src_p_ctx->netint_fd;
14730 }
14731
14732 return NI_RETCODE_SUCCESS;
14733}
14734
14735
14736/*!******************************************************************************
14737 * \brief Query and acquire buffer from xcoder scaler instance
14738 *
14739 * \param[in] p_ctx pointer to scaler session context
14740 *
14741 * \return NI_RETCODE_INVALID_PARAM
14742 * NI_RETCODE_ERROR_INVALID_SESSION
14743 * NI_RETCODE_ERROR_MEM_ALOC
14744 * NI_RETCODE_ERROR_NVME_CMD_FAILED
14745 * NI_RETCODE_FAILURE
14746 *******************************************************************************/
14748{
14750 ni_instance_buf_info_t sInstanceBuf = {0};
14751 int query_retry = 0;
14752
14753 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
14754 {
14755 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
14756 __func__);
14758 }
14759
14760 if (p_ctx->buffered_frame_index > 0)
14761 {
14762 ni_log2(p_ctx, NI_LOG_ERROR,
14763 "Session=0x%x: %s buffered_frame_index=%d return %d\n",
14764 p_ctx->session_id,
14765 __func__,
14766 p_ctx->buffered_frame_index,
14767 retval);
14768 return retval;
14769 }
14770
14771 for (;;)
14772 {
14773 query_sleep(p_ctx);
14774 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: query by ni_query_instance_buf_info INST_BUF_INFO_RW_UPLOAD\n", __func__);
14776 NI_DEVICE_TYPE_SCALER, &sInstanceBuf);
14777
14778 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
14779 p_ctx->device_type, p_ctx->hw_id,
14780 &(p_ctx->session_id), OPT_3);
14781
14782 /* A frame index of zero is invalid, the memory acquisition failed */
14783 if (NI_RETCODE_SUCCESS != retval || (sInstanceBuf.hw_inst_ind.frame_index == 0 && query_retry >=500))
14784 {
14785 if (query_retry >=500)
14786 {
14787 ni_log2(p_ctx, NI_LOG_DEBUG,
14788 "scaler write exceeded max query retries. rc=%d try=%d\n",
14789 retval, query_retry);
14790 }
14792 LRETURN;
14793 }
14794 if (sInstanceBuf.hw_inst_ind.frame_index == 0 && query_retry < 500)
14795 {
14796 query_retry++;
14798 ni_usleep(100);
14800 }
14801 else
14802 {
14803 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: FID %d\n", __func__,
14804 sInstanceBuf.hw_inst_ind.frame_index);
14805 p_ctx->buffered_frame_index = sInstanceBuf.hw_inst_ind.frame_index;
14806 break;
14807 }
14808 }
14809
14810 ni_log2(p_ctx, NI_LOG_DEBUG,
14811 "Session=0x%x: %s got FrameIndex=%u buffered_frame_index=%d\n",
14812 p_ctx->session_id,
14813 __func__,
14814 sInstanceBuf.hw_inst_ind.frame_index,p_ctx->buffered_frame_index);
14815
14816END:
14817
14818 if (NI_RETCODE_SUCCESS != retval)
14819 {
14820 ni_log2(p_ctx, NI_LOG_DEBUG,
14821 "%s Warning scalar read hwdesc fail rc %d or ind !\n",
14822 __func__, retval);
14823 }
14824 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
14825
14826 return retval;
14827}
14828
14829
14830/*!******************************************************************************
14831* \brief Query and acquire buffer from xcoder upload instance
14832*
14833* \param p_ctx pointer to uploader session context
14834*
14835* \return NI_RETCODE_SUCCESS
14836* NI_RETCODE_ERROR_INVALID_SESSION
14837* NI_RETCODE_ERROR_MEM_ALOC
14838*******************************************************************************/
14840{
14842 //uint32_t metadata_size = NI_APP_ENC_FRAME_META_DATA_SIZE;
14843 uint32_t frame_size_bytes = 0;
14844 uint32_t retry_count = 0;
14845 ni_instance_buf_info_t buf_info = { 0 };
14846
14847 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
14848
14849 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
14850 {
14851 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
14852 __func__);
14854 LRETURN;
14855 }
14856
14857//#ifdef MEASURE_LATENCY
14858#if 0
14859 if ((p_frame->pts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
14860 {
14861 uint64_t abs_time_ns = ni_gettime_ns();
14863 abs_time_ns, p_frame->pts);
14864 }
14865#endif
14866
14867 //p_ctx->status = 0;
14868
14869 if (p_ctx->buffered_frame_index > 0)
14870 return retval;
14871
14872 for (;;)
14873 {
14874 query_sleep(p_ctx);
14875
14877 NI_DEVICE_TYPE_ENCODER, &buf_info);
14878 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
14879 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
14880 if (NI_RETCODE_SUCCESS != retval ||
14881 (buf_info.hw_inst_ind.buffer_avail == 0 && retry_count >= 500))
14882 {
14883 if (retry_count >= 500)
14884 {
14885 ni_log2(p_ctx, NI_LOG_DEBUG,
14886 "hwupload write exceeded max query retries. rc=%d try=%d"
14887 "\n",
14888 retval, retry_count);
14889 }
14891 //p_ctx->status = NI_RETCODE_NVME_SC_WRITE_BUFFER_FULL;
14892 LRETURN;
14893 }
14894 if (buf_info.hw_inst_ind.buffer_avail == 0 && retry_count < 500)
14895 {
14896 retry_count++;
14898 ni_usleep(100);
14900 }
14901 else
14902 {
14903 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: avail %d, FID %d\n", __func__,
14904 buf_info.hw_inst_ind.buffer_avail,
14905 buf_info.hw_inst_ind.frame_index);
14906
14908 break;
14909 }
14910 }
14911 ni_log2(p_ctx, NI_LOG_DEBUG, "Info hwupload write query success, available buf "
14912 "size %u >= frame size %u , retry %u\n",
14913 buf_info.buf_avail_size, frame_size_bytes, retry_count);
14914
14915//#ifdef MEASURE_LATENCY
14916#if 0
14917 if ((p_frame->pts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
14918 {
14919 uint64_t abs_time_ns = ni_gettime_ns();
14921 ni_log(NI_LOG_INFO, "PTS:%" PRId64 ",DELTA:%" PRId64 ",uLAT:%" PRIu64 ";\n",
14922 p_frame->pts, abs_time_ns - q->last_benchmark_time,
14923 ni_lat_meas_q_check_latency(q, abs_time_ns, p_frame->pts));
14924 q->last_benchmark_time = abs_time_ns;
14925 }
14926#endif
14927
14928 //retval = size;
14929
14930END:
14931
14932 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
14933 return retval;
14934}
14935
14936
14937/*!******************************************************************************
14938* \brief Send a YUV p_frame to upload session
14939*
14940* \param
14941*
14942* \return
14943*******************************************************************************/
14945 niFrameSurface1_t *hwdesc)
14946{
14947 int retval = 0;
14948 uint32_t size = 0;
14949 //uint32_t metadata_size = NI_APP_ENC_FRAME_META_DATA_SIZE;
14950 uint32_t i = 0;
14951 uint32_t sent_size = 0;
14952 uint32_t frame_size_bytes = 0;
14953 uint32_t retry_count = 0;
14954 ni_instance_buf_info_t buf_info = { 0 };
14955
14956 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
14957 //niFrameSurface1_t* p_data3 = (niFrameSurface1_t*)((uint8_t*)p_frame->p_data[3]);
14959 //ni_log2(p_ctx, NI_LOG_DEBUG, "%s:mar16 HW=%d ui16FrameIdx=%d i8InstID=%d device_handle=%d\n",
14960 // ishwframe, p_data3->ui16FrameIdx, p_data3->i8InstID, p_data3->device_handle);
14961
14962 if (!p_ctx || !p_frame)
14963 {
14964 ni_log(NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
14965 __func__);
14966 retval = NI_RETCODE_INVALID_PARAM;
14967 LRETURN;
14968 }
14969
14970 uint8_t separate_metadata = p_frame->separate_metadata;
14971 uint8_t separate_start = (p_frame->separate_start && p_frame->total_start_len) ? 1 : 0;
14972
14973 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
14974 {
14975 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
14976 __func__);
14978 LRETURN;
14979 }
14980
14981#ifdef MEASURE_LATENCY
14982 if ((p_frame->pts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
14983 {
14984 uint64_t abs_time_ns = ni_gettime_ns();
14986 abs_time_ns, p_frame->pts);
14987 }
14988#endif
14989
14990 frame_size_bytes = p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2];// +p_frame->data_len[3] + p_frame->extra_data_len;
14991 ni_log2(p_ctx, NI_LOG_DEBUG, "frame size bytes =%u %d is metadata!\n", frame_size_bytes,
14992 0);
14993 p_ctx->status = 0;
14994
14995 if (p_frame->end_of_stream)
14996 {
14997 retval = NI_RETCODE_SUCCESS;
14998 LRETURN;
14999 }
15000
15001 if (p_ctx->buffered_frame_index > 0)
15002 {
15004 p_ctx->buffered_frame_index = 0;
15005 }
15006 else
15007 {
15008 for (;;)
15009 {
15010 query_sleep(p_ctx);
15011
15013 NI_DEVICE_TYPE_ENCODER, &buf_info);
15014 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15015 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15016 if (NI_RETCODE_SUCCESS != retval ||
15017 (buf_info.hw_inst_ind.buffer_avail == 0 && retry_count >= 500))
15018 {
15019 if (retry_count >= 500)
15020 {
15021 ni_log2(p_ctx, NI_LOG_DEBUG,
15022 "hwupload write exceeded max query retries. rc=%d try=%d"
15023 "\n",
15024 retval, retry_count);
15025 }
15028 LRETURN;
15029 }
15030 if (buf_info.hw_inst_ind.buffer_avail == 0 && retry_count < 500)
15031 {
15032 retry_count++;
15034 ni_usleep(100);
15036 } else //available
15037 {
15038 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: avail %d, FID %d\n", __func__,
15039 buf_info.hw_inst_ind.buffer_avail,
15040 buf_info.hw_inst_ind.frame_index);
15041 break;
15042 }
15043 }
15044 ni_log2(p_ctx, NI_LOG_DEBUG, "Info hwupload write query success, available buf "
15045 "size %u >= frame size %u , retry %u\n",
15046 buf_info.buf_avail_size, frame_size_bytes, retry_count);
15047 }
15048
15049 {
15050#ifdef XCODER_TIMESTAMP_DTS_ENABLED
15051 retval = ni_timestamp_register(p_ctx->buffer_pool, p_ctx->dts_queue,
15052 p_frame->dts, 0);
15053 if (NI_RETCODE_SUCCESS != retval)
15054 {
15055 ni_log2(p_ctx, NI_LOG_ERROR,
15056 "ERROR %s(): ni_timestamp_register() for dts "
15057 "returned: %d\n",
15058 __func__, retval);
15059 }
15060#endif
15061
15062 //Apply write configuration here
15063 retval = ni_config_session_rw(p_ctx, SESSION_WRITE_CONFIG, 1,
15066 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15067 CHECK_VPU_RECOVERY(retval);
15068
15069 if (separate_metadata)
15070 {
15072 "6S") < 0)
15073 {
15074 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): uploader separated metadata not supported on device with FW api version < 6.S\n",
15075 __func__);
15077 LRETURN;
15078 }
15079
15080 if (!p_frame->p_metadata_buffer)
15081 {
15082 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_metadata_buffer is NULL, allocation failed?\n",
15083 __func__);
15085 LRETURN;
15086 }
15087
15088 // fill in metadata
15090 p_meta = (ni_metadata_enc_frame_t *)p_frame->p_metadata_buffer;
15091
15092 if (separate_start)
15093 {
15094 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
15095 p_meta->start_len[i] = p_frame->start_len[i];
15096 }
15097 else
15098 {
15099 memset(p_meta->start_len, 0, sizeof(p_meta->start_len));
15100 }
15102
15103 ni_log(
15105 "%s(): %d.%u p_ctx->frame_num=%" PRIu64 ", "
15106 "p_frame->video_width=%u, p_frame->video_height=%u, "
15107 "start_len [%u,%u,%u] inconsecutive_transfer %u\n",
15108 __func__, p_ctx->hw_id, p_ctx->session_id, p_ctx->frame_num,
15109 p_frame->video_width, p_frame->video_height,
15110 p_meta->start_len[0], p_meta->start_len[1], p_meta->start_len[2],
15111 p_meta->inconsecutive_transfer);
15112
15113 uint32_t ui32LBA_metadata =
15115 ni_log2(p_ctx, NI_LOG_DEBUG,
15116 "%s: p_metadata_buffer = %p, metadata_buffer_size "
15117 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
15118 __func__, p_frame->p_metadata_buffer,
15119 p_frame->metadata_buffer_size, p_ctx->frame_num,
15120 ui32LBA_metadata);
15121
15122 sent_size =
15124
15125 retval = ni_nvme_send_write_cmd(
15126 p_ctx->blk_io_handle, p_ctx->event_handle,
15127 p_frame->p_metadata_buffer, sent_size,
15128 ui32LBA_metadata);
15129 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
15130 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15131 CHECK_VPU_RECOVERY(retval);
15132 if (retval < 0)
15133 {
15134 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n",
15135 __func__);
15137 LRETURN;
15138 }
15139 }
15140
15141 if (separate_start)
15142 {
15143 if (!p_frame->p_start_buffer)
15144 {
15145 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_start_buffer is NULL, allocation failed?\n",
15146 __func__);
15148 LRETURN;
15149 }
15150
15151 uint32_t ui32LBA =
15153 ni_log2(p_ctx, NI_LOG_DEBUG,
15154 "%s: p_start_buffer = %p, p_frame->start_buffer_size "
15155 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
15156 __func__, p_frame->p_start_buffer, p_frame->start_buffer_size, p_ctx->frame_num,
15157 ui32LBA);
15158
15159 sent_size =
15161
15162 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
15163 p_frame->p_start_buffer, sent_size, ui32LBA);
15164 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
15165 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15166 CHECK_VPU_RECOVERY(retval);
15167 if (retval < 0)
15168 {
15169 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
15171 LRETURN;
15172 }
15173 }
15174
15175 if (p_frame->inconsecutive_transfer)
15176 {
15177 uint32_t ui32LBA =
15179
15180 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
15181 {
15182 ni_log2(p_ctx, NI_LOG_DEBUG,
15183 "%s: p_data = %p, p_frame->buffer_size "
15184 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
15185 __func__, p_frame->p_data, p_frame->buffer_size, p_ctx->frame_num,
15186 ui32LBA);
15187
15188 if (p_frame->data_len[i])
15189 {
15190 sent_size = p_frame->data_len[i];
15191 if (separate_start)
15192 sent_size -= p_frame->start_len[i];
15193
15194 sent_size =
15196
15197 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
15198 p_frame->p_data[i]+p_frame->start_len[i], sent_size, ui32LBA);
15199 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
15200 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15201 CHECK_VPU_RECOVERY(retval);
15202 if (retval < 0)
15203 {
15204 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
15206 LRETURN;
15207 }
15208 }
15209 }
15210 }
15211 else
15212 {
15213 uint32_t ui32LBA =
15215 ni_log2(p_ctx, NI_LOG_DEBUG,
15216 "%s: p_data = %p, p_frame->buffer_size = %u, "
15217 "p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
15218 __func__, p_frame->p_data, p_frame->buffer_size, p_ctx->frame_num,
15219 ui32LBA);
15220
15221 sent_size = frame_size_bytes;
15222 if (separate_start)
15223 sent_size -= p_frame->total_start_len;
15224
15225 sent_size =
15227
15228 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
15229 p_frame->p_buffer+p_frame->total_start_len, sent_size, ui32LBA);
15230 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
15231 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15232 CHECK_VPU_RECOVERY(retval);
15233 if (retval < 0)
15234 {
15235 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
15237 LRETURN;
15238 }
15239 }
15240
15241 hwdesc->ui16FrameIdx = buf_info.hw_inst_ind.frame_index;
15242 hwdesc->ui16session_ID = p_ctx->session_id;
15243 hwdesc->device_handle =
15244 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
15245 hwdesc->bit_depth = p_ctx->bit_depth_factor;
15246 hwdesc->src_cpu = (uint8_t)NI_DEVICE_TYPE_ENCODER;
15247 hwdesc->output_idx = hwdesc->ui32nodeAddress = 0;
15248
15249 p_ctx->frame_num++;
15250 size = frame_size_bytes;
15251
15252#ifdef XCODER_DUMP_DATA
15253 char dump_file[256];
15254 snprintf(dump_file, sizeof(dump_file), "%ld-%u-hwup-fme/fme-%04ld.yuv",
15255 (long)getpid(), p_ctx->session_id, (long)p_ctx->frame_num);
15256
15257 FILE *f = NULL;
15258 ni_fopen(&f, dump_file, "wb");
15259 fwrite(p_frame->p_buffer,
15260 p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2],
15261 1, f);
15262 fflush(f);
15263 fclose(f);
15264#endif
15265 }
15266
15267#ifdef MEASURE_LATENCY
15268 if ((p_frame->pts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
15269 {
15270 uint64_t abs_time_ns = ni_gettime_ns();
15272 ni_log(NI_LOG_INFO, "PTS:%" PRId64 ",DELTA:%" PRId64 ",uLAT:%" PRIu64 ";\n",
15273 p_frame->pts, abs_time_ns - q->last_benchmark_time,
15274 ni_lat_meas_q_check_latency(q, abs_time_ns, p_frame->pts));
15275 q->last_benchmark_time = abs_time_ns;
15276 }
15277#endif
15278
15279 retval = size;
15280
15281END:
15282
15283 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
15284 return retval;
15285}
15286
15287/*!******************************************************************************
15288* \brief Retrieve a HW descriptor of uploaded frame
15289*
15290* \param p_ctx pointer to uploader session context
15291* hwdesc pointer to hw descriptor
15292*
15293* \return
15294* On success
15295* NI_RETCODE_SUCCESS
15296* On failure
15297* NI_RETCODE_INVALID_PARAM
15298* NI_RETCODE_ERROR_INVALID_SESSION
15299* NI_RETCODE_FAILURE
15300*******************************************************************************/
15302 niFrameSurface1_t *hwdesc)
15303{
15304 int retval = 0;
15305 ni_instance_buf_info_t hwdesc_info = { 0 };
15306 int query_retry = 0;
15307
15308 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
15309
15310 if (!p_ctx || !hwdesc)
15311 {
15312 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
15313 __func__);
15314 retval = NI_RETCODE_INVALID_PARAM;
15315 LRETURN;
15316 }
15317
15318 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
15319 {
15320 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
15321 __func__);
15323 LRETURN;
15324 }
15325
15326 for (;;)
15327 {
15328 query_sleep(p_ctx);
15329
15330 query_retry++;
15331#ifndef _WIN32
15333 NI_DEVICE_TYPE_ENCODER, &hwdesc_info);
15334#else
15336 NI_DEVICE_TYPE_ENCODER, &hwdesc_info);
15337#endif
15338 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15339 p_ctx->device_type, p_ctx->hw_id,
15340 &(p_ctx->session_id), OPT_1);
15341
15342 if (NI_RETCODE_SUCCESS != retval)
15343 {
15344 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning upload read hwdesc fail rc %d or ind "
15345 "!\n", retval);
15346
15347 if (query_retry >= 1000)
15348 {
15349 retval = NI_RETCODE_FAILURE;
15350 LRETURN;
15351 }
15352 ni_usleep(100);
15353 }
15354 else
15355 {
15356 ni_log2(p_ctx, NI_LOG_DEBUG, "Info hwupload read hwdesc success, "
15357 "frame_ind=%d !\n", hwdesc_info.hw_inst_ind.frame_index);
15358
15359 hwdesc->ui16FrameIdx = hwdesc_info.hw_inst_ind.frame_index;
15360 hwdesc->ui16session_ID = p_ctx->session_id;
15361 hwdesc->device_handle =
15362 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
15363 hwdesc->bit_depth = p_ctx->bit_depth_factor;
15364 hwdesc->src_cpu = (uint8_t)NI_DEVICE_TYPE_ENCODER;
15365 hwdesc->output_idx = 0;
15366 LRETURN;
15367 }
15368 }
15369
15370END:
15371 return retval;
15372}
15373
15374/*!*****************************************************************************
15375* \brief clear a particular xcoder instance buffer/data
15376*
15377* \param ni_session_context_t p_ctx - xcoder Context
15378* \param ni_instance_buf_info_rw_type_t rw_type
15379* \param ni_device_type_t device_type - xcoder type Encoder or Decoder
15380* \param ni_instance_buf_info_t *out - Struct preallocated from the caller
15381* where the resulting data will be placed
15382*
15383* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
15384* NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on
15385* failure
15386******************************************************************************/
15388{
15389 void* p_buffer = NULL;
15391 uint32_t ui32LBA = 0;
15392
15393 ni_log(NI_LOG_TRACE, "%s(): enter - device_handle %d\n", __func__,
15394 surface->device_handle);
15395
15396 if ((uint16_t)NI_INVALID_SESSION_ID == surface->ui16session_ID)
15397 {
15398 ni_log(NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
15399 __func__);
15401 LRETURN;
15402 }
15403
15404 //malloc data buffer
15405 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
15406 {
15407 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
15408 NI_ERRNO, __func__);
15410 LRETURN;
15411 }
15412 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
15413 ni_log(NI_LOG_DEBUG, "%s(): FID = %d\n", __func__, surface->ui16FrameIdx);
15414 ui32LBA = CLEAR_INSTANCE_BUF_W(((uint16_t)surface->ui16FrameIdx));
15415 retval = ni_nvme_send_write_cmd((ni_device_handle_t)(int64_t)surface->device_handle,
15416 NI_INVALID_DEVICE_HANDLE, p_buffer,
15417 NI_DATA_BUFFER_LEN, ui32LBA);
15418 //Cannot check sessio stats here since this isn't a session command.
15419 if (retval < 0)
15420 {
15421 ni_log(NI_LOG_ERROR, "[session_id=0x%x,time_stamp=%" PRIu64 "] " "%s(): NVME command Failed\n", surface->ui16session_ID, ni_log_get_utime(), __func__);
15423 LRETURN;
15424 }
15425
15426END:
15427
15428 ni_aligned_free(p_buffer);
15429 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
15430 return retval;
15431}
15432
15433/*!******************************************************************************
15434* \brief Retrieve a hw desc p_frame from decoder
15435* \param
15436*
15437* \return
15438*******************************************************************************/
15440{
15441 //Needs serious editing to support hwdesc read again, this is currently vanilla read
15442 //queue_info decoder_read_workerqueue;
15444 int rx_size = 0;
15445 uint64_t frame_offset = 0;
15446 uint32_t frame_dropped = 0;
15447 uint8_t *p_data_buffer = NULL;
15448 uint32_t i = 0;
15449 int retval = NI_RETCODE_SUCCESS;
15450 int metadata_hdr_size = NI_FW_META_DATA_SZ -
15452 int sei_size = 0;
15453 uint32_t total_bytes_to_read = 0;
15454 uint32_t total_yuv_met_size = 0;
15455 uint32_t read_size_bytes = 0;
15456 ni_instance_buf_info_t buf_info = {0};
15457 int query_retry = 0;
15458 uint32_t ui32LBA = 0;
15459 unsigned int bytes_read_so_far = 0;
15460 int query_type = INST_BUF_INFO_RW_READ;
15461 int low_delay_notify = 0;
15462 ni_session_statistic_t sessionStatistic = {0};
15463 uint32_t frames_dropped = 0;
15464 ni_xcoder_params_t *p_param;
15465 uint8_t get_first_metadata = 0;
15466 uint8_t sequence_change = 0;
15467
15468 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
15469
15470 if (!p_ctx || !p_frame)
15471 {
15472 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
15473 __func__);
15475 }
15476
15478
15479start:
15480 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
15481 {
15482 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
15483 __func__);
15485 LRETURN;
15486 }
15487
15488 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
15489 p_data_buffer = (uint8_t *)p_frame->p_buffer;
15490
15491 // p_frame->p_data[] can be NULL before actual resolution is returned by
15492 // decoder and buffer pool is allocated, so no checking here.
15493
15494 total_bytes_to_read = p_frame->data_len[3] + metadata_hdr_size;
15495 total_yuv_met_size = p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2] + metadata_hdr_size;
15496 ni_log2(p_ctx, NI_LOG_DEBUG,
15497 "Total bytes to read %u total_yuv_met_size %u, low_delay %u\n",
15498 total_bytes_to_read, total_yuv_met_size, p_ctx->decoder_low_delay);
15499 if (p_ctx->decoder_low_delay > 0 && !p_ctx->ready_to_close)
15500 {
15501 ni_log2(p_ctx, NI_LOG_DEBUG, "frame_num = %" PRIu64 ", pkt_num = %" PRIu64 "\n",
15502 p_ctx->frame_num, p_ctx->pkt_num);
15503 frames_dropped = p_ctx->session_statistic.ui32FramesDropped;
15504 if (p_ctx->force_low_delay && (p_ctx->force_low_delay_cnt < frames_dropped)) {
15505 p_ctx->force_low_delay_cnt = frames_dropped;
15506 }
15507 if (p_ctx->frame_num + p_ctx->force_low_delay_cnt
15508 >= p_ctx->pkt_num)
15509 {
15510 //nothing to query, leave
15511 retval = NI_RETCODE_SUCCESS;
15512 LRETURN;
15513 }
15514 query_type = INST_BUF_INFO_RW_READ_BUSY;
15515 }
15516 for (;;)
15517 {
15518 query_sleep(p_ctx);
15519
15520 query_retry++;
15521
15524 "6r3") >= 0)
15525 {
15527 &sessionStatistic);
15528 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
15530 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
15531 CHECK_VPU_RECOVERY(retval);
15532
15533 buf_info.buf_avail_size = sessionStatistic.ui32RdBufAvailSize;
15534 } else
15535 {
15536 retval = ni_query_instance_buf_info(p_ctx, query_type,
15537 NI_DEVICE_TYPE_DECODER, &buf_info);
15538 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15539 p_ctx->device_type, p_ctx->hw_id,
15540 &(p_ctx->session_id), OPT_1);
15541 CHECK_VPU_RECOVERY(retval);
15542 }
15543
15544 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read desc query buf_info.size = %u\n",
15545 buf_info.buf_avail_size);
15546
15547 if (NI_RETCODE_SUCCESS != retval)
15548 {
15549 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read desc failed. Retry %d\n", query_retry);
15550
15551 if (query_retry >= 1000)
15552 {
15553 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: dec read desc failed %d retries. rc=%d"
15554 "\n", query_retry, retval);
15555 p_ctx->max_retry_fail_count[1]++;
15556 low_delay_notify = 1;
15558 LRETURN;
15559 }
15563 } else if (buf_info.buf_avail_size == DP_IPC_PASSTHRU)
15564 {
15565 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Bad available buffer size %u\n", __FUNCTION__, buf_info.buf_avail_size);
15566 retval = NI_RETCODE_FAILURE;
15567 LRETURN;
15568 } else if (buf_info.buf_avail_size == metadata_hdr_size)
15569 {
15570 ni_log2(p_ctx, NI_LOG_DEBUG,
15571 "Dec read desc only hdr metadata is available. Seq change may "
15572 "have occured.\n");
15573 total_bytes_to_read = metadata_hdr_size;
15574 sequence_change = 1;
15575 break;
15576 } else if (buf_info.buf_avail_size < total_yuv_met_size)
15577 {
15578 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read desc buf_size < frame_size. Retry %d\n", query_retry);
15579
15580 // query to see if it is eos now, if we have sent it
15581 if (p_ctx->ready_to_close)
15582 {
15583 ni_log2(p_ctx, NI_LOG_TRACE,
15584 "Dec read desc query, ready_to_close %u, query eos\n",
15585 p_ctx->ready_to_close);
15586 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_DECODER, &data);
15587 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15588 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15589 CHECK_VPU_RECOVERY(retval);
15590
15591 if (data.is_flushed ||
15592 query_retry >=
15594 {
15595 if (query_retry >=
15597 {
15598 ni_log2(p_ctx, NI_LOG_ERROR,
15599 "WARNING: Dec read desc query eos reached but exceeded max "
15600 "retries. is_flushed=%u try=%d.\n",
15601 data.is_flushed, query_retry);
15602 } else
15603 {
15604 ni_log2(p_ctx, NI_LOG_DEBUG,
15605 "Dec read desc query eos reached. is_flushed=%u try=%d"
15606 "\n",
15607 data.is_flushed, query_retry);
15608 }
15609 p_frame->end_of_stream = 1;
15610 low_delay_notify = 1;
15611 retval = NI_RETCODE_SUCCESS;
15612 LRETURN;
15613 }
15614 else
15615 {
15616 ni_log2(p_ctx, NI_LOG_TRACE,
15617 "Dec read desc available buf size == %d, query try %d, "
15618 "retrying...\n",
15619 buf_info.buf_avail_size, query_retry);
15623 continue;
15624 }
15625 }
15626
15628 (p_ctx->decoder_low_delay > 0 &&
15629 ((p_ctx->frame_num + p_ctx->force_low_delay_cnt)
15630 < p_ctx->pkt_num))) &&
15631 query_retry < 1000 / 2)
15632 {
15633 if (p_ctx->decoder_low_delay && p_ctx->force_low_delay) {
15634 if (p_ctx->session_statistic.ui32FramesDropped > frames_dropped) {
15635 // last pkt sent to decoder marked as dropped, no output,
15636 // so just stop query and return
15637 p_ctx->force_low_delay_cnt++;
15638 low_delay_signal(p_ctx);
15639 retval = NI_RETCODE_SUCCESS;
15640 LRETURN;
15641 }
15642 } else if (NI_RETCODE_NVME_SC_WRITE_BUFFER_FULL == p_ctx->status &&
15643 sessionStatistic.ui32WrBufAvailSize > p_ctx->required_buf_size)
15644 {
15645 ni_log2(p_ctx, NI_LOG_TRACE, "Info dec write buffer is enough, available buf "
15646 "size %u >= required size %u !\n",
15647 sessionStatistic.ui32WrBufAvailSize, p_ctx->required_buf_size);
15648 p_ctx->status = 0;
15649 p_ctx->required_buf_size = 0;
15650 retval = NI_RETCODE_SUCCESS;
15651 LRETURN;
15652 }
15656
15657 continue;
15658 } else
15659 {
15660 if (p_ctx->decoder_low_delay > 0)
15661 {
15662 if (p_ctx->force_low_delay) {
15663 p_ctx->force_low_delay_cnt++;
15664 low_delay_signal(p_ctx);
15665 } else {
15666 ni_log2(p_ctx, NI_LOG_ERROR,"Warning: low delay mode with non sequential "
15667 "input (B frames)? Just cancel the low delay mode then\n");
15668 // Here it should be the last signal to release the send thread
15669 // holding the low delay mutex.
15670 low_delay_signal(p_ctx);
15671 p_ctx->decoder_low_delay = 0;
15672 }
15673 }
15674
15675 if ((p_param->dec_input_params.min_packets_delay && p_ctx->pkt_delay_cnt))
15676 {
15677 if(p_ctx->pkt_num >= (p_ctx->frame_num + p_ctx->pkt_delay_cnt +
15679 {
15680 if(query_retry <= 2000)
15681 {
15683 ni_usleep(25);
15685 continue;
15686 } else {
15687 p_ctx->pkt_delay_cnt++;
15688 ni_log2(p_ctx, NI_LOG_ERROR,
15689 "Warning: decoder pkt_num %u frame_num %u "
15690 "timeout, increasing pkt_delay_cnt to %u\n",
15691 p_ctx->pkt_num, p_ctx->frame_num,
15692 p_ctx->pkt_delay_cnt);
15693 }
15694 }
15695 }
15696 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: dec read desc failed %d retries. rc=%d"
15697 "\n", query_retry, retval);
15698 }
15699 retval = NI_RETCODE_SUCCESS;
15700 LRETURN;
15701 }
15702 else
15703 {
15704 // We have to ensure there are adequate number of DTS for picture
15705 // reorder delay otherwise wait for more packets to be sent to decoder.
15706 ni_timestamp_table_t *p_dts_queue = p_ctx->dts_queue;
15707 if ((int)p_dts_queue->list.count < p_ctx->pic_reorder_delay + 1 &&
15708 !p_ctx->ready_to_close &&
15710 {
15711 retval = NI_RETCODE_SUCCESS;
15712 ni_log2(p_ctx, NI_LOG_DEBUG,
15713 "At least %d packets should be sent before reading the "
15714 "first frame!\n",
15715 p_ctx->pic_reorder_delay + 1);
15716 LRETURN;
15717 }
15718 p_ctx->max_retry_fail_count[1] = 0;
15719
15720 // get actual YUV transfer size if this is the stream's very first read
15721 if (0 == p_ctx->active_video_width || 0 == p_ctx->active_video_height)
15722 {
15723 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_DECODER, &data);
15724 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15725 p_ctx->device_type, p_ctx->hw_id,
15726 &(p_ctx->session_id), OPT_1);
15727 CHECK_VPU_RECOVERY(retval);
15728
15729 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec YUV query, pic size %ux%u xfer frame size "
15730 "%ux%u frame-rate %u is_flushed %u\n",
15731 data.picture_width, data.picture_height,
15733 data.frame_rate, data.is_flushed);
15736 p_ctx->actual_video_width = data.picture_width;
15737 p_ctx->pixel_format = data.pix_format;
15739 //p_ctx->bit_depth_factor = data.transfer_frame_stride / data.picture_width;
15740 p_ctx->is_first_frame = 1;
15741 p_ctx->pixel_format_changed = 0;
15742
15743 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec YUV, adjust frame size from %ux%u to "
15744 "%ux%u\n", p_frame->video_width, p_frame->video_height,
15746
15747 retval = ni_frame_buffer_alloc(
15748 p_frame, p_ctx->actual_video_width, p_ctx->active_video_height,
15750 p_ctx->bit_depth_factor,
15751 3, // Alloc space for write to data[3] and metadata
15752 1);
15753
15754 if (NI_RETCODE_SUCCESS != retval)
15755 {
15756 LRETURN;
15757 }
15758 total_bytes_to_read = p_frame->data_len[3] + metadata_hdr_size;
15759 p_data_buffer = (uint8_t*)p_frame->p_buffer;
15760 // make sure we don't read more than available
15761 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec buf size: %u YUV frame + meta-hdr size: %u "
15762 "available: %u\n", p_frame->buffer_size,
15763 total_bytes_to_read, buf_info.buf_avail_size);
15764 }
15765 break;
15766 }
15767 }// end while1 query retry
15768
15769 ni_log2(p_ctx, NI_LOG_DEBUG, "total_bytes_to_read %u max_nvme_io_size %u ylen %u cr len "
15770 "%u cb len %u hdr %d\n",
15771 total_bytes_to_read, p_ctx->max_nvme_io_size,
15772 p_frame->data_len[0], p_frame->data_len[1],
15773 p_frame->data_len[2], metadata_hdr_size);
15774
15775 ni_log2(p_ctx, NI_LOG_DEBUG, "p_frame->data_len[3] = %u\n", p_frame->data_len[3]);
15776 if (buf_info.buf_avail_size < total_bytes_to_read)
15777 {
15779
15780 ni_log2(p_ctx, NI_LOG_ERROR,
15781 "ERROR %s() avaliable size(%u) less than "
15782 "needed (%u)\n",
15783 __func__, buf_info.buf_avail_size, total_bytes_to_read);
15784 abort();
15785 } else if (total_bytes_to_read == metadata_hdr_size && !p_ctx->frame_num)
15786 {
15789 "6rE") >= 0)
15790 {
15791 // allocate p_data_buffer to read the first metadata
15792 void *p_metadata_buffer = NULL;
15793 int buffer_size = ((metadata_hdr_size + (NI_MEM_PAGE_ALIGNMENT - 1)) /
15795 if (ni_posix_memalign(&p_metadata_buffer, sysconf(_SC_PAGESIZE), buffer_size))
15796 {
15797 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate metadata buffer.\n",
15798 NI_ERRNO, __func__);
15800 LRETURN;
15801 }
15802 p_data_buffer = (uint8_t *)p_metadata_buffer;
15803 get_first_metadata = 1;
15804 sequence_change = 0;
15805 }
15806 }
15807
15808 //Apply read configuration here
15809 retval = ni_config_session_rw(p_ctx, SESSION_READ_CONFIG, 1,
15811 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
15812 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15813 CHECK_VPU_RECOVERY(retval);
15814
15815 read_size_bytes = total_bytes_to_read;
15817 if (read_size_bytes % NI_MEM_PAGE_ALIGNMENT)
15818 {
15819 read_size_bytes = ( (read_size_bytes / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
15820 }
15821
15822 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
15823 p_data_buffer, read_size_bytes, ui32LBA);
15824 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
15825 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15826 CHECK_VPU_RECOVERY(retval);
15827 if (retval < 0)
15828 {
15829 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
15831 LRETURN;
15832 } else if (get_first_metadata) {
15833 // got first metadata alone
15834 ni_metadata_dec_frame_t *p_meta =
15835 (ni_metadata_dec_frame_t *)((uint8_t *)p_data_buffer);
15836 ni_log2(p_ctx, NI_LOG_DEBUG, "Got first pkt_delay_cnt %u\n",
15838 if (p_ctx->pkt_delay_cnt < p_meta->metadata_common.pkt_delay_cnt)
15840 get_first_metadata = 0;
15841 ni_aligned_free(p_data_buffer);
15842 goto start;
15843 } else
15844 {
15845 // command issued successfully, now exit
15847 p_meta =
15848 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
15849 p_frame->data_len[0] +
15850 p_frame->data_len[1] +
15851 p_frame->data_len[2] +
15852 p_frame->data_len[3]);
15853
15854 if (buf_info.buf_avail_size != metadata_hdr_size)
15855 {
15856 low_delay_notify = 1;
15857 // shift metadata to end of triple output
15858#ifdef _WIN32
15859 p_data_buffer = (uint8_t *)p_frame->p_buffer +
15861 memcpy(p_meta, p_data_buffer, metadata_hdr_size);
15862#else
15863 memcpy(p_meta,
15864 p_frame->p_buffer +
15866 metadata_hdr_size);
15867#endif
15868 sei_size = p_meta->sei_size;
15869 niFrameSurface1_t *p_data3 =
15870 (niFrameSurface1_t *)((uint8_t *)p_frame->p_buffer +
15871 p_frame->data_len[0] +
15872 p_frame->data_len[1] +
15873 p_frame->data_len[2]);
15874
15875 niFrameSurface1_t *p_data3_1 =
15876 (niFrameSurface1_t *)((uint8_t *)p_frame->p_buffer +
15877 sizeof(niFrameSurface1_t));
15878 niFrameSurface1_t *p_data3_2 =
15879 (niFrameSurface1_t *)((uint8_t *)p_frame->p_buffer +
15880 2 * sizeof(niFrameSurface1_t));
15881 // Libxcoder knows the handle so overwrite here
15882 p_data3->device_handle =
15883 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
15884 p_data3_1->device_handle =
15885 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
15886 p_data3_2->device_handle =
15887 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
15888 p_data3->ui16session_ID = p_data3_1->ui16session_ID =
15889 p_data3_2->ui16session_ID = (uint16_t)p_ctx->session_id;
15890 p_data3->src_cpu = p_data3_1->src_cpu = p_data3_2->src_cpu =
15891 (uint8_t)NI_DEVICE_TYPE_DECODER;
15892
15893 p_data3->output_idx = 0;
15894 p_data3_1->output_idx = 1;
15895 p_data3_2->output_idx = 2;
15896
15897 ni_log2(p_ctx, NI_LOG_DEBUG,
15898 "p_data3_1:sei_size=%d device_handle=%d == hw_id=%d ses_id=%d\n",
15899 sei_size, p_data3_1->device_handle, p_ctx->hw_id,
15900 p_data3_1->ui16session_ID);
15901 ni_log2(p_ctx, NI_LOG_DEBUG,
15902 "p_data3_1: ui16FrameIdx=%d NodeAddre=0x%x planar=%d bd=%d\n",
15903 p_data3_1->ui16FrameIdx, p_data3_1->ui32nodeAddress,
15904 p_data3_1->encoding_type, p_data3_1->bit_depth);
15905 ni_log2(p_ctx,
15907 "p_data3_2:sei_size=%d device_handle=%d == hw_id=%d ses_id=%d\n",
15908 sei_size, p_data3_2->device_handle, p_ctx->hw_id,
15909 p_data3_2->ui16session_ID);
15910 ni_log2(p_ctx, NI_LOG_DEBUG,
15911 "p_data3_2: ui16FrameIdx=%d NodeAddre=0x%x planar=%d bd=%d\n",
15912 p_data3_2->ui16FrameIdx, p_data3_2->ui32nodeAddress,
15913 p_data3_2->encoding_type, p_data3_2->bit_depth);
15914
15915 ni_log2(p_ctx, NI_LOG_DEBUG,
15916 "%s:sei_size=%d device_handle=%d == hw_id=%d "
15917 "ses_id=%d\n",
15918 __func__, sei_size, p_data3->device_handle, p_ctx->hw_id,
15919 p_data3->ui16session_ID);
15920 ni_log2(p_ctx, NI_LOG_DEBUG,
15921 "%s: session=0x%x ui16FrameIdx=%u NodeAddress=0x%x, "
15922 "planar=%d bd=%d\n",
15923 __func__, p_ctx->session_id, p_data3->ui16FrameIdx, p_data3->ui32nodeAddress,
15924 p_data3->encoding_type, p_data3->bit_depth);
15925 } else if (ni_cmp_fw_api_ver(
15927 "6rE") >= 0)
15928 {
15929 p_meta =
15930 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer);
15931 ni_log2(p_ctx, NI_LOG_DEBUG, "Got pkt_delay_cnt %u\n",
15933 if (p_ctx->pkt_delay_cnt < p_meta->metadata_common.pkt_delay_cnt)
15935 }
15936
15937 total_bytes_to_read = total_bytes_to_read + sei_size;
15938 ni_log2(p_ctx, NI_LOG_DEBUG,
15939 "%s decoder read desc success, retval %d "
15940 "total_bytes_to_read include sei %u sei_size %d\n",
15941 __func__, retval, total_bytes_to_read, sei_size);
15942
15943 if (total_bytes_to_read > NI_MEM_PAGE_ALIGNMENT)
15944 {
15945 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Oversized metadata!\n", __func__);
15947 LRETURN;
15948 }
15949 }
15950
15951 //bytes_read_so_far = total_bytes_to_read;
15952 // Note: session status is NOT reset but tracked between send
15953 // and recv to catch and recover from a loop condition
15954 //total_bytes_to_read = p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2] + p_frame->data_len[3] + metadata_hdr_size + sei_size; //since only HW desc
15955 bytes_read_so_far = total_bytes_to_read;
15956 //bytes_read_so_far = p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2] + p_frame->data_len[3] + metadata_hdr_size + sei_size; //since only HW desc
15958 "6sP") >= 0)
15959 {
15960 rx_size = ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, &frame_dropped, true);
15961 }
15962 else
15963 {
15964 rx_size = ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, 0, true);
15965 }
15966 p_ctx->frame_pkt_offset = frame_offset;
15967 if (p_ctx->decoder_low_delay > 0 && buf_info.buf_avail_size == metadata_hdr_size &&
15969 {
15970 ni_log2(p_ctx, NI_LOG_TRACE, "Low delay mode amd check header if has b frame\n");
15971
15972 ni_metadata_dec_frame_t *p_meta =
15973 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
15974 p_frame->data_len[0] +
15975 p_frame->data_len[1] +
15976 p_frame->data_len[2]);
15977 if (p_meta->metadata_common.has_b_frame == 1)
15978 {
15979 ni_log2(p_ctx, NI_LOG_ERROR,"Warning: session 0x%x decoder lowDelay mode "
15980 "is cancelled due to has_b_frames, frame_num %u\n",
15981 p_ctx->session_id, p_ctx->frame_num);
15982 p_ctx->decoder_low_delay = 0;
15983 }
15984 }
15985
15986 if (rx_size > 0)
15987 {
15988 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): s-state %d first_frame %d\n", __func__,
15989 p_ctx->session_run_state, p_ctx->is_first_frame);
15990
15991 int64_t tmp_dts, prev_dts = INT64_MIN, ts_diff = 0;
15992 int nb_diff = 0;
15993
15995 "6sP") >= 0)
15996 {
15997 if(p_ctx->last_frame_dropped + frame_dropped != p_ctx->session_statistic.ui32FramesDropped)
15998 {
15999 ni_log2(p_ctx, NI_LOG_DEBUG,
16000 "### %s(): Warning: ui32FramesDropped %u should be %u + %u\n",
16001 __func__, p_ctx->session_statistic.ui32FramesDropped,
16002 p_ctx->last_frame_dropped, frame_dropped);
16003
16004 p_ctx->session_statistic.ui32FramesDropped = p_ctx->last_frame_dropped + frame_dropped;
16005 }
16006
16008 }
16009
16010 if (p_ctx->is_first_frame)
16011 {
16012 ni_log2(p_ctx, NI_LOG_DEBUG,
16013 "%s(): First frame : session_id 0x%x, pic_reorder_delay: %d "
16014 "total frames input:%u buffered: %u completed: %u output: %u "
16015 "dropped: %u (%u %u) error: %u\n",
16016 __func__, p_ctx->session_id, p_ctx->pic_reorder_delay,
16022 p_ctx->last_frame_dropped, frame_dropped,
16024
16025 if (p_ctx->session_statistic.ui32FramesDropped > 0)
16026 {
16027 for (i = 0; i < p_ctx->session_statistic.ui32FramesDropped; i++)
16028 {
16030 p_ctx->dts_queue, 0, &tmp_dts,
16033 {
16034 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): FramesDropped pop "
16035 "decoder dts queue %d %ld failed !\n",
16036 __func__, i, tmp_dts);
16037 break;
16038 } else
16039 {
16040 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop "
16041 "decoder dts queue %d %ld success !\n",
16042 __func__, i, tmp_dts);
16043 if (prev_dts != INT64_MIN) {
16044 ts_diff += llabs(tmp_dts - prev_dts);
16045 nb_diff++;
16046 }
16047 prev_dts = tmp_dts;
16048 }
16049 }
16050 if (nb_diff > 1)
16051 {
16052 ts_diff = ts_diff / nb_diff;
16053 }
16055 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop dts "
16056 "average diff: %ld\n", __func__, ts_diff);
16057 }
16058 }
16059 else
16060 {
16062 {
16063 for(i = p_ctx->decoder_last_drop_frame_num; i < p_ctx->session_statistic.ui32FramesDropped; i++)
16064 {
16066 p_ctx->dts_queue, 0, &tmp_dts,
16069 {
16070 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): FramesDropped pop "
16071 "decoder dts queue %d %ld failed !\n",
16072 __func__, i, tmp_dts);
16073 break;
16074 }
16075 }
16077 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop dts %d\n", __func__, p_ctx->decoder_last_drop_frame_num);
16078 }
16079 }
16080
16082 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
16085 {
16086 if (p_ctx->last_dts != NI_NOPTS_VALUE && !p_ctx->ready_to_close)
16087 {
16088 p_ctx->pic_reorder_delay++;
16089 p_frame->dts = p_ctx->last_dts + p_ctx->last_dts_interval;
16090 ni_log2(p_ctx, NI_LOG_DEBUG, "Padding DTS: %" PRId64 "\n", p_frame->dts);
16091 } else
16092 {
16093 p_frame->dts = NI_NOPTS_VALUE;
16094 }
16095 }
16096
16097 if (p_ctx->is_first_frame)
16098 {
16099 for (i = 0; (int)i < p_ctx->pic_reorder_delay; i++)
16100 {
16101 if (p_ctx->last_pts == NI_NOPTS_VALUE &&
16102 p_ctx->last_dts == NI_NOPTS_VALUE)
16103 {
16104 // If the p_frame->pts is unknown in the very beginning we assume
16105 // p_frame->pts == 0 as well as DTS less than PTS by 1000 * 1/timebase
16106 if (p_frame->pts >= p_frame->dts &&
16107 p_frame->pts - p_frame->dts < 1000)
16108 {
16109 break;
16110 }
16111 }
16112
16114 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
16116 p_ctx->frame_num % 500 == 0,
16118 {
16119 p_frame->dts = NI_NOPTS_VALUE;
16120 } else
16121 {
16122 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): pic_reorder_delay pop "
16123 "decoder dts queue %d %ld success !\n",
16124 __func__, i, p_frame->dts);
16125 }
16126 }
16127 // Reset for DTS padding counting
16128 p_ctx->pic_reorder_delay = 0;
16129 }
16130 if (p_ctx->codec_format == NI_CODEC_FORMAT_JPEG)//fw won't save frameoffset when decoding jpeg.
16131 {
16132 if (p_ctx->is_first_frame)
16133 {
16134 p_ctx->is_first_frame = 0;
16135 }
16136 p_frame->pts = p_ctx->pts_offsets[p_ctx->frame_num % NI_FIFO_SZ];
16137 p_frame->flags = p_ctx->flags_array[p_ctx->frame_num % NI_FIFO_SZ];
16138 p_frame->pkt_pos = p_ctx->pkt_pos[p_ctx->frame_num % NI_FIFO_SZ];
16139 ni_log2(p_ctx, NI_LOG_DEBUG, "p_frame->pts = %u, frame_num = %d, p_frame->dts = %u\n",
16140 p_frame->pts, p_ctx->frame_num, p_frame->dts);
16141 }
16142 else
16143 {
16144 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: frame_offset %" PRIu64 "\n", __func__,
16145 frame_offset);
16146
16147 // search for the pkt_offsets of received frame according to frame_offset.
16148 // here we get the index(i) which promises (p_ctx->pkt_offsets_index_min[i] <= frame_offset && p_ctx->pkt_offsets_index[i] > frame_offset)
16149 // i = -1 if not found
16150 int j = 0;
16151 j = rotated_array_binary_search(p_ctx->pkt_offsets_index_min,
16153 frame_offset);
16154 if (j >= 0)
16155 {
16156 p_frame->pts = p_ctx->pts_offsets[j];
16157 p_frame->flags = p_ctx->flags_array[j];
16158 p_frame->pkt_pos = p_ctx->pkt_pos[j];
16159 ni_log2(p_ctx, NI_LOG_DEBUG,
16160 "%s: (found pts) dts %" PRId64 " pts "
16161 "%" PRId64 " frame_offset %" PRIu64 " j %d "
16162 "pkt_offsets_index_min %" PRIu64 " "
16163 "pkt_offsets_index %" PRIu64 " pkt_pos %" PRIu64 "\n",
16164 __func__, p_frame->dts, p_frame->pts, frame_offset, j,
16165 p_ctx->pkt_offsets_index_min[j],
16166 p_ctx->pkt_offsets_index[j],
16167 p_ctx->pkt_pos[j]);
16168
16169 if (p_ctx->is_first_frame)
16170 {
16171 // if the first frame is I frame and there are dropped frames,
16172 // find the dts closest to its pts using the average of dts diff
16173 if (p_frame->dts != NI_NOPTS_VALUE &&
16174 p_frame->pts != NI_NOPTS_VALUE &&
16175 PIC_TYPE_I == p_frame->ni_pict_type &&
16177 ts_diff > 0)
16178 {
16179 while (p_frame->dts < p_frame->pts &&
16180 llabs(p_frame->pts - p_frame->dts) > ts_diff)
16181 {
16182 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: First I frame pts %ld "
16183 "dts %ld diff. %ld > ts_diff %ld\n",
16184 __func__, p_frame->pts, p_frame->dts,
16185 llabs(p_frame->pts - p_frame->dts), ts_diff);
16186
16188 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
16190 {
16191 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): First I frame "
16192 "pop decoder dts queue error.\n", __func__);
16193 break;
16194 }
16195 }
16196 }
16197 }
16198
16199 p_frame->p_custom_sei_set = p_ctx->pkt_custom_sei_set[j];
16200 p_ctx->pkt_custom_sei_set[j] = NULL;
16201 } else
16202 {
16203 //backup solution pts
16204 if (p_param->dec_input_params.skip_pts_guess && p_ctx->last_pts != NI_NOPTS_VALUE)
16205 {
16206 // if skip guess_correct_pts, use pts interval to get the correct pts
16207 p_frame->pts = p_ctx->last_pts + (p_ctx->last_pts_interval > 0 ? p_ctx->last_pts_interval : 1);
16208 }
16209 else
16210 {
16211 p_frame->pts = p_ctx->last_pts + (p_frame->dts - p_ctx->last_dts);
16212 }
16213 p_frame->pkt_pos = p_ctx->last_pkt_pos + (frame_offset - p_ctx->last_frame_offset);
16214 ni_log2(p_ctx, NI_LOG_ERROR,
16215 "ERROR: Frame pts %" PRId64 " not found for offset "
16216 "%" PRIu64 "\n", p_frame->pts, frame_offset);
16217 ni_log2(p_ctx, NI_LOG_DEBUG,
16218 "%s: (not found use default) dts %" PRId64 " pts %" PRId64
16219 "\n",
16220 __func__, p_frame->dts, p_frame->pts);
16221 }
16222
16223 if (p_ctx->is_first_frame)
16224 {
16225 p_ctx->is_first_frame = 0;
16226 }
16227 }
16228
16229 p_frame->orignal_pts = p_frame->pts;
16230 p_ctx->last_pkt_pos = p_frame->pkt_pos;
16231 p_ctx->last_frame_offset = frame_offset;
16232 if (!p_param->dec_input_params.skip_pts_guess)
16233 p_frame->pts = guess_correct_pts(p_ctx, p_frame->pts, p_frame->dts);
16234 if (p_frame->pts != NI_NOPTS_VALUE && p_ctx->last_pts != NI_NOPTS_VALUE)
16235 p_ctx->last_pts_interval = p_frame->pts - p_ctx->last_pts;
16236 p_ctx->last_pts = p_frame->pts;
16237 if (p_frame->dts != NI_NOPTS_VALUE && p_ctx->last_dts != NI_NOPTS_VALUE)
16238 p_ctx->last_dts_interval = p_frame->dts - p_ctx->last_dts;
16239 p_ctx->last_dts = p_frame->dts;
16240 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: (best_effort_timestamp) pts %" PRId64 "\n",
16241 __func__, p_frame->pts);
16242 p_ctx->frame_num++;
16243
16245 if (p_frame->error_ratio > 0)
16246 {
16247 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: frame number = %d, error_ratio = %u\n",
16248 __func__, p_ctx->frame_num, p_frame->error_ratio);
16249 }
16250
16251 if (p_ctx->ppu_reconfig_pkt_pos != 0 &&
16253 {
16254 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: ppu reconfig done. ppu_reconfig_pkt_pos = %u, frame_num = %u droped = %u\n",
16255 __func__, p_ctx->ppu_reconfig_pkt_pos, p_ctx->frame_num, p_ctx->session_statistic.ui32FramesDropped);
16256 p_ctx->ppu_reconfig_pkt_pos = 0;
16257 }
16258#ifdef MEASURE_LATENCY
16259#ifndef XCODER_311
16260 ni_log2(p_ctx, NI_LOG_INFO, "DEC pkt_num %d, fme_num %d, latecy is %d\n",
16261 p_ctx->pkt_num, p_ctx->frame_num, p_ctx->pkt_num - p_ctx->frame_num);
16262#endif
16263#endif
16264
16265 }
16266
16267 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): received data: [0x%08x]\n", __func__, rx_size);
16268 ni_log2(p_ctx, NI_LOG_DEBUG,
16269 "%s(): p_frame->start_of_stream=%u, "
16270 "p_frame->end_of_stream=%u, p_frame->video_width=%u, "
16271 "p_frame->video_height=%u\n",
16272 __func__, p_frame->start_of_stream, p_frame->end_of_stream,
16273 p_frame->video_width, p_frame->video_height);
16274 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): p_frame->data_len[0/1/2]=%u/%u/%u\n", __func__,
16275 p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2]);
16276
16277 if (p_ctx->frame_num % 500 == 0)
16278 {
16279 ni_log2(p_ctx, NI_LOG_DEBUG,
16280 "Decoder pts queue size = %d dts queue size = %d\n\n",
16281 p_ctx->pts_table->list.count, p_ctx->dts_queue->list.count);
16282 // scan and clean up
16284 p_ctx->buffer_pool);
16285 }
16286
16287#ifdef MEASURE_LATENCY
16288 if ((p_frame->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
16289 {
16290 uint64_t abs_time_ns = ni_gettime_ns();
16292 ni_log2(p_ctx, NI_LOG_INFO, "DTS:%" PRId64 ",DELTA:%" PRId64 ",dLAT:%" PRIu64 ";\n",
16293 p_frame->dts, abs_time_ns - q->last_benchmark_time,
16294 ni_lat_meas_q_check_latency(q, abs_time_ns, p_frame->dts));
16295 q->last_benchmark_time = abs_time_ns;
16296 }
16297#endif
16298
16299END:
16300
16302
16303 if (get_first_metadata && p_data_buffer)
16304 ni_aligned_free(p_data_buffer);
16305 if (sequence_change && p_ctx->frame_num)
16306 {
16307 if (p_ctx->actual_video_width == p_frame->video_width &&
16308 p_ctx->active_video_height == p_frame->video_height)
16309 {
16310 p_ctx->pixel_format_changed = 1;
16311 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): format changed\n", __func__);
16312 }
16313 }
16314 if (NI_RETCODE_SUCCESS != retval)
16315 {
16316 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): bad exit, retval = %d\n", __func__, retval);
16317 if (retval == NI_RETCODE_ERROR_VPU_RECOVERY)
16318 {
16319 low_delay_signal(p_ctx);
16320 }
16321
16322 return retval;
16323 } else
16324 {
16325 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit, rx_size = %d\n", __func__, rx_size);
16326 if (low_delay_notify)
16327 {
16328 low_delay_signal(p_ctx);
16329 }
16330
16331 return rx_size;
16332 }
16333}
16334
16335/*!******************************************************************************
16336* \brief Retrieve a YUV p_frame from decoder
16337*
16338* \param
16339*
16340* \return
16341*******************************************************************************/
16343{
16344 int retval = NI_RETCODE_SUCCESS;
16345 int rx_size = 0;
16346 uint64_t frame_offset = 0;
16347 uint8_t *p_data_buffer;
16348 int metadata_hdr_size = NI_FW_META_DATA_SZ -
16350 uint32_t total_bytes_to_read = 0;
16351 uint32_t read_size_bytes = 0;
16352 uint32_t ui32LBA = 0;
16353
16354 //ni_log2(p_ctx, NI_LOG_DEBUG, "hwcontext.c:ni_hwdl_frame() hwdesc %d %d %d\n",
16355 // hwdesc->ui16FrameIdx,
16356 // hwdesc->i8InstID,
16357 // hwdesc->ui16session_ID);
16358
16359 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
16360
16361 if ((!p_ctx) || (!p_frame))
16362 {
16363 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
16364 __func__);
16366 }
16367
16368 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
16369 {
16370 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
16371 __func__);
16373 LRETURN;
16374 }
16375
16376 p_data_buffer = (uint8_t *)p_frame->p_buffer;
16377
16378 if (!p_frame->p_data[0] || !p_data_buffer)
16379 {
16380 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): No receive buffer allocated.\n",
16381 __func__);
16382 retval = NI_RETCODE_INVALID_PARAM;
16383 LRETURN;
16384 }
16385
16386 if (0 == p_frame->data_len[0])
16387 {
16388 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_frame->data_len[0] = 0!.\n",
16389 __func__);
16390 retval = NI_RETCODE_INVALID_PARAM;
16391 LRETURN;
16392 }
16393
16395 {
16396 p_frame->data_len[2] = 0;
16397 } else if (hwdesc->encoding_type == NI_PIXEL_PLANAR_FORMAT_TILED4X4)
16398 {
16399 ni_log2(p_ctx, NI_LOG_ERROR,
16400 "ERROR %s(): NI_PIXEL_PLANAR_FORMAT_TILED4X4 not supported in download.\n",
16401 __func__);
16402 retval = NI_RETCODE_INVALID_PARAM;
16403 LRETURN;
16404 }
16405 total_bytes_to_read = p_frame->data_len[0] + p_frame->data_len[1] +
16406 p_frame->data_len[2];// +metadata_hdr_size;
16407 unsigned int bytes_read_so_far = 0;
16408 uint32_t output_chunk_offset = hwdesc->ui32nodeAddress / FRAME_CHUNK_INDEX_SIZE; //for reading output1 or output2
16409 uint32_t output_minor_offset = hwdesc->ui32nodeAddress - output_chunk_offset * FRAME_CHUNK_INDEX_SIZE;
16410 ni_log2(p_ctx, NI_LOG_DEBUG, "Total bytes to download %u, start offset = %u, chunkOffset "
16411 "%u, minorOffset %u\n",
16412 total_bytes_to_read, hwdesc->ui32nodeAddress,
16413 output_chunk_offset, output_minor_offset);
16414
16415 ni_log2(p_ctx, NI_LOG_DEBUG, "total_bytes_to_read %u max_nvme_io_size %u ylen %u cr len "
16416 "%u cb len %u hdr %d\n",
16417 total_bytes_to_read, p_ctx->max_nvme_io_size,
16418 p_frame->data_len[0], p_frame->data_len[1],
16419 p_frame->data_len[2], metadata_hdr_size);
16420
16421 //Apply read configuration here
16422 retval =
16424 (output_minor_offset << NI_CODEC_HW_PAYLOAD_OFFSET) |
16426 hwdesc->ui16FrameIdx);
16427 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, hwdesc->src_cpu,
16428 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
16429 CHECK_VPU_RECOVERY(retval);
16430 if (retval < 0)
16431 {
16432 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
16434 LRETURN;
16435 } else
16436 {
16437 ni_log2(p_ctx, NI_LOG_DEBUG,
16438 "Config HW download read desc success, retval %d total_bytes_to_read %u\n",
16439 retval, total_bytes_to_read);
16440 }
16441
16442 read_size_bytes = total_bytes_to_read;
16443 ui32LBA = READ_INSTANCE_R(p_ctx->session_id, hwdesc->src_cpu);
16444 ui32LBA += output_chunk_offset;
16445 if (read_size_bytes % NI_MEM_PAGE_ALIGNMENT)
16446 {
16447 read_size_bytes = ( (read_size_bytes / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
16448 }
16449
16450 retval = ni_nvme_send_read_cmd(
16451 (ni_device_handle_t)(int64_t)hwdesc->device_handle,
16452 NI_INVALID_DEVICE_HANDLE, p_data_buffer, read_size_bytes, ui32LBA);
16453 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, hwdesc->src_cpu,
16454 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
16455 CHECK_VPU_RECOVERY(retval);
16456 if (retval < 0)
16457 {
16458 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
16460 LRETURN;
16461 } else
16462 {
16463 ni_log2(p_ctx, NI_LOG_DEBUG,
16464 "HW download read desc success, retval %d total_bytes_to_read %u\n",
16465 retval, total_bytes_to_read);
16466 }
16467
16468 //Unset applied read configuration here
16469 retval = ni_config_session_rw(p_ctx, SESSION_READ_CONFIG, 0, 0, 0);
16470 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, hwdesc->src_cpu,
16471 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
16472 CHECK_VPU_RECOVERY(retval);
16473
16474 if (retval < 0)
16475 {
16476 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
16478 LRETURN;
16479 } else
16480 {
16481 ni_log2(p_ctx, NI_LOG_DEBUG,
16482 "Unconfig HW download read desc success, retval %d total_bytes_to_read %u\n",
16483 retval, total_bytes_to_read);
16484 }
16485
16486 bytes_read_so_far = total_bytes_to_read;
16487 // Note: session status is NOT reset but tracked between send
16488 // and recv to catch and recover from a loop condition
16489
16490 if (p_ctx->is_auto_dl)
16491 rx_size = (int)bytes_read_so_far;
16492 else
16493 {
16494 rx_size =
16495 ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, 0, false);
16496 p_ctx->frame_pkt_offset = frame_offset;
16497 }
16498
16499 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): received data: [0x%08x]\n",
16500 __func__, rx_size);
16501 ni_log2(p_ctx, NI_LOG_DEBUG,
16502 "%s(): p_frame->start_of_stream=%u, "
16503 "p_frame->end_of_stream=%u, p_frame->video_width=%u, "
16504 "p_frame->video_height=%u\n",
16505 __func__, p_frame->start_of_stream, p_frame->end_of_stream,
16506 p_frame->video_width, p_frame->video_height);
16507 ni_log2(p_ctx, NI_LOG_DEBUG,
16508 "%s(): p_ctx->frame_num %" PRIu64 ", "
16509 "p_frame->data_len[0/1/2]=%u/%u/%u\n",
16510 __func__, p_ctx->frame_num, p_frame->data_len[0], p_frame->data_len[1],
16511 p_frame->data_len[2]);
16512
16513 //if (decq_count % 500 == 0)
16514 //{
16515 // ni_log2(p_ctx, NI_LOG_DEBUG, "Decoder pts queue size = %d dts queue size = %d\n\n",
16516 // p_ctx->pts_table->list.count, p_ctx->dts_queue)->list.count);
16517 // // scan and clean up
16518 // ni_timestamp_scan_cleanup(p_ctx->pts_table, p_ctx->dts_queue, p_ctx->buffer_pool);
16519 //}
16520
16521END:
16522
16523 if (NI_RETCODE_SUCCESS != retval)
16524 {
16525 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): bad exit, retval = %d\n", __func__, retval);
16526 return retval;
16527 } else
16528 {
16529 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit, rx_size = %d\n", __func__, rx_size);
16530 return rx_size;
16531 }
16532}
16533
16534int ni_hwdownload_by_frame_idx(niFrameSurface1_t* hwdesc, ni_frame_t* p_frame, int is_auto_dl)
16535{
16536 int retval = NI_RETCODE_SUCCESS;
16537 int rx_size = 0;
16538 uint64_t frame_offset = 0;
16539 uint8_t *p_data_buffer;
16540 int metadata_hdr_size = NI_FW_META_DATA_SZ -
16542 uint32_t total_bytes_to_read = 0;
16543 uint32_t read_size_bytes = 0;
16544 uint32_t ui32LBA = 0;
16545 ni_global_session_stats_t *global_state;
16546 const char *error_flag = "NetintQuadraErr";
16547
16548 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
16549
16550 p_data_buffer = (uint8_t *)p_frame->p_buffer;
16551
16552 if (!p_frame->p_data[0] || !p_data_buffer || 0 == p_frame->data_len[0])
16553 {
16554 ni_log(NI_LOG_ERROR, "ERROR %s(): passed parameters are null or p_frame->data_len is 0.\n",
16555 __func__);
16556 retval = NI_RETCODE_INVALID_PARAM;
16557 LRETURN;
16558 }
16559
16561 {
16562 p_frame->data_len[2] = 0;
16563 } else if (hwdesc->encoding_type >= NI_PIXEL_PLANAR_FORMAT_TILED4X4)
16564 {
16566 "ERROR %s(): Unsupported format %d for hw download.\n",
16567 __func__, hwdesc->encoding_type);
16568 retval = NI_RETCODE_INVALID_PARAM;
16569 LRETURN;
16570 }
16571 total_bytes_to_read = p_frame->data_len[0] + p_frame->data_len[1] +
16572 p_frame->data_len[2];// +metadata_hdr_size;
16573 unsigned int bytes_read_so_far = 0;
16574 uint32_t output_chunk_offset = hwdesc->ui32nodeAddress / FRAME_CHUNK_INDEX_SIZE; //for reading output1 or output2
16575 uint32_t output_minor_offset = hwdesc->ui32nodeAddress - output_chunk_offset * FRAME_CHUNK_INDEX_SIZE;
16576
16577 ni_log(NI_LOG_DEBUG, "total_bytes_to_read %u ylen %u cr len "
16578 "%u cb len %u hdr %d\n",
16579 total_bytes_to_read,
16580 p_frame->data_len[0], p_frame->data_len[1],
16581 p_frame->data_len[2], metadata_hdr_size);
16582
16583 // preset content of buffer, if not refresh means download fail
16584 memset(p_data_buffer, 0, NI_DATA_BUFFER_LEN);
16585 global_state = (ni_global_session_stats_t *)p_data_buffer;
16586 memcpy(global_state->error_flag, error_flag, strlen(error_flag)+1);
16587 global_state->check_flag[0] = global_state->check_flag[2] = 0x0;
16588 global_state->check_flag[1] = global_state->check_flag[3] = 0xFF;
16589
16590 read_size_bytes = total_bytes_to_read;
16591 ui32LBA = DOWNLOAD_FRAMEIDX_R(hwdesc->ui16FrameIdx);
16592 ui32LBA += output_chunk_offset;
16593 if (read_size_bytes % NI_MEM_PAGE_ALIGNMENT)
16594 {
16595 read_size_bytes = ( (read_size_bytes / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
16596 }
16597 ni_log(NI_LOG_DEBUG, "Total bytes to download %u, start offset = %u, chunkOffset "
16598 "%u, minorOffset %u hwdesc->ui16FrameIdx %d ui32LBA 0x%x\n",
16599 total_bytes_to_read, hwdesc->ui32nodeAddress,
16600 output_chunk_offset, output_minor_offset, hwdesc->ui16FrameIdx, ui32LBA);
16601
16602 retval = ni_nvme_send_read_cmd(
16603 (ni_device_handle_t)(int64_t)hwdesc->device_handle,
16604 NI_INVALID_DEVICE_HANDLE, p_data_buffer, read_size_bytes, ui32LBA);
16605
16606 if (retval < 0)
16607 {
16608 ni_log(NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
16610 LRETURN;
16611 }
16612 global_state = (ni_global_session_stats_t *)p_data_buffer;
16613 if (!strcmp(global_state->error_flag, error_flag) &&
16614 global_state->check_flag[0] == 0x0 && global_state->check_flag[1] == 0xFF &&
16615 global_state->check_flag[2] == 0x0 && global_state->check_flag[3] == 0xFF) {
16616 ni_log(NI_LOG_ERROR, "ERROR %s(): nvme download failed, invalid frameidx %u or "
16617 "size %u + offset %u out of range\n",
16618 __func__, hwdesc->ui16FrameIdx, read_size_bytes, output_chunk_offset);
16619 retval = NI_RETCODE_INVALID_PARAM;
16620 LRETURN;
16621 }
16622
16623 bytes_read_so_far = total_bytes_to_read;
16624 // Note: session status is NOT reset but tracked between send
16625 // and recv to catch and recover from a loop condition
16626
16627 if (is_auto_dl)
16628 rx_size = (int)bytes_read_so_far;
16629 else
16630 {
16631 rx_size =
16632 ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, 0, false);
16633 }
16634
16636 "HW download read desc success, retval %d total_bytes_to_read %u\n",
16637 retval, total_bytes_to_read);
16638
16639END:
16640
16641 if (NI_RETCODE_SUCCESS != retval)
16642 {
16643 ni_log(NI_LOG_ERROR, "%s(): bad exit, retval = %d\n", __func__, retval);
16644 return retval;
16645 } else
16646 {
16647 ni_log(NI_LOG_TRACE, "%s(): exit, rx_size = %d\n", __func__, rx_size);
16648 return rx_size;
16649 }
16650}
16651
16653 ni_frameclone_desc_t *p_frameclone_desc)
16654{
16655 int retval = NI_RETCODE_SUCCESS;
16656 uint8_t *p_data = NULL;
16657 uint32_t dataLen;
16658 uint32_t ui32LBA = 0;
16659
16660 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
16661
16662 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
16663 {
16664 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
16665 __func__);
16667 LRETURN;
16668 }
16669
16670 dataLen = (sizeof(ni_frameclone_desc_t) + NI_MEM_PAGE_ALIGNMENT - 1) &
16671 ~(NI_MEM_PAGE_ALIGNMENT - 1);
16672 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
16673 {
16674 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
16675 NI_ERRNO, __func__);
16677 LRETURN;
16678 }
16679 memset(p_data, 0, dataLen);
16680 memcpy(p_data, p_frameclone_desc, sizeof(ni_frameclone_desc_t));
16681 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): ui16DstIdx %u, ui16SrcIdx %u, size %u, offset %u\n", __func__,
16682 p_frameclone_desc->ui16DstIdx, p_frameclone_desc->ui16SrcIdx,
16683 p_frameclone_desc->ui32Size, p_frameclone_desc->ui32Offset);
16684
16685 ui32LBA = CONFIG_SESSION_FRAME_COPY_W(p_ctx->session_id);
16686 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, NI_INVALID_EVENT_HANDLE,
16687 p_data, dataLen, ui32LBA);
16689 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
16690 OPT_1);
16691 CHECK_VPU_RECOVERY(retval);
16692 if (NI_RETCODE_SUCCESS != retval)
16693 {
16694 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n",
16695 __func__);
16697 LRETURN;
16698 }
16699
16700END:
16701 ni_aligned_free(p_data);
16702 if (NI_RETCODE_SUCCESS != retval)
16703 {
16704 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): bad exit, retval = %d\n", __func__, retval);
16705 }
16706 return retval;
16707}
16708
16709/*!******************************************************************************
16710* \brief Close an xcoder upload instance
16711*
16712* \param p_ctx pointer to uploader session context
16713*
16714* \return NI_RETCODE_SUCCESS
16715*******************************************************************************/
16717{
16718#ifndef _WIN32
16719 if (p_ctx->isP2P)
16720 {
16721 if (p_ctx->netint_fd)
16722 {
16723 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: close driver fd %d\n", __func__,
16724 p_ctx->netint_fd);
16725 close(p_ctx->netint_fd);
16726 }
16727 }
16728#endif
16729 return NI_RETCODE_SUCCESS;
16730}
16731
16732/*!******************************************************************************
16733* \brief Send a p_config command to configure uploading parameters.
16734*
16735* \param ni_session_context_t p_ctx - xcoder Context
16736* \param[in] pool_size pool size to create
16737* \param[in] pool 0 = normal pool, 1 = P2P pool
16738*
16739* \return - NI_RETCODE_SUCCESS on success,
16740* NI_RETCODE_ERROR_INVALID_SESSION
16741* NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
16742*******************************************************************************/
16744 uint32_t pool_size,
16745 uint32_t pool)
16746{
16747 void* p_uploader_config = NULL;
16748 ni_uploader_config_t* p_cfg = NULL;
16749 uint32_t buffer_size = sizeof(ni_encoder_config_t);
16751 uint32_t ui32LBA = 0;
16752 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
16753
16754 if (!p_ctx)
16755 {
16756 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
16757 __func__);
16758 retval = NI_RETCODE_INVALID_PARAM;
16759 LRETURN;
16760 }
16761
16762 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
16763 {
16764 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
16765 __func__);
16767 LRETURN;
16768 }
16769
16770 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
16771 if (ni_posix_memalign(&p_uploader_config, sysconf(_SC_PAGESIZE),
16772 buffer_size))
16773 {
16774 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
16775 NI_ERRNO, __func__);
16777 LRETURN;
16778 }
16779 memset(p_uploader_config, 0, buffer_size);//
16780
16781 p_cfg = (ni_uploader_config_t*)p_uploader_config;
16782 p_cfg->ui16picWidth = p_ctx->active_video_width;
16783 p_cfg->ui16picHeight = p_ctx->active_video_height;
16784 p_cfg->ui8poolSize = pool_size;
16785 p_cfg->ui8PixelFormat = p_ctx->pixel_format;
16786 p_cfg->ui8Pool = pool;
16787 p_cfg->ui32lumaLinesize = 0; // cannot support config linesize yet because ni_frames_init is called when filter graph is created (no frame linesize info)
16788 p_cfg->ui32chromaLinesize = 0;
16789 bool isrgb = ((NI_PIX_FMT_RGBA == p_cfg->ui8PixelFormat) || (NI_PIX_FMT_BGRA == p_cfg->ui8PixelFormat) ||
16790 (NI_PIX_FMT_ARGB == p_cfg->ui8PixelFormat) || (NI_PIX_FMT_ABGR == p_cfg->ui8PixelFormat) ||
16791 (NI_PIX_FMT_BGR0 == p_cfg->ui8PixelFormat));
16795 {
16796 ni_log2(p_ctx, NI_LOG_ERROR, "Resolution %d x %d not supported for %d format!\n", p_cfg->ui16picWidth, p_cfg->ui16picHeight, p_cfg->ui8PixelFormat);
16797 retval = NI_RETCODE_INVALID_PARAM;
16798 LRETURN;
16799 }
16800
16801 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_config_instance_set_uploader_params():%d x %d x Format %d with %d framepool\n",
16802 p_cfg->ui16picWidth, p_cfg->ui16picHeight, p_cfg->ui8PixelFormat, p_cfg->ui8poolSize);
16803
16804 //configure the session here
16805 ui32LBA =
16807
16808 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
16809 p_uploader_config, buffer_size, ui32LBA);
16811 p_ctx->device_type, p_ctx->hw_id,
16812 &(p_ctx->session_id), OPT_1);
16813 if (NI_RETCODE_SUCCESS != retval)
16814 {
16815 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
16816 //Close the session since we can't configure it
16817 retval = ni_encoder_session_close(p_ctx, 0);
16818 if (NI_RETCODE_SUCCESS != retval)
16819 {
16820 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_uploader_session_close failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
16821 }
16822
16824 }
16825 else
16826 {
16828 }
16829
16830END:
16831
16832 ni_aligned_free(p_uploader_config);
16833 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
16834
16835 return retval;
16836}
16837
16838/*!******************************************************************************
16839* \brief Send a p_config command to configure decoding parameters.
16840*
16841* \param ni_session_context_t p_ctx - xcoder Context
16842* \param uint32_t max_pkt_size - overwrite maximum packet size if nonzero
16843*
16844* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
16845*******************************************************************************/
16847{
16848 void* p_decoder_config = NULL;
16849 uint32_t buffer_size = sizeof(ni_decoder_config_t);
16851 uint32_t ui32LBA = 0;
16852 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
16853
16854 if (!p_ctx)
16855 {
16856 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
16857 __func__);
16858 retval = NI_RETCODE_INVALID_PARAM;
16859 LRETURN;
16860 }
16861
16862 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
16863 {
16864 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
16865 __func__);
16867 LRETURN;
16868 }
16869
16870 if (ni_cmp_fw_api_ver((char*)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rT") < 0)
16871 {
16872 ni_log2(p_ctx, NI_LOG_INFO, "%s() FW rev %s < 6rT-- load balancing might be affected\n", __func__,
16874 }
16875
16876 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
16877 if (ni_posix_memalign(&p_decoder_config, sysconf(_SC_PAGESIZE), buffer_size))
16878 {
16879 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_decoder_config buffer\n",
16880 NI_ERRNO, __func__);
16882 LRETURN;
16883 }
16884 memset(p_decoder_config, 0, buffer_size);
16885
16886 ni_set_custom_dec_template(p_ctx, p_decoder_config, p_ctx->p_session_config, max_pkt_size);
16887 retval = ni_validate_custom_dec_template(p_ctx->p_session_config, p_ctx, p_decoder_config, p_ctx->param_err_msg, sizeof(p_ctx->param_err_msg));
16888 if (NI_RETCODE_PARAM_WARN == retval)
16889 {
16890 ni_log2(p_ctx, NI_LOG_INFO, "WARNING: %s . %s\n", __func__, p_ctx->param_err_msg);
16891 fflush(stdout);
16892 }
16893 else if (NI_RETCODE_SUCCESS != retval)
16894 {
16895 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s failed. %s\n", __func__,
16896 p_ctx->param_err_msg);
16897 fflush(stdout);
16898 retval = NI_RETCODE_INVALID_PARAM;
16899 LRETURN;
16900 }
16901
16902 // configure the session here
16904
16905 //Flip the bytes!!
16906 //p_cfg = (ni_decoder_config_t*)p_decoder_config;
16907 //p_cfg->i32picWidth = ni_htonl(p_cfg->i32picWidth);
16908 //p_cfg->i32picHeight = ni_htonl(p_cfg->i32picHeight);
16909 //p_cfg->i32meBlkMode = ni_htonl(p_cfg->i32meBlkMode);
16910 //p_cfg->i32frameRateInfo = ni_htonl(p_cfg->i32frameRateInfo);
16911 //p_cfg->i32vbvBufferSize = ni_htonl(p_cfg->i32vbvBufferSize);
16912 //p_cfg->i32userQpMax = ni_htonl(p_cfg->i32userQpMax);
16913 //p_cfg->i32maxIntraSize = ni_htonl(p_cfg->i32maxIntraSize);
16914 //p_cfg->i32userMaxDeltaQp = ni_htonl(p_cfg->i32userMaxDeltaQp);
16915 //p_cfg->i32userMinDeltaQp = ni_htonl(p_cfg->i32userMinDeltaQp);
16916 //p_cfg->i32userQpMin = ni_htonl(p_cfg->i32userQpMin);
16917 //p_cfg->i32bitRate = ni_htonl(p_cfg->i32bitRate);
16918 //p_cfg->i32bitRateBL = ni_htonl(p_cfg->i32bitRateBL);
16919 //p_cfg->i32srcBitDepth = ni_htonl(p_cfg->i32srcBitDepth);
16920 //p_cfg->hdrEnableVUI = ni_htonl(p_cfg->hdrEnableVUI);
16921 //p_cfg->ui32VuiDataSizeBits = ni_htonl(p_cfg->ui32VuiDataSizeBits);
16922 //p_cfg->ui32VuiDataSizeBytes = ni_htonl(p_cfg->ui32VuiDataSizeBytes);
16923 //p_cfg->i32hwframes = ni_htonl(p_cfg->i32hwframes);
16924 // flip the 16 bytes of the reserved field using 32 bits pointers
16925 //for (i = 0; i < (16 >> 2); i++)
16926 //{
16927 // ((uint32_t*)p_cfg->ui8Reserved)[i] = ni_htonl(((uint32_t*)p_cfg->ui8Reserved)[i]);
16928 //}
16930 //for (i = 0; i < (NI_MAX_VUI_SIZE >> 2); i++) // apply on 32 bits
16931 //{
16932 // ((uint32_t*)p_cfg->ui8VuiRbsp)[i] = ni_htonl(((uint32_t*)p_cfg->ui8VuiRbsp)[i]);
16933 //}
16934
16935 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: ui32LBA = 0x%x\n", __func__, ui32LBA);
16936 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
16937 p_decoder_config, buffer_size, ui32LBA);
16939 p_ctx->device_type, p_ctx->hw_id,
16940 &(p_ctx->session_id), OPT_1);
16941 if (NI_RETCODE_SUCCESS != retval)
16942 {
16943 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
16944 //Close the session since we can't configure it
16945 retval = ni_decoder_session_close(p_ctx, 0);
16946 if (NI_RETCODE_SUCCESS != retval)
16947 {
16948 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_encoder_session_close failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
16949 }
16950
16952 }
16953
16954END:
16955
16956 ni_aligned_free(p_decoder_config);
16957 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
16958 return retval;
16959}
16960
16961/*!******************************************************************************
16962* \brief Send a p_config command to configure decoding parameters.
16963*
16964* \param ni_session_context_t p_ctx - xcoder Context
16965* \param uint32_t max_pkt_size - overwrite maximum packet size if nonzero
16966*
16967* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
16968*******************************************************************************/
16970 void *p_dec_ppu_config, int buffer_size)
16971{
16972 void* p_ppu_config = NULL;
16973 // uint32_t buffer_size = sizeof(ni_decoder_output_picture_size);
16974 uint32_t tmp_buffer_size = buffer_size;
16976 uint32_t ui32LBA = 0;
16977
16978 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
16979
16980 if (!p_ctx || !p_dec_ppu_config)
16981 {
16982 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
16983 __func__);
16984 retval = NI_RETCODE_INVALID_PARAM;
16985 LRETURN;
16986 }
16987
16988 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
16989 {
16990 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
16991 __func__);
16993 LRETURN;
16994 }
16995
16997
16998 if (ni_cmp_fw_api_ver((char*)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rT") < 0)
16999 {
17000 ni_log2(p_ctx, NI_LOG_INFO, "%s() FW rev %s < 6rT-- load balancing might be affected\n", __func__,
17002 }
17003
17004 tmp_buffer_size = ((tmp_buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
17005 if (ni_posix_memalign(&p_ppu_config, sysconf(_SC_PAGESIZE), tmp_buffer_size))
17006 {
17007 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate memory\n",
17008 NI_ERRNO, __func__);
17010 LRETURN;
17011 }
17012 memset(p_ppu_config, 0, tmp_buffer_size);
17013
17014 memcpy(p_ppu_config, p_dec_ppu_config, buffer_size);
17015 // configure the session here
17017
17018 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17019 p_ppu_config, tmp_buffer_size, ui32LBA);
17021 p_ctx->device_type, p_ctx->hw_id,
17022 &(p_ctx->session_id), OPT_1);
17023 if (NI_RETCODE_SUCCESS != retval)
17024 {
17025 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17027 //Close the session since we can't configure it
17028 retval = ni_decoder_session_close(p_ctx, 0);
17029 if (NI_RETCODE_SUCCESS != retval)
17030 {
17031 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_decoder_session_close failed: blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n", (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17032 }
17035 }
17036
17037END:
17038
17040 ni_aligned_free(p_ppu_config);
17041 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
17042 return retval;
17043}
17044
17045/*!******************************************************************************
17046 * \brief read a hardware descriptor from a scaler session
17047 *
17048 * \param[in] p_ctx pointer to session context
17049 * \param[out] p_frame pointer to frame to write hw descriptor
17050 *
17051 * \return NI_RETCODE_INVALID_PARAM
17052 * NI_RETCODE_ERROR_INVALID_SESSION
17053 * NI_RETCODE_ERROR_MEM_ALOC
17054 * NI_RETCODE_ERROR_NVME_CMD_FAILED
17055 * NI_RETCODE_FAILURE
17056 *******************************************************************************/
17058 ni_session_context_t *p_ctx,
17059 ni_frame_t *p_frame)
17060{
17061 ni_retcode_t retval;
17062 ni_instance_buf_info_t sInstanceBuf = {0};
17063 niFrameSurface1_t *pFrameSurface;
17064 int query_retry = 0;
17065
17066 if (!p_ctx || !p_frame || !p_frame->p_data[3])
17067 {
17068 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
17069 __func__);
17071 }
17072
17073 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
17074 {
17075 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17076 __func__);
17078 }
17079
17080 if (p_ctx->buffered_frame_index)
17081 {
17082 pFrameSurface = (niFrameSurface1_t *) p_frame->p_data[3];
17083 pFrameSurface->ui16FrameIdx = p_ctx->buffered_frame_index;
17084 pFrameSurface->ui16session_ID = p_ctx->session_id;
17085 pFrameSurface->device_handle =
17086 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
17087 pFrameSurface->src_cpu = (uint8_t) NI_DEVICE_TYPE_SCALER;
17088 pFrameSurface->output_idx = 0;
17089
17090 p_ctx->buffered_frame_index = 0;
17091 return NI_RETCODE_SUCCESS;
17092 }
17093
17095
17096 for (;;)
17097 {
17098 query_retry++;
17099
17100 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: query by ni_query_instance_buf_info INST_BUF_INFO_RW_UPLOAD\n",
17101 __func__);
17103 NI_DEVICE_TYPE_SCALER, &sInstanceBuf);
17104
17105 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
17106 p_ctx->device_type, p_ctx->hw_id,
17107 &(p_ctx->session_id), OPT_3);
17108
17110 {
17111 if (query_retry >= 1000)
17112 {
17113 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning hwdesc read fail rc %d\n", retval);
17114 LRETURN;
17115 }
17116 }
17117 else if (retval != NI_RETCODE_SUCCESS)
17118 {
17119 LRETURN;
17120 }
17121 else
17122 {
17123 pFrameSurface = (niFrameSurface1_t *) p_frame->p_data[3];
17124 pFrameSurface->ui16FrameIdx = sInstanceBuf.hw_inst_ind.frame_index;
17125 pFrameSurface->ui16session_ID = p_ctx->session_id;
17126 pFrameSurface->device_handle =
17127 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
17128 pFrameSurface->src_cpu = (uint8_t) NI_DEVICE_TYPE_SCALER;
17129 pFrameSurface->output_idx = 0;
17130
17131 /* A frame index of zero is invalid, the memory acquisition failed */
17132 if (pFrameSurface->ui16FrameIdx == 0)
17133 {
17134 if (query_retry >= 1000)
17135 {
17136 ni_log2(p_ctx, NI_LOG_ERROR, "Error: 2D could not acquire frame\n");
17137 retval = NI_RETCODE_FAILURE;
17138 LRETURN;
17139 }
17140 ni_usleep(100);
17141 continue;
17142 }
17143
17144 ni_log2(p_ctx, NI_LOG_DEBUG,
17145 "Session=0x%x: %s got FrameIndex=%u\n",
17146 p_ctx->session_id,
17147 __func__,
17148 pFrameSurface->ui16FrameIdx);
17149
17150 LRETURN;
17151 }
17152 }
17153
17154END:
17155
17157
17158 if (NI_RETCODE_SUCCESS != retval)
17159 {
17160 ni_log2(p_ctx, NI_LOG_DEBUG,
17161 "%s Warning scalar read hwdesc fail rc %d or ind !\n",
17162 __func__, retval);
17163 retval = NI_RETCODE_FAILURE;
17164 }
17165
17166 return retval;
17167}
17168
17169/*!******************************************************************************
17170* \brief Grab bitdepth factor from NI_PIX_FMT
17171*
17172* \param[in] pix_fmt ni_pix_fmt_t
17173*
17174* \return 1 or 2 for success, -1 for error
17175*******************************************************************************/
17177{
17178 switch (pix_fmt)
17179 {
17180 case NI_PIX_FMT_YUV420P:
17181 case NI_PIX_FMT_NV12:
17183 return 1;
17185 case NI_PIX_FMT_P010LE:
17187 return 2;
17188 default:
17189 {
17190 ni_log(NI_LOG_ERROR, "ERROR: %s() non applicable format %d\n", __func__,
17191 pix_fmt);
17192 break;
17193 }
17194 }
17195 return -1;
17196}
17197
17198/*!******************************************************************************
17199* \brief Grab planar info from NI_PIX_FMT
17200*
17201* \param[in] pix_fmt ni_pix_fmt_t
17202*
17203* \return 0 or 1 for success, -1 for error
17204*******************************************************************************/
17206{
17207 switch (pix_fmt)
17208 {
17209 case NI_PIX_FMT_YUV420P:
17211 case NI_PIX_FMT_ABGR:
17212 case NI_PIX_FMT_ARGB:
17213 case NI_PIX_FMT_RGBA:
17214 case NI_PIX_FMT_BGRA:
17215 return 1;
17216 break;
17217 case NI_PIX_FMT_NV12:
17218 case NI_PIX_FMT_P010LE:
17219 return 0;
17220 break;
17221 default:
17222 {
17223 ni_log(NI_LOG_ERROR, "ERROR: %s() non applicable format %d\n", __func__,
17224 pix_fmt);
17225 break;
17226 }
17227 }
17228 return -1;
17229}
17230
17231#ifndef _WIN32
17232/*!*****************************************************************************
17233 * \brief Get an address offset from a hw descriptor
17234 *
17235 * \param[in] p_ctx ni_session_context_t to be referenced
17236 * \param[in] hwdesc Pointer to caller allocated niFrameSurface1_t
17237 * \param[out] p_offset Value of offset
17238 *
17239 * \return On success NI_RETCODE_SUCCESS
17240 * On failure NI_RETCODE_INVALID_PARAM
17241 ******************************************************************************/
17243 uint32_t *p_offset)
17244{
17245 if (!hwdesc)
17246 {
17247 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed null parameter\n", __func__);
17249 }
17250
17251 if (hwdesc->ui16FrameIdx <= NI_GET_MIN_HWDESC_P2P_BUF_ID(p_ctx->ddr_config) ||
17253 {
17254 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() pass invalid data. "
17255 "FrameIdx %d OOR (%d,%d]. DDR config %d \n", __func__, hwdesc->ui16FrameIdx,
17257 p_ctx->ddr_config);
17259 }
17260
17261 *p_offset = (hwdesc->ui16FrameIdx - NI_GET_MIN_HWDESC_P2P_BUF_ID(p_ctx->ddr_config)) *
17263
17264 return NI_RETCODE_SUCCESS;
17265}
17266#endif
17267
17268/* AI functions */
17270 void *nb_data, uint32_t nb_size)
17271{
17272 void *p_ai_config = NULL;
17273 void *p_nb_data = NULL;
17274 uint32_t buffer_size;
17275 // uint8_t *p_data;
17276 // uint32_t transferred, this_size;
17278 uint32_t ui32LBA = 0;
17279 uint32_t config_size;
17280 void *p_buffer = NULL;
17281 uint32_t dataLen;
17282 ni_instance_buf_info_t buf_info = {0};
17283 int retry_count = 0;
17284
17285 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
17286
17287 if (!p_ctx)
17288 {
17289 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
17290 __func__);
17292 }
17293
17294 if (!nb_data || nb_size == 0) {
17295 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() invalid nb_data %p nb_size %u\n",
17296 __func__, nb_data, nb_size);
17298 }
17299
17301
17302 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
17303 {
17304 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17305 __func__);
17307 LRETURN;
17308 }
17309
17310 config_size = (sizeof(ni_ai_config_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
17311 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17312 if (ni_posix_memalign(&p_ai_config, sysconf(_SC_PAGESIZE), config_size))
17313 {
17314 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate ai config buffer.\n");
17316 LRETURN;
17317 }
17318
17319 ((ni_ai_config_t *)p_ai_config)->ui32NetworkBinarySize = nb_size;
17320 ni_calculate_sha256(nb_data, nb_size,
17321 ((ni_ai_config_t *)p_ai_config)->ui8Sha256);
17322
17323 buffer_size =
17324 (nb_size + (NI_MEM_PAGE_ALIGNMENT - 1)) & ~(NI_MEM_PAGE_ALIGNMENT - 1);
17325 if (ni_posix_memalign(&p_nb_data, sysconf(_SC_PAGESIZE), buffer_size))
17326 {
17327 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate encConf buffer.\n");
17329 LRETURN;
17330 }
17331
17332 memcpy(p_nb_data, nb_data, nb_size);
17333
17334 /* configure network binary size to be written */
17336 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): LBA 0x%x, nb_size %u\n", __func__, ui32LBA,
17337 ((ni_ai_config_t *)p_ai_config)->ui32NetworkBinarySize);
17338
17339 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17340 p_ai_config, config_size, ui32LBA);
17342 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17343 if (NI_RETCODE_SUCCESS != retval)
17344 {
17345 ni_log2(p_ctx, NI_LOG_ERROR,
17346 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
17347 ", hw_id, %u, xcoder_inst_id: %d\n",
17348 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17349 //Close the session since we can't configure it
17350 retval = ni_ai_session_close(p_ctx, 0);
17351 if (NI_RETCODE_SUCCESS != retval)
17352 {
17353 ni_log2(p_ctx, NI_LOG_ERROR,
17354 "ERROR: ni_ai_session_close failed: blk_io_handle: %" PRIx64
17355 ", hw_id, %u, xcoder_inst_id: %d\n",
17356 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
17357 p_ctx->session_id);
17358 }
17359
17361 LRETURN;
17362 }
17363
17364 dataLen = (sizeof(ni_network_layer_info_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
17365 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17366 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
17367 {
17368 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate buffer.\n");
17370 LRETURN;
17371 }
17372
17373 for (;;)
17374 {
17375 /* test if the model is already exist. if not, then continue to write binary data */
17376 memset(p_buffer, 0, dataLen);
17378 "6J") >= 0)
17379 {
17380 ui32LBA = QUERY_INSTANCE_NL_SIZE_V2_R(p_ctx->session_id,
17382 } else
17383 {
17384 ui32LBA =
17386 }
17387 retval =
17389 p_buffer, dataLen, ui32LBA);
17390 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
17391 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17392 if (retval != NI_RETCODE_SUCCESS)
17393 {
17394 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
17396 LRETURN;
17397 }
17398 if (((ni_instance_buf_info_t *)p_buffer)->buf_avail_size > 0)
17399 {
17400 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): network binary registered\n", __func__);
17401 LRETURN;
17402 }
17403
17404 /* if this model is not ready, try to require nbuffer to write */
17406 NI_DEVICE_TYPE_AI, &buf_info);
17407 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
17408 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17409 if (retval != NI_RETCODE_SUCCESS)
17410 {
17411 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Query Write buffer Failed\n", __func__);
17412 LRETURN;
17413 }
17414 if (buf_info.buf_avail_size < nb_size)
17415 {
17416 /*
17417 * Cannot aquire the write access to nbuffer because someone else on the go,
17418 * Retry to see if model is ready.
17419 */
17420 ni_log2(p_ctx, NI_LOG_TRACE,
17421 "AI write query failed or buf_size %u < "
17422 "frame_size %u.\n", buf_info.buf_avail_size, nb_size);
17423 } else
17424 {
17425 /* Grant write access to nbuffer */
17426 ni_log2(p_ctx, NI_LOG_DEBUG,
17427 "Info ai write query success, available buf "
17428 "size %u >= frame size %u !\n",
17429 buf_info.buf_avail_size, nb_size);
17430 break;
17431 }
17432 retry_count++;
17433 /* Wait for at least 30s */
17435 {
17437 ni_usleep(100);
17439 } else
17440 {
17441 ni_log2(p_ctx, NI_LOG_DEBUG, "AI network binary configuration polling timeout\n");
17443 LRETURN;
17444 }
17445 }
17446
17447#if 1
17448 /* write network binary data */
17450 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): write nb LBA 0x%x\n", __func__, ui32LBA);
17451 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17452 p_nb_data, buffer_size, ui32LBA);
17453 ni_log2(p_ctx, NI_LOG_DEBUG, "write complete retval %d\n", retval);
17454 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
17455 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17456 if (NI_RETCODE_SUCCESS != retval)
17457 {
17458 ni_log2(p_ctx, NI_LOG_ERROR,
17459 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
17460 ", hw_id, %u, xcoder_inst_id: %d\n",
17461 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17462 //Close the session since we can't configure it
17463 retval = ni_ai_session_close(p_ctx, 0);
17464 if (NI_RETCODE_SUCCESS != retval)
17465 {
17466 ni_log2(p_ctx, NI_LOG_ERROR,
17467 "ERROR: ni_ai_session_close failed: blk_io_handle: %" PRIx64
17468 ", hw_id, %u, xcoder_inst_id: %d\n",
17469 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
17470 p_ctx->session_id);
17471 }
17472
17474 LRETURN;
17475 }
17476
17477#else
17478 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): write nb buffer_size %u\n", __func__,
17479 buffer_size);
17480 for (transferred = 0; transferred < buffer_size; transferred += this_size)
17481 {
17482 this_size = p_ctx->max_nvme_io_size < (buffer_size - transferred) ?
17483 p_ctx->max_nvme_io_size :
17484 (buffer_size - transferred);
17485
17486 if (this_size & (4096 - 1))
17487 {
17488 this_size = (this_size + (4096 - 1)) & ~(4096 - 1);
17489 }
17490 /* write network binary data */
17491 ui32LBA = WRITE_INSTANCE_W(p_ctx->session_id, NI_DEVICE_TYPE_AI) +
17492 (transferred >> 12);
17493 ni_log2(p_ctx, NI_LOG_DEBUG,
17494 "%s(): write nb LBA 0x%x, this_size %u, page_offset %u\n",
17495 __func__, ui32LBA, this_size, (transferred >> 12));
17496 p_data = (uint8_t *)p_nb_data + transferred;
17497 retval = ni_nvme_send_write_cmd(
17498 p_ctx->blk_io_handle, p_ctx->event_handle,
17499 (uint8_t *)p_nb_data + transferred, this_size, ui32LBA);
17500 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): write retval %d\n", __func__, retval);
17501 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
17502 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17503 if (NI_RETCODE_SUCCESS != retval)
17504 {
17505 ni_log(
17507 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
17508 ", hw_id, %u, xcoder_inst_id: %d\n",
17509 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17510 //Close the session since we can't configure it
17511 retval = ni_ai_session_close(p_ctx, 0);
17512 if (NI_RETCODE_SUCCESS != retval)
17513 {
17514 ni_log(
17516 "ERROR: ni_ai_session_close failed: blk_io_handle: %" PRIx64
17517 ", hw_id, %u, xcoder_inst_id: %d\n",
17518 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
17519 p_ctx->session_id);
17520 }
17521
17523 LRETURN;
17524 }
17525 }
17526
17527#endif
17528
17529END:
17531
17532 ni_aligned_free(p_ai_config);
17533 ni_aligned_free(p_nb_data);
17534 ni_aligned_free(p_buffer);
17535
17536 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
17537
17538 return retval;
17539}
17540
17542{
17543 void *p_stream_info = NULL;
17544 void *p_ai_config = NULL;
17545 void *p_nb_data = NULL;
17547 uint32_t ui32LBA = 0;
17548 uint32_t config_size;
17549
17550 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
17551
17552 if (!p_ctx)
17553 {
17554 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
17555 __func__);
17556 retval = NI_RETCODE_INVALID_PARAM;
17557 LRETURN;
17558 }
17559
17561
17562 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
17563 {
17564 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17565 __func__);
17567 LRETURN;
17568 }
17569
17570 config_size = (sizeof(ni_instance_mgr_stream_info_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
17571 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17572
17573 if (ni_posix_memalign(&p_stream_info, sysconf(_SC_PAGESIZE), config_size))
17574 {
17575 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate stream info buffer.\n");
17577 LRETURN;
17578 }
17579
17580 ((ni_instance_mgr_stream_info_t *)p_stream_info)->picture_width = p_ctx->active_video_width;
17581 ((ni_instance_mgr_stream_info_t *)p_stream_info)->picture_height = p_ctx->active_video_height;
17582 if (p_ctx->hvsplus_type == 0)
17583 {
17584 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_model_type = AI_MODEL_TYPE_HVSPLUS_FILTER;
17585 }
17586 else
17587 {
17590 "6sW") >= 0)
17591 {
17592 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_model_type = AI_MODEL_TYPE_USM_FILTER;
17593 }
17594 else
17595 {
17596 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: USM filter not support for FW version lower than 6sW\n");
17597 retval = NI_RETCODE_INVALID_PARAM;
17598 LRETURN;
17599 }
17600 }
17601 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_enhance_level = p_ctx->hvsplus_level;
17602 ((ni_instance_mgr_stream_info_t *)p_stream_info)->pix_format = p_ctx->pixel_format;
17603
17604 ni_log2(p_ctx, NI_LOG_DEBUG,
17605 "### %s: width %d %d height %d model type %d level %d pix_format %d\n", __func__,
17606 p_ctx->active_video_width, p_ctx->ori_width, p_ctx->active_video_height,
17607 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_model_type,
17608 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_enhance_level,
17609 ((ni_instance_mgr_stream_info_t *)p_stream_info)->pix_format);
17610
17611 /* configure AI manager to load the suitable network binary */
17613 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): LBA 0x%x config_size %d %d\n", __func__, ui32LBA, config_size, sizeof(ni_instance_mgr_stream_info_t));
17614
17615 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17616 p_stream_info, config_size, ui32LBA);
17618 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17619 if (NI_RETCODE_SUCCESS != retval)
17620 {
17621 ni_log2(p_ctx, NI_LOG_ERROR,
17622 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
17623 ", hw_id, %u, xcoder_inst_id: %d\n",
17624 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17625 //Close the session since we can't configure it
17626 retval = ni_ai_session_close(p_ctx, 0);
17627 if (NI_RETCODE_SUCCESS != retval)
17628 {
17629 ni_log2(p_ctx, NI_LOG_ERROR,
17630 "ERROR: ni_ai_session_close failed: blk_io_handle: %" PRIx64
17631 ", hw_id, %u, xcoder_inst_id: %d\n",
17632 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
17633 p_ctx->session_id);
17634 }
17635
17637 LRETURN;
17638 }
17639
17640END:
17642
17643 ni_aligned_free(p_ai_config);
17644 ni_aligned_free(p_nb_data);
17645 ni_aligned_free(p_stream_info);
17646
17647 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
17648
17649 return retval;
17650}
17651
17653{
17655 void *p_buffer = NULL;
17656 uint32_t ui32LBA = 0;
17657 int retry_count = 0;
17658 uint32_t dataLen = (sizeof(ni_network_layer_info_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
17659 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17660 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
17661 {
17662 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate buffer.\n");
17664 LRETURN;
17665 }
17666 for(;;)
17667 {
17668 memset(p_buffer, 0, dataLen);
17669 ui32LBA =
17671 retval =
17673 p_buffer, dataLen, ui32LBA);
17674 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
17675 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17676 if (retval != NI_RETCODE_SUCCESS)
17677 {
17678 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
17679 }
17680 if (((ni_instance_buf_info_t *)p_buffer)->buf_avail_size > 0)
17681 {
17682 ni_log2(p_ctx, NI_LOG_INFO, "%s(): network binary registered\n", __func__);
17683 break;
17684 }
17685
17686 retry_count++;
17687 /* Wait for at least 30s */
17689 {
17690 ni_usleep(100);
17691 } else
17692 {
17693 ni_log2(p_ctx, NI_LOG_DEBUG, "AI network binary configuration polling timeout\n");
17695 LRETURN;
17696 }
17697 }
17698END:
17699
17700 ni_aligned_free(p_buffer);
17701 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
17702
17703 return retval;
17704
17705}
17706
17708 ni_frame_t *p_frame)
17709{
17711 uint32_t ui32LBA = 0;
17712 ni_instance_buf_info_t buf_info = {0};
17713 uint32_t frame_size_bytes;
17714 uint32_t sent_size = 0;
17715 int32_t query_retry = 0;
17716 uint32_t dataLen;
17717 ni_network_buffer_info_t *buffer_info = NULL;
17718
17719 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
17720
17721 if (!p_ctx || !p_frame)
17722 {
17723 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): passed parameters is null\n",
17724 __func__);
17725 retval = NI_RETCODE_INVALID_PARAM;
17726 return retval;
17727 }
17728
17729 if (p_frame->data_len[0] == 0)
17730 {
17731 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() invalid data length\n",
17732 __func__);
17733 retval = NI_RETCODE_INVALID_PARAM;
17734 return retval;
17735 }
17736
17738
17739
17740 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
17741 {
17742 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17743 __func__);
17745 LRETURN;
17746 }
17747
17748 frame_size_bytes = p_frame->data_len[0];
17749 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): frame_size_bytes %u\n", __func__,
17750 frame_size_bytes);
17751
17752 for (;;)
17753 {
17754 if (p_ctx->session_statistic.ui32WrBufAvailSize >= frame_size_bytes)
17755 {
17756 buf_info.buf_avail_size =
17758 ni_log2(p_ctx, NI_LOG_DEBUG,
17759 "Info ai write query success, available buf "
17760 "size %u >= frame size %u !\n",
17761 buf_info.buf_avail_size, frame_size_bytes);
17762 break;
17763 }
17764
17766 "6K") >= 0)
17767 {
17769 &p_ctx->session_statistic);
17770 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
17772 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
17773 buf_info.buf_avail_size =
17775 } else
17776 {
17778 NI_DEVICE_TYPE_AI, &buf_info);
17779 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
17780 p_ctx->device_type, p_ctx->hw_id,
17781 &(p_ctx->session_id), OPT_1);
17782 }
17783 if (NI_RETCODE_SUCCESS != retval ||
17784 buf_info.buf_avail_size < frame_size_bytes)
17785 {
17786 ni_log2(p_ctx, NI_LOG_TRACE,
17787 "AI write query failed or buf_size < frame_size. Retry %d\n",
17788 query_retry);
17789 // extend to 5000 retries for 8K encode on FPGA
17790 if (query_retry >= NI_MAX_ENCODER_QUERY_RETRIES)
17791 {
17792 ni_log2(p_ctx, NI_LOG_DEBUG,
17793 "AI write query exceeded max retries: %d\n",
17796 retval = NI_RETCODE_SUCCESS;
17797 LRETURN;
17798 }
17802 query_retry++;
17803 }
17804 }
17805
17807 < 0 || p_frame->iovec_num <= 1) {
17808 void *p_data;
17809 if (p_frame->iovec_num == 1) {
17810 if (!p_frame->iovec) {
17811 ni_log2(p_ctx, NI_LOG_ERROR, "Ai session write: invaid iovec\n");
17812 retval = NI_RETCODE_INVALID_PARAM;
17813 LRETURN;
17814 }
17815 if (!p_frame->iovec[0].ptr || p_frame->iovec[0].size == 0 ||
17816 ((int64_t)p_frame->iovec[0].ptr & (NI_MEM_PAGE_ALIGNMENT - 1))) {
17817 ni_log2(p_ctx, NI_LOG_ERROR, "Ai session write: invalid iovec ptr 0x%lx, size %u\n",
17818 (int64_t)p_frame->iovec[0].ptr, p_frame->iovec[0].size);
17819 retval = NI_RETCODE_INVALID_PARAM;
17820 LRETURN;
17821 }
17822 p_data = p_frame->iovec[0].ptr;
17823 } else {
17824 p_data = p_frame->p_buffer; //equals to p_frame->p_data[0]
17825 }
17827 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai session write: p_data = %p, p_frame->buffer_size = %u, "
17828 "p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
17829 p_data, p_frame->buffer_size, p_ctx->frame_num,
17830 ui32LBA);
17831
17832 sent_size = frame_size_bytes;
17833 if (sent_size & (NI_MEM_PAGE_ALIGNMENT - 1))
17834 {
17835 sent_size = (sent_size + NI_MEM_PAGE_ALIGNMENT - 1) &
17836 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17837 }
17838
17839 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17840 p_data, sent_size, ui32LBA);
17842 "6K") >= 0)
17843 {
17844 if (retval != NI_RETCODE_SUCCESS)
17845 {
17846 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
17848 LRETURN;
17849 }
17851 &p_ctx->session_statistic);
17852 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
17854 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
17855 } else
17856 {
17857 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
17858 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17859 if (retval < 0)
17860 {
17861 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
17863 LRETURN;
17864 }
17865 }
17866 } else { //for iovec
17867 //validate iovec
17868 uint32_t i;
17869 uint32_t rel_offset = 0;
17870 int32_t iovec_index = 0;
17871 int32_t iovec_left;
17872
17873 if (!p_frame->iovec) {
17874 ni_log2(p_ctx, NI_LOG_ERROR, "Ai session write: invaid iovec\n");
17875 retval = NI_RETCODE_INVALID_PARAM;
17876 LRETURN;
17877 }
17878
17879 for (i = 0; i < p_frame->iovec_num; i++) {
17880 ni_iovec_t *this_iovec = &p_frame->iovec[i];
17881
17882 ni_log2(p_ctx, NI_LOG_DEBUG, "iovec %d, ptr %p, size %u\n", i,
17883 this_iovec->ptr, this_iovec->size);
17884 if ((this_iovec->ptr == NULL) || (this_iovec->size == 0) ||
17885 ((int64_t)this_iovec->ptr & (NI_MEM_PAGE_ALIGNMENT - 1))) {
17886 ni_log2(p_ctx, NI_LOG_ERROR, "Ai session write: invalid iovec ptr 0x%lx, size %u\n",
17887 (int64_t)this_iovec->ptr, this_iovec->size);
17888 retval = NI_RETCODE_INVALID_PARAM;
17889 LRETURN;
17890 }
17891 }
17892
17893 //1, write iovec details
17894 dataLen = (sizeof(ni_network_buffer_info_t) + NI_MEM_PAGE_ALIGNMENT - 1) &
17895 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17896 if (ni_posix_memalign((void **)&buffer_info, sysconf(_SC_PAGESIZE), dataLen))
17897 {
17898 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
17899 NI_ERRNO, __func__);
17901 }
17902 memset(buffer_info, 0x00, dataLen);
17903
17904 //2, write iovec
17905 iovec_left = p_frame->iovec_num;
17906 do {
17907 int iovec_batch = iovec_left < NI_MAX_SEGMENT_NUM ? iovec_left : NI_MAX_SEGMENT_NUM;
17908 uint32_t rel_lba = 0;
17909
17910 buffer_info->ui16Option = NI_AI_FLAG_IOVEC;
17911 buffer_info->ui32IovecNum = iovec_batch;
17912 buffer_info->ui32RelOffset = rel_offset;
17913 for (i = 0; (int)i < iovec_batch; i++) {
17914 ni_iovec_t *iovec = &p_frame->iovec[iovec_index + i];
17915 buffer_info->segment[i].ui32RelLba = rel_lba;
17916 buffer_info->segment[i].ui32Size = iovec->size;
17917 rel_lba += (((iovec->size + NI_MEM_PAGE_ALIGNMENT - 1) &
17918 ~(NI_MEM_PAGE_ALIGNMENT - 1)) >> LBA_BIT_OFFSET) + 1;
17919 rel_offset += iovec->size;
17920 }
17921 ni_log2(p_ctx, NI_LOG_DEBUG, "Dev alloc frame: frame_index %u\n",
17922 buffer_info->ui16FrameIdx[0]);
17923
17924 ui32LBA =
17926
17927 retval =
17929 buffer_info, dataLen, ui32LBA);
17930 //CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config,
17931 // p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
17932 // OPT_1);
17933 if (NI_RETCODE_SUCCESS != retval)
17934 {
17935 ni_log2(p_ctx,
17937 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
17938 ", hw_id, %u, xcoder_inst_id: %d\n",
17939 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17940 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n",
17941 __func__);
17943 LRETURN;
17944 }
17945
17946#ifdef __linux__
17947 for (i = 0; (int)i < iovec_batch; i++) {
17948 ni_iovec_t *iovec = &p_frame->iovec[iovec_index + i];
17949 ni_segment_t *segment = &buffer_info->segment[i];
17950 ui32LBA = WRITE_INSTANCE_W(p_ctx->session_id, NI_DEVICE_TYPE_AI) + segment->ui32RelLba;
17951 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai session write: data = %p, size = %u, "
17952 "p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
17953 iovec->ptr, iovec->size, p_ctx->frame_num, ui32LBA);
17954 ni_nvme_setup_aio_iocb(p_ctx->blk_io_handle, p_ctx->iocbs[i], iovec->ptr,
17955 (iovec->size + NI_MEM_PAGE_ALIGNMENT - 1) & ~(NI_MEM_PAGE_ALIGNMENT - 1),
17956 ui32LBA, 1);
17957 }
17958
17959 retval = ni_nvme_batch_cmd_aio(p_ctx->aio_context, p_ctx->iocbs, p_ctx->io_event, iovec_batch);
17960 if (retval != NI_RETCODE_SUCCESS) {
17961 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to do batch io\n", __func__);
17962 LRETURN;
17963 }
17964#else
17965 for (i = 0; (int)i < iovec_batch; i++) {
17966 ni_iovec_t *iovec = &p_frame->iovec[iovec_index + i];
17967 ui32LBA = WRITE_INSTANCE_W(p_ctx->session_id, NI_DEVICE_TYPE_AI) + rel_lba;
17968 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai session write: data = %p, size = %u, "
17969 "p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
17970 iovec->ptr, iovec->size, p_ctx->frame_num,
17971 ui32LBA);
17972
17973 sent_size = (iovec->size + NI_MEM_PAGE_ALIGNMENT - 1) &
17974 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17975 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17976 iovec->ptr, sent_size, ui32LBA);
17977 if (retval != NI_RETCODE_SUCCESS) {
17978 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
17979 LRETURN;
17980 }
17981 rel_lba = (((iovec->size + NI_MEM_PAGE_ALIGNMENT - 1) &
17982 ~(NI_MEM_PAGE_ALIGNMENT - 1)) >> LBA_BIT_OFFSET) + 1;
17983 }
17984#endif
17985 iovec_index += iovec_batch;
17986 iovec_left -= iovec_batch;
17987 } while (iovec_left);
17988
17990 "6K") >= 0)
17991 {
17992 if (retval != NI_RETCODE_SUCCESS)
17993 {
17994 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
17996 LRETURN;
17997 }
17999 &p_ctx->session_statistic);
18000 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
18002 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
18003 } else
18004 {
18005 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
18006 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18007 if (retval < 0)
18008 {
18009 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18011 LRETURN;
18012 }
18013 }
18014 }
18015
18016 p_ctx->frame_num++;
18017
18018 retval = frame_size_bytes;
18019
18020END:
18021
18023
18024 free(buffer_info);
18025
18026 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18027
18028 return retval;
18029}
18030
18032 ni_packet_t *p_packet)
18033{
18034 uint32_t actual_read_size = 0;
18035 int retval = NI_RETCODE_SUCCESS;
18036 uint32_t ui32LBA = 0;
18037 ni_instance_buf_info_t buf_info = {0};
18038
18039 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
18040
18041 if (!p_ctx || !p_packet || !p_packet->p_data)
18042 {
18043 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18044 __func__);
18045 retval = NI_RETCODE_INVALID_PARAM;
18046 return retval;
18047 }
18048
18050
18051 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
18052 {
18053 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
18054 __func__);
18056 LRETURN;
18057 }
18058
18059 for (;;)
18060 {
18061 if (p_ctx->session_statistic.ui32RdBufAvailSize >= p_packet->data_len)
18062 {
18063 buf_info.buf_avail_size =
18065 ni_log2(p_ctx, NI_LOG_DEBUG,
18066 "Info ai read query success, available buf "
18067 "size %u >= frame size %u !\n",
18068 buf_info.buf_avail_size, p_packet->data_len);
18069 break;
18070 }
18072 "6K") >= 0)
18073 {
18075 &p_ctx->session_statistic);
18076 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
18078 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
18079 buf_info.buf_avail_size =
18081 } else
18082 {
18084 NI_DEVICE_TYPE_AI, &buf_info);
18085 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
18086 p_ctx->device_type, p_ctx->hw_id,
18087 &(p_ctx->session_id), OPT_1);
18088 }
18089 ni_log2(p_ctx, NI_LOG_TRACE,
18090 "Info ai read query rc %d, available buf size %u, "
18091 "frame_num=%" PRIu64 ", pkt_num=%" PRIu64 "\n",
18092 retval, buf_info.buf_avail_size, p_ctx->frame_num,
18093 p_ctx->pkt_num);
18094
18095 if (NI_RETCODE_SUCCESS != retval)
18096 {
18097 ni_log2(p_ctx, NI_LOG_DEBUG, "Buffer info query failed in ai read!!!!\n");
18098 LRETURN;
18099 } else if (0 == buf_info.buf_avail_size)
18100 {
18101 ni_log2(p_ctx, NI_LOG_DEBUG, "Info ai read available buf size %u, eos %u !\n",
18102 buf_info.buf_avail_size, p_packet->end_of_stream);
18103 retval = NI_RETCODE_SUCCESS;
18104 LRETURN;
18105 }
18106 }
18107 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai read buf_avail_size %u\n", buf_info.buf_avail_size);
18108
18109 assert(buf_info.buf_avail_size >= p_packet->data_len);
18110
18111 ui32LBA = READ_INSTANCE_R(p_ctx->session_id, NI_DEVICE_TYPE_AI);
18112 actual_read_size = p_packet->data_len;
18113 if (actual_read_size & (NI_MEM_PAGE_ALIGNMENT - 1))
18114 {
18115 actual_read_size = (actual_read_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
18116 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18117 }
18118
18119 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
18120 p_packet->p_data, actual_read_size, ui32LBA);
18122 "6K") >= 0)
18123 {
18124 if (retval != NI_RETCODE_SUCCESS)
18125 {
18126 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18128 LRETURN;
18129 }
18131 &p_ctx->session_statistic);
18132 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
18134 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
18135 } else
18136 {
18137 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
18138 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18139 if (retval < 0)
18140 {
18141 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18143 LRETURN;
18144 }
18145 }
18146
18147 retval = p_packet->data_len;
18148
18149END:
18150
18152
18153 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18154
18155 return retval;
18156}
18157
18158static void ni_unreference_network_data(ni_network_data_t *network_data)
18159{
18160 if (network_data)
18161 {
18162 ni_memfree(network_data->inset);
18163 ni_memfree(network_data->linfo.in_param);
18164 }
18165}
18166
18168 ni_network_data_t *p_network)
18169{
18170 void *p_buffer = NULL;
18171 void *p_info = NULL;
18173 uint32_t ui32LBA = 0;
18174 uint32_t dataLen;
18175 int32_t query_retry = 0;
18176 uint32_t l;
18177 ni_network_layer_params_t *layer_param;
18178 uint32_t buffer_size;
18179 uint32_t this_size;
18180 ni_network_data_t *network_data = NULL;
18181 uint32_t total_io_num;
18182
18183 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
18184
18185 if (!p_ctx || !p_network)
18186 {
18187 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18188 __func__);
18189 retval = NI_RETCODE_INVALID_PARAM;
18190 LRETURN;
18191 }
18192
18193 network_data = p_ctx->network_data;
18194 if (network_data->linfo.in_param != NULL)
18195 {
18196 ni_log2(p_ctx, NI_LOG_ERROR,
18197 "ERROR: %s(): network parameters data is already initialized\n",
18198 __func__);
18199 retval = NI_RETCODE_SUCCESS;
18200 LRETURN;
18201 }
18202
18204
18205 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
18206 {
18207 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
18208 __func__);
18210 LRETURN;
18211 }
18212
18213 /* query available size can be read. */
18214 dataLen = (sizeof(ni_instance_buf_info_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
18215 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18216 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
18217 {
18218 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
18219 NI_ERRNO, __func__);
18221 LRETURN;
18222 }
18223 memset(p_buffer, 0, dataLen);
18224
18225 for (;;)
18226 {
18228 "6J") >= 0)
18229 {
18230 ui32LBA = QUERY_INSTANCE_NL_SIZE_V2_R(p_ctx->session_id,
18232 } else
18233 {
18234 ui32LBA =
18236 }
18237 retval =
18239 p_buffer, dataLen, ui32LBA);
18240 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
18241 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18242 if (retval != NI_RETCODE_SUCCESS)
18243 {
18244 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
18246 LRETURN;
18247 }
18248
18249 if (((ni_instance_buf_info_t *)p_buffer)->buf_avail_size > 0)
18250 {
18251 break;
18252 }
18253
18254 query_retry++;
18255 if (query_retry > 50000)
18256 {
18257 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): exceeded max query retries: %d\n",
18258 __func__, query_retry - 1);
18260 LRETURN;
18261 }
18263 ni_usleep(200);
18265 continue;
18266 }
18267
18268 if (((ni_instance_buf_info_t *)p_buffer)->buf_avail_size == 0)
18269 {
18271 LRETURN;
18272 }
18273
18275 "6J") >= 0)
18276 {
18277 network_data->input_num =
18278 ((ni_instance_buf_info_t *)p_buffer)->buf_avail_size >> 16;
18279 network_data->output_num =
18280 ((ni_instance_buf_info_t *)p_buffer)->buf_avail_size & 0xFFFF;
18281 } else
18282 {
18283 network_data->input_num = 4;
18284 network_data->output_num = 4;
18285 }
18286
18287 total_io_num = network_data->input_num + network_data->output_num;
18288
18289 network_data->linfo.in_param = (ni_network_layer_params_t *)calloc(
18290 total_io_num, sizeof(ni_network_layer_params_t));
18291 if (!network_data->linfo.in_param)
18292 {
18293 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Unable to allocate network layer params\n",
18294 __func__);
18296 LRETURN;
18297 }
18298 network_data->linfo.out_param =
18299 network_data->linfo.in_param + network_data->input_num;
18300
18301 network_data->inset = (ni_network_layer_offset_t *)calloc(
18302 total_io_num, sizeof(ni_network_layer_offset_t));
18303 if (!network_data->inset)
18304 {
18305 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Unable to allocate network offset\n",
18306 __func__);
18308 LRETURN;
18309 }
18310 network_data->outset = network_data->inset + network_data->input_num;
18311
18313 "6J") >= 0)
18314 {
18315 /* query the real network layer data */
18316 this_size = sizeof(ni_network_layer_params_t) * total_io_num;
18317 dataLen = (this_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
18318 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18319 if (ni_posix_memalign(&p_info, sysconf(_SC_PAGESIZE), dataLen))
18320 {
18321 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate info buffer\n",
18322 NI_ERRNO, __func__);
18324 LRETURN;
18325 }
18326 memset(p_info, 0, dataLen);
18327
18329 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
18330 p_info, dataLen, ui32LBA);
18331 if ((int32_t)retval < 0)
18332 {
18333 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
18335 LRETURN;
18336 }
18337 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
18338 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18339 memcpy(network_data->linfo.in_param, p_info, this_size);
18340 } else
18341 {
18342 /* query the real network layer data */
18343 this_size = sizeof(ni_network_layer_params_t) * total_io_num;
18344 dataLen = (this_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
18345 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18346 if (ni_posix_memalign(&p_info, sysconf(_SC_PAGESIZE), dataLen))
18347 {
18348 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate info buffer\n",
18349 NI_ERRNO, __func__);
18351 LRETURN;
18352 }
18353 memset(p_info, 0, dataLen);
18354
18356 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
18357 p_info, dataLen, ui32LBA);
18358 if ((int32_t)retval < 0)
18359 {
18360 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
18362 LRETURN;
18363 }
18364 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
18365 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18366 memcpy(network_data->linfo.in_param, p_info, this_size);
18367
18368 for (l = 0, network_data->input_num = 0; l < 4; l++)
18369 {
18370 layer_param = &network_data->linfo.in_param[l];
18371 if (layer_param->num_of_dims == 0)
18372 {
18373 break;
18374 }
18375 network_data->input_num++;
18376 }
18377
18378 for (l = 0, network_data->output_num = 0; l < 4; l++)
18379 {
18380 layer_param = &network_data->linfo.out_param[l];
18381 if (layer_param->num_of_dims == 0)
18382 {
18383 break;
18384 }
18385 network_data->output_num++;
18386 }
18387 }
18388
18389 for (l = 0, buffer_size = 0; l < network_data->input_num; l++)
18390 {
18391 layer_param = &network_data->linfo.in_param[l];
18392 this_size = ni_ai_network_layer_size(layer_param);
18393 this_size =
18394 (this_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
18395 network_data->inset[l].offset = buffer_size;
18396 buffer_size += this_size;
18397
18398 ni_log2(p_ctx,
18400 "%s(): network input layer %d: dims %u, %u/%u/%u/%u, f %d, q %d\n",
18401 __func__, l, layer_param->num_of_dims, layer_param->sizes[0],
18402 layer_param->sizes[1], layer_param->sizes[2], layer_param->sizes[3],
18403 layer_param->data_format, layer_param->quant_format);
18404 }
18405
18406 for (l = 0, buffer_size = 0; l < network_data->output_num; l++)
18407 {
18408 layer_param = &network_data->linfo.out_param[l];
18409 this_size = ni_ai_network_layer_size(layer_param);
18410 this_size =
18411 (this_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
18412 network_data->outset[l].offset = buffer_size;
18413 buffer_size += this_size;
18414
18415 ni_log2(p_ctx,
18417 "%s(): network output layer %d: dims %u, %u/%u/%u/%u, f %d, q %d\n",
18418 __func__, l, layer_param->num_of_dims, layer_param->sizes[0],
18419 layer_param->sizes[1], layer_param->sizes[2], layer_param->sizes[3],
18420 layer_param->data_format, layer_param->quant_format);
18421 }
18422
18423 memcpy(p_network, network_data, sizeof(ni_network_data_t));
18424
18425 retval = NI_RETCODE_SUCCESS;
18426
18427END:
18429
18430 if (retval != NI_RETCODE_SUCCESS)
18431 {
18432 ni_unreference_network_data(network_data);
18433 }
18434 ni_aligned_free(p_buffer);
18435 ni_aligned_free(p_info);
18436 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18437 return retval;
18438}
18439
18441{
18443 void *p_buffer = NULL;
18444 uint32_t ui32LBA = 0;
18445
18446 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
18447
18448 if (!p_ctx)
18449 {
18450 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18451 __func__);
18452 retval = NI_RETCODE_INVALID_PARAM;
18453 LRETURN;
18454 }
18455
18456 //Check if there is an instance or we need a new one
18457 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
18458 {
18460 p_ctx->pts_table = NULL;
18461 p_ctx->dts_queue = NULL;
18462 p_ctx->buffer_pool = NULL;
18463 p_ctx->status = 0;
18464 p_ctx->key_frame_type = 0;
18465 p_ctx->keyframe_factor = 1;
18466 p_ctx->frame_num = 0;
18467 p_ctx->pkt_num = 0;
18468 p_ctx->rc_error_count = 0;
18469 p_ctx->force_frame_type = 0;
18470 p_ctx->ready_to_close = 0;
18471 //Sequence change tracking reated stuff
18472 p_ctx->active_video_width = 0;
18473 p_ctx->active_video_height = 0;
18474 p_ctx->p_all_zero_buf = NULL;
18475 p_ctx->actual_video_width = 0;
18477 memset(&(p_ctx->param_err_msg[0]), 0, sizeof(p_ctx->param_err_msg));
18478
18479 //malloc zero data buffer
18480 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
18482 {
18483 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc all zero buffer failed\n",
18484 NI_ERRNO, __func__);
18486 LRETURN;
18487 }
18488 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
18489
18490 //malloc data buffer
18491 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
18493 {
18494 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
18495 NI_ERRNO, __func__);
18497 LRETURN;
18498 }
18499 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
18500
18501 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
18502 //In case we can open sesison, the session id would become valid.
18503 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
18504 (uint16_t)NI_INVALID_SESSION_ID;
18505
18506 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
18507 ui32LBA = OPEN_SESSION_CODEC(NI_DEVICE_TYPE_AI, 0, p_ctx->hw_action);
18508 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): LBA 0x%x, hw_action %d\n", __func__,
18509 ui32LBA, p_ctx->hw_action);
18510 retval =
18512 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
18513 if (retval != NI_RETCODE_SUCCESS)
18514 {
18515 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR ni_nvme_send_read_cmd\n");
18516 LRETURN;
18517 }
18518 //Open will return a session status structure with a valid session id if it worked.
18519 //Otherwise the invalid session id set before the open command will stay
18520 if ((uint16_t)NI_INVALID_SESSION_ID ==
18521 ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId))
18522 {
18523 ni_log2(p_ctx, NI_LOG_ERROR,
18524 "ERROR %s(): p_ctx->device_handle=%" PRIx64
18525 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
18526 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
18527 p_ctx->session_id);
18528 ni_ai_session_close(p_ctx, 0);
18530 LRETURN;
18531 }
18532 p_ctx->session_id =
18533 ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
18534 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
18535 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
18536 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
18537 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai open session ID:0x%x,timestamp:%" PRIu64 "\n",
18538 p_ctx->session_id, p_ctx->session_timestamp);
18539
18540 ni_log2(p_ctx, NI_LOG_DEBUG, "Open session completed\n");
18541 ni_log2(p_ctx, NI_LOG_DEBUG,
18542 "%s(): p_ctx->device_handle=%" PRIx64
18543 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
18544 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
18545 p_ctx->session_id);
18546
18547 //Send keep alive timeout Info
18548 uint64_t keep_alive_timeout =
18549 p_ctx->keep_alive_timeout * 1000000; //send us to FW
18550 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
18551 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
18552 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
18553 keep_alive_timeout);
18555 retval =
18557 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
18559 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18560 CHECK_VPU_RECOVERY(retval);
18561
18562 if (NI_RETCODE_SUCCESS != retval)
18563 {
18564 ni_log2(p_ctx, NI_LOG_ERROR,
18565 "ERROR %s(): nvme write keep_alive_timeout command "
18566 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
18567 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
18569 LRETURN;
18570 }
18571
18572 p_ctx->network_data =
18573 (ni_network_data_t *)calloc(1, sizeof(ni_network_data_t));
18574 if (!p_ctx->network_data)
18575 {
18576 ni_log2(p_ctx, NI_LOG_ERROR,
18577 "ERROR %s(): Unable to allocate network_data memory\n");
18579 LRETURN;
18580 }
18581 }
18582
18583 //aio
18584#ifdef __linux__
18585 if (ni_aio_setup(NI_MAX_SEGMENT_NUM, &p_ctx->aio_context) != 0) {
18586 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to setup aio context\n", __func__);
18588 LRETURN;
18589 }
18590
18591 p_ctx->iocbs = (ni_iocb_t **)malloc(sizeof(ni_iocb_t *) * NI_MAX_SEGMENT_NUM);
18592 if (!p_ctx->iocbs) {
18593 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to allocate iocbs\n", __func__);
18595 LRETURN;
18596 } else {
18597 int i;
18598 for (i = 0; i < NI_MAX_SEGMENT_NUM; i++) {
18599 p_ctx->iocbs[i] = (ni_iocb_t *)malloc(sizeof(ni_iocb_t));
18600 if (!p_ctx->iocbs[i]) {
18601 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to allocate iocb %d\n", __func__, i);
18603 LRETURN;
18604 }
18605 }
18606 }
18607
18608 p_ctx->io_event = (ni_io_event_t *)malloc(sizeof(ni_io_event_t) * NI_MAX_SEGMENT_NUM);
18609 if (!p_ctx->io_event) {
18610 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to allocate ioevent %d\n", __func__);
18612 LRETURN;
18613 }
18614#endif
18615
18616 // init for frame pts calculation
18617 p_ctx->is_first_frame = 1;
18618 p_ctx->last_pts = 0;
18619 p_ctx->last_dts = 0;
18620 p_ctx->active_video_width = 0;
18621 p_ctx->active_video_height = 0;
18622 p_ctx->actual_video_width = 0;
18623
18624END:
18625
18626 ni_aligned_free(p_buffer);
18627 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18628 return retval;
18629}
18630
18632{
18634 void *p_buffer = NULL;
18635 uint32_t ui32LBA = 0;
18636
18637 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
18638
18639 if (!p_ctx)
18640 {
18641 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18642 __func__);
18644 }
18645
18647
18648 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
18649 {
18650 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): Invalid session ID, return.\n", __func__);
18651 retval = NI_RETCODE_SUCCESS;
18652 LRETURN;
18653 }
18654
18655 //malloc data buffer
18656 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
18657 {
18658 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
18659 NI_ERRNO, __func__);
18661 LRETURN;
18662 }
18663 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
18664
18665 ui32LBA = CLOSE_SESSION_R(p_ctx->session_id, NI_DEVICE_TYPE_AI);
18666
18667 int retry = 0;
18668 while (retry < NI_SESSION_CLOSE_RETRY_MAX)
18669 {
18670 ni_log2(p_ctx, NI_LOG_DEBUG,
18671 "%s(): p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
18672 "p_ctx->session_id=%d, close_mode=1\n",
18673 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
18674 p_ctx->session_id);
18675
18677 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
18678 {
18679 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): command failed\n", __func__);
18682 break;
18683 } else
18684 {
18685 //Close should always succeed
18686 retval = NI_RETCODE_SUCCESS;
18688 break;
18689 }
18690 /*
18691 else if(((ni_session_closed_status_t *)p_buffer)->session_closed)
18692 {
18693 retval = NI_RETCODE_SUCCESS;
18694 p_ctx->session_id = NI_INVALID_SESSION_ID;
18695 break;
18696 }
18697 else
18698 {
18699 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): wait for close\n", __func__);
18700 ni_usleep(NI_SESSION_CLOSE_RETRY_INTERVAL_US);
18701 retval = NI_RETCODE_ERROR_NVME_CMD_FAILED;
18702 }
18703 */
18704 retry++;
18705 }
18706
18707END:
18708
18709#ifdef __linux__
18710 if (p_ctx->aio_context != 0) {
18711 if (ni_aio_destroy(p_ctx->aio_context) != 0) {
18712 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to destroy aio context\n", __func__);
18713 } else {
18714 p_ctx->aio_context = 0;
18715 }
18716 }
18717 if (p_ctx->iocbs) {
18718 for (int i = 0; i < NI_MAX_SEGMENT_NUM; i++) {
18719 ni_memfree(p_ctx->iocbs[i]);
18720 }
18721 ni_memfree(p_ctx->iocbs);
18722 }
18723 ni_memfree(p_ctx->io_event);
18724#endif
18725
18726 ni_unreference_network_data(p_ctx->network_data);
18727 ni_memfree(p_ctx->network_data);
18728
18729 ni_aligned_free(p_buffer);
18731
18732 //Sequence change related stuff cleanup here
18733 p_ctx->active_video_width = 0;
18734 p_ctx->active_video_height = 0;
18735 p_ctx->actual_video_width = 0;
18736
18737 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): CTX[Card:%" PRIx64 " / HW:%d / INST:%d]\n",
18738 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
18739 p_ctx->session_id);
18740 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18741
18743
18744 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18745
18746 return retval;
18747}
18748
18750 ni_frame_config_t p_cfg_in[],
18751 int numInCfgs,
18752 ni_frame_config_t *p_cfg_out)
18753{
18755 ni_network_buffer_info_t *p_data = NULL;
18756 void *p_read_data = NULL;
18757 uint32_t dataLen;
18758 uint32_t ui32LBA = 0;
18759
18760 if (!p_ctx)
18761 {
18762 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18763 __func__);
18765 }
18766
18767 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
18768 {
18769 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
18770 __func__);
18772 }
18774 ni_instance_buf_info_t buf_info = {0};
18775 int32_t query_retry = 0;
18776 for (;;)
18777 {
18779 {
18780 buf_info.buf_avail_size =
18782 ni_log2(p_ctx, NI_LOG_DEBUG,
18783 "Info ai write query success, available buf "
18784 "size %u !\n",
18785 buf_info.buf_avail_size);
18786 break;
18787 }
18788
18790 &p_ctx->session_statistic);
18791 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
18793 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
18794 buf_info.buf_avail_size =
18796 if (NI_RETCODE_SUCCESS != retval ||
18797 buf_info.buf_avail_size == 0)
18798 {
18799 ni_log2(p_ctx, NI_LOG_TRACE,
18800 "AI write query failed or buf_size < frame_size. Retry %d\n",
18801 query_retry);
18802 // extend to 5000 retries for 8K encode on FPGA
18803 if (query_retry >= NI_MAX_ENCODER_QUERY_RETRIES)
18804 {
18805 ni_log2(p_ctx, NI_LOG_TRACE,
18806 "AI write query exceeded max retries: %d\n",
18809 retval = NI_RETCODE_SUCCESS;
18810 LRETURN;
18811 }
18815 query_retry++;
18816 }
18817 }
18818
18819 dataLen = (sizeof(ni_network_buffer_info_t) + NI_MEM_PAGE_ALIGNMENT - 1) &
18820 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18821
18822 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
18823 {
18824 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
18825 NI_ERRNO, __func__);
18827 }
18828
18829 memset(p_data, 0x00, dataLen);
18830 p_data->ui16Width = p_cfg_in[0].picture_width;
18831 p_data->ui16Height = p_cfg_in[0].picture_height;
18832 p_data->ui16Option = p_cfg_in[0].options;
18833 p_data->ui8PoolSize = p_cfg_in[0].rgba_color;
18834 p_data->ui8MultiIn = 1;
18835 for(int i = 0; i < numInCfgs; i++){
18836 p_data->ui16FrameIdx[i] = p_cfg_in[i].frame_index;
18837 ni_log2(p_ctx, NI_LOG_DEBUG, "Dev alloc frame[%d]: frame_index %u, hw=%d\n",
18838 i,p_data->ui16FrameIdx[i], p_data->ui8MultiIn);
18839 }
18840
18841
18842 ui32LBA =
18844
18845 retval =
18847 p_data, dataLen, ui32LBA);
18849 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
18850 OPT_1);
18851 if (NI_RETCODE_SUCCESS != retval)
18852 {
18853 ni_log2(p_ctx,
18855 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
18856 ", hw_id, %u, xcoder_inst_id: %d\n",
18857 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
18858 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n",
18859 __func__);
18861 LRETURN;
18862 }
18863
18864 END:
18866 ni_aligned_free(p_data);
18867 if (p_read_data != NULL)
18868 {
18869 ni_aligned_free(p_read_data);
18870 }
18871 return retval;
18872}
18873
18875 niFrameSurface1_t *p_out_surface)
18876{
18878 ni_network_buffer_info_t *p_data = NULL;
18879 void *p_read_data = NULL;
18880 uint32_t dataLen;
18881 uint32_t ui32LBA = 0;
18882
18883 if (!p_ctx)
18884 {
18885 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18886 __func__);
18888 }
18889
18890 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
18891 {
18892 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
18893 __func__);
18895 }
18896
18899 "6rL") < 0)
18900 {
18901 ni_log2(p_ctx, NI_LOG_ERROR,
18902 "Error: %s function not supported on device with FW API version < 6rL\n",
18903 __func__);
18905 }
18906
18908
18909 int query_retry = 0;
18910 dataLen =
18912 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18913 if (ni_posix_memalign(&p_read_data, sysconf(_SC_PAGESIZE), dataLen))
18914 {
18915 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
18916 NI_ERRNO, __func__);
18918 LRETURN;
18919 }
18920 memset(p_read_data, 0, dataLen);
18921
18922 for (;;)
18923 {
18926 retval =
18928 p_read_data, dataLen, ui32LBA);
18929 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read,
18930 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
18931 OPT_1);
18932 if (retval != NI_RETCODE_SUCCESS)
18933 {
18934 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
18936 LRETURN;
18937 }
18938
18939 if (((ni_instance_buf_info_t *)p_read_data)->hw_inst_ind.buffer_avail > 0)
18940 {
18941 p_out_surface->ui16FrameIdx = ((ni_instance_buf_info_t *)p_read_data)->hw_inst_ind.frame_index;
18942 p_out_surface->ui16session_ID = p_ctx->session_id;
18943 p_out_surface->device_handle =
18944 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
18945 p_out_surface->bit_depth = p_ctx->bit_depth_factor;
18946 p_out_surface->src_cpu = (uint8_t)NI_DEVICE_TYPE_AI;
18947 p_out_surface->output_idx = 0;
18948 break;
18949 }
18950
18951 query_retry++;
18952 if (query_retry > 2000)
18953 {
18954 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): exceeded max query retries: %d\n",
18955 __func__, query_retry - 1);
18956 retval = NI_RETCODE_EAGAIN;
18957 LRETURN;
18958 }
18960 ni_usleep(200);
18962 continue;
18963 }
18964
18965 if (((ni_instance_buf_info_t *)p_read_data)->hw_inst_ind.buffer_avail == 0)
18966 {
18968 LRETURN;
18969 }
18970END:
18972 ni_aligned_free(p_data);
18973 if (p_read_data != NULL)
18974 {
18975 ni_aligned_free(p_read_data);
18976 }
18977 return retval;
18978}
18979
18981 int height, int options, int pool_size,
18982 int frame_index)
18983{
18985 ni_network_buffer_info_t *p_data = NULL;
18986 void *p_read_data = NULL;
18987 uint32_t dataLen;
18988 uint32_t ui32LBA = 0;
18989
18990 if (!p_ctx)
18991 {
18992 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18993 __func__);
18995 }
18996
18997 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
18998 {
18999 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
19000 __func__);
19002 }
19003
19005
19006 if (options == NI_AI_FLAG_IO)
19007 {
19008 int query_retry = 0;
19009 dataLen =
19011 ~(NI_MEM_PAGE_ALIGNMENT - 1);
19012 if (ni_posix_memalign(&p_read_data, sysconf(_SC_PAGESIZE), dataLen))
19013 {
19014 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
19015 NI_ERRNO, __func__);
19017 LRETURN;
19018 }
19019 memset(p_read_data, 0, dataLen);
19020
19021 for (;;)
19022 {
19025 retval =
19027 p_read_data, dataLen, ui32LBA);
19028 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read,
19029 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
19030 OPT_1);
19031 if (retval != NI_RETCODE_SUCCESS)
19032 {
19033 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
19035 LRETURN;
19036 }
19037
19038 if (((ni_instance_buf_info_t *)p_read_data)->buf_avail_size > 0)
19039 {
19040 break;
19041 }
19042
19043 query_retry++;
19044 if (query_retry > 2000)
19045 {
19046 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): exceeded max query retries: %d\n",
19047 __func__, query_retry - 1);
19048 retval = NI_RETCODE_EAGAIN;
19049 LRETURN;
19050 }
19052 ni_usleep(200);
19054 continue;
19055 }
19056
19057 if (((ni_instance_buf_info_t *)p_read_data)->buf_avail_size == 0)
19058 {
19060 LRETURN;
19061 }
19062 } else
19063 {
19064 ni_instance_buf_info_t buf_info = {0};
19065 int32_t query_retry = 0;
19066 for (;;)
19067 {
19069 {
19070 buf_info.buf_avail_size =
19072 ni_log2(p_ctx, NI_LOG_DEBUG,
19073 "Info ai write query success, available buf "
19074 "size %u !\n",
19075 buf_info.buf_avail_size);
19076 break;
19077 }
19078
19080 &p_ctx->session_statistic);
19081 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
19083 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
19084 buf_info.buf_avail_size =
19086 if (NI_RETCODE_SUCCESS != retval ||
19087 buf_info.buf_avail_size == 0)
19088 {
19089 ni_log2(p_ctx, NI_LOG_TRACE,
19090 "AI write query failed or buf_size < frame_size. Retry %d\n",
19091 query_retry);
19092 // extend to 5000 retries for 8K encode on FPGA
19093 if (query_retry >= NI_MAX_ENCODER_QUERY_RETRIES)
19094 {
19095 ni_log2(p_ctx, NI_LOG_TRACE,
19096 "AI write query exceeded max retries: %d\n",
19099 retval = NI_RETCODE_SUCCESS;
19100 LRETURN;
19101 }
19105 query_retry++;
19106 }
19107 }
19108
19109 dataLen = (sizeof(ni_network_buffer_info_t) + NI_MEM_PAGE_ALIGNMENT - 1) &
19110 ~(NI_MEM_PAGE_ALIGNMENT - 1);
19111
19112 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
19113 {
19114 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
19115 NI_ERRNO, __func__);
19117 }
19118
19119 memset(p_data, 0x00, dataLen);
19120 p_data->ui16FrameIdx[0] = frame_index;
19121 p_data->ui16Width = width;
19122 p_data->ui16Height = height;
19123 p_data->ui16Option = options;
19124 p_data->ui8PoolSize = pool_size;
19125 p_data->ui8MultiIn = 0;
19126 ni_log2(p_ctx, NI_LOG_DEBUG, "Dev alloc frame: frame_index %u\n",
19127 p_data->ui16FrameIdx[0]);
19128
19129 ui32LBA =
19131
19132 retval =
19134 p_data, dataLen, ui32LBA);
19136 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
19137 OPT_1);
19138 if (NI_RETCODE_SUCCESS != retval)
19139 {
19140 ni_log2(p_ctx,
19142 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
19143 ", hw_id, %u, xcoder_inst_id: %d\n",
19144 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
19145 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n",
19146 __func__);
19148 LRETURN;
19149 }
19150 }
19151
19152END:
19154 ni_aligned_free(p_data);
19155 if (p_read_data != NULL)
19156 {
19157 ni_aligned_free(p_read_data);
19158 }
19159 return retval;
19160}
19161
19162/*!******************************************************************************
19163 * \brief read a hardware descriptor from a scaler session
19164 *
19165 * \param[in] p_ctx pointer to session context
19166 * \param[out] p_frame pointer to frame to write hw descriptor
19167 *
19168 * \return NI_RETCODE_INVALID_PARAM
19169 * NI_RETCODE_ERROR_INVALID_SESSION
19170 * NI_RETCODE_ERROR_MEM_ALOC
19171 * NI_RETCODE_ERROR_NVME_CMD_FAILED
19172 * NI_RETCODE_FAILURE
19173 *******************************************************************************/
19175 ni_frame_t *p_frame)
19176{
19177 int retval = NI_RETCODE_SUCCESS;
19178 int retry_count = 0;
19179
19180 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
19181
19183
19184 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
19185 {
19186 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
19187 __func__);
19189 LRETURN;
19190 }
19191
19192 for (;;)
19193 {
19194 retry_count++;
19195 ni_instance_buf_info_t sInstanceBuf = {0};
19196 niFrameSurface1_t *pFrameSurface;
19198 NI_DEVICE_TYPE_AI, &sInstanceBuf);
19199 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
19200 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
19201 OPT_3);
19202
19204 {
19205 if (retry_count >= 500)
19206 {
19207 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning hwdesc read fail rc %d\n",
19208 retval);
19209 LRETURN;
19210 }
19212 ni_usleep(100);
19214 }
19215 else if (retval != NI_RETCODE_SUCCESS)
19216 {
19217 LRETURN;
19218 } else
19219 {
19220 pFrameSurface = (niFrameSurface1_t *)p_frame->p_data[3];
19221 pFrameSurface->ui16FrameIdx = sInstanceBuf.hw_inst_ind.frame_index;
19222 pFrameSurface->ui16session_ID = p_ctx->session_id;
19223 pFrameSurface->device_handle =
19224 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
19225 pFrameSurface->src_cpu = (uint8_t)NI_DEVICE_TYPE_AI;
19226 pFrameSurface->output_idx = 0;
19227
19228 /* A frame index of zero is invalid, the memory acquisition failed */
19229 if (pFrameSurface->ui16FrameIdx == 0)
19230 {
19231 if (retry_count >= 500)
19232 {
19233 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning hwdesc read fail rc %d\n",
19234 retval);
19235 retval = NI_RETCODE_EAGAIN;
19236 LRETURN;
19237 }
19239 ni_usleep(100);
19241 continue;
19242 }
19243 LRETURN;
19244 }
19245 }
19246
19247END:
19248
19250
19251 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
19252
19253 return retval;
19254}
19255
19256/*!*****************************************************************************
19257 * \brief Get DDR configuration of Quadra device
19258 *
19259 * \param[in/out] p_ctx pointer to a session context with valid file handle
19260 *
19261 * \return On success NI_RETCODE_SUCCESS
19262 * On failure NI_RETCODE_INVALID_PARAM
19263 * NI_RETCODE_ERROR_MEM_ALOC
19264 * NI_RETCODE_ERROR_NVME_CMD_FAILED
19265 ******************************************************************************/
19267{
19268 void *p_buffer = NULL;
19269 ni_nvme_identity_t *p_id_data;
19271 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
19272 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
19273 ni_device_handle_t device_handle = p_ctx->blk_io_handle;
19274
19275 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
19276
19277 if (NI_INVALID_DEVICE_HANDLE == device_handle)
19278 {
19279 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid passed parameters\n",
19280 __func__);
19281 retval = NI_RETCODE_INVALID_PARAM;
19282 LRETURN;
19283 }
19284
19285 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
19287 {
19288 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
19289 NI_ERRNO, __func__);
19291 LRETURN;
19292 }
19293
19294 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
19295
19296 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer,
19297 NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
19298 {
19300 LRETURN;
19301 }
19302
19303 p_id_data = (ni_nvme_identity_t *) p_buffer;
19304
19305 if (p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_SR_4G)
19306 {
19307 p_ctx->ddr_config = 6;
19308 }
19309 else
19310 {
19313 "6rJ") >= 0)
19314 {
19315 p_ctx->ddr_config = (p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_SR)
19316 ? 3 : ((p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_DR)? 4 : 5);
19317 }
19318 else if (ni_cmp_fw_api_ver(
19320 "6rD") >= 0)
19321 {
19322 p_ctx->ddr_config = (p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_SR)
19323 ? 3 : 4;
19324 } else
19325 {
19326 p_ctx->ddr_config = (p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_SR)
19327 ? 1 : 2;
19328 }
19329 }
19330
19331 ni_log2(p_ctx, NI_LOG_DEBUG, "Memory configuration %d\n",p_ctx->ddr_config);
19332END:
19333
19334 ni_aligned_free(p_buffer);
19335 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): retval: %d\n", __func__, retval);
19336
19337 return retval;
19338}
19339
19340/*!*****************************************************************************
19341 * \brief Set DDR configuration of Quadra device
19342 *
19343 * \param[in] p_ctx pointer to a session context with valid file handle
19344 * \param[in] ddr_priority_mode ddr priority mode
19345 *
19346 * \return On success NI_RETCODE_SUCCESS
19347 * On failure NI_RETCODE_INVALID_PARAM
19348 * NI_RETCODE_ERROR_MEM_ALOC
19349 * NI_RETCODE_ERROR_NVME_CMD_FAILED
19350 ******************************************************************************/
19352 uint8_t ddr_priority_mode)
19353{
19354 void *p_buffer = NULL;
19356 ni_ddr_priority_config_t *p_cfg = NULL;
19357 uint32_t ui32LBA = CONFIG_SESSION_DDR_PRIORITY_W(p_ctx->session_id);
19358 ni_device_handle_t device_handle = p_ctx->blk_io_handle;
19359
19360 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
19361
19362 ni_log2(p_ctx, NI_LOG_INFO, "set ddr priority %d\n",
19363 ddr_priority_mode);
19364
19365 if (NI_INVALID_DEVICE_HANDLE == device_handle)
19366 {
19367 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid passed parameters\n",
19368 __func__);
19369 retval = NI_RETCODE_INVALID_PARAM;
19370 LRETURN;
19371 }
19372
19373 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
19375 {
19376 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
19377 NI_ERRNO, __func__);
19379 LRETURN;
19380 }
19381
19382 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
19383 p_cfg = (ni_ddr_priority_config_t *)p_buffer;
19384 p_cfg->ddr_mode = ddr_priority_mode;
19385 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, NI_INVALID_EVENT_HANDLE,
19386 p_buffer,NI_DATA_BUFFER_LEN, ui32LBA) < 0)
19387 {
19388 ni_log2(p_ctx, NI_LOG_ERROR, "DDR priority setting failed with mode %d\n",
19389 ddr_priority_mode);
19391 LRETURN;
19392 }
19393END:
19394 ni_aligned_free(p_buffer);
19395 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): retval: %d\n", __func__, retval);
19396
19397 return retval;
19398}
19399
19400/*!*****************************************************************************
19401 * \brief Allocate memory for the metadata header and auxillary data for
19402 * encoder input data.
19403 *
19404 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
19405 *
19406 * \param[in] extra_len Length header and auxillary data
19407 *
19408 * \return On success
19409 * NI_RETCODE_SUCCESS
19410 * On failure
19411 * NI_RETCODE_INVALID_PARAM
19412 * NI_RETCODE_ERROR_MEM_ALOC
19413 *****************************************************************************/
19415 int extra_len)
19416{
19417 void *metadata_buffer = NULL;
19418 int retval = NI_RETCODE_SUCCESS;
19419
19420 if ((!p_frame) || (extra_len <= 0))
19421 {
19423 "ERROR: %s passed parameters are null or not supported, "
19424 "p_frame %p, extra_len %d",
19425 __func__, p_frame, extra_len);
19427 }
19428
19429 int buffer_size = extra_len;
19430 if (buffer_size % NI_MEM_PAGE_ALIGNMENT)
19431 {
19432 buffer_size = ((buffer_size / NI_MEM_PAGE_ALIGNMENT) + 1) *
19434 }
19435
19436 // Check if previous metadata buffer needs to be freed
19437 if ((p_frame->metadata_buffer_size != buffer_size) &&
19438 (p_frame->metadata_buffer_size > 0))
19439 {
19441 "%s: free current p_frame metadata buffer, "
19442 "p_frame->buffer_size=%u\n",
19443 __func__, p_frame->metadata_buffer_size);
19444 p_frame->metadata_buffer_size = 0;
19446 }
19447
19448 // Check if new metadata buffer needs to be allocated
19449 if (p_frame->metadata_buffer_size != buffer_size)
19450 {
19451 if (ni_posix_memalign(&metadata_buffer, sysconf(_SC_PAGESIZE),
19452 buffer_size))
19453 {
19455 "ERROR %d: %s() Cannot allocate metadata buffer.\n",
19456 NI_ERRNO, __func__);
19458 LRETURN;
19459 }
19460
19461 // init once after allocation
19462 memset(metadata_buffer, 0, buffer_size);
19463 p_frame->metadata_buffer_size = buffer_size;
19464 p_frame->p_metadata_buffer = metadata_buffer;
19465
19466 ni_log(NI_LOG_DEBUG, "%s: allocated new metadata buffer\n", __func__);
19467 } else
19468 {
19469 ni_log(NI_LOG_DEBUG, "%s: reuse metadata buffer\n", __func__);
19470 }
19471
19473 "%s: success: p_frame->p_metadata_buffer %p "
19474 "p_frame->metadata_buffer_size=%u\n",
19475 __func__, p_frame->p_metadata_buffer, p_frame->metadata_buffer_size);
19476
19477END:
19478
19479 if (NI_RETCODE_SUCCESS != retval)
19480 {
19481 ni_aligned_free(metadata_buffer);
19482 }
19483
19484 return retval;
19485}
19486
19487/*!*****************************************************************************
19488 * \brief Allocate memory for the non-4k-aligned part at the start of YUV data for
19489 * encoder input data.
19490 *
19491 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
19492 *
19493 * \param[in] start_len Length of non-4k-aligned part at the start of YUV data
19494 *
19495 * \return On success
19496 * NI_RETCODE_SUCCESS
19497 * On failure
19498 * NI_RETCODE_INVALID_PARAM
19499 * NI_RETCODE_ERROR_MEM_ALOC
19500 *****************************************************************************/
19502{
19503 void *start_buffer = NULL;
19504 int retval = NI_RETCODE_SUCCESS;
19505
19506 if (!p_frame)
19507 {
19509 "ERROR: %s passed parameters are null or not supported, "
19510 "p_frame %p\n",
19511 __func__, p_frame);
19513 }
19514
19515 // Check if new start buffer needs to be allocated
19516 if (!p_frame->start_buffer_size)
19517 {
19518 if (ni_posix_memalign(&start_buffer, sysconf(_SC_PAGESIZE),
19520 {
19522 "ERROR %d: %s() Cannot allocate start buffer.\n",
19523 NI_ERRNO, __func__);
19525 LRETURN;
19526 }
19527
19528 // init once after allocation
19531 p_frame->p_start_buffer = start_buffer;
19532
19533 ni_log(NI_LOG_DEBUG, "%s: allocated new start buffer\n", __func__);
19534 } else
19535 {
19536 ni_log(NI_LOG_DEBUG, "%s: reuse start buffer\n", __func__);
19537 }
19538
19540 "%s: success: p_frame->p_start_buffer %p "
19541 "p_frame->start_buffer_size=%u\n",
19542 __func__, p_frame->p_start_buffer, p_frame->start_buffer_size);
19543
19544END:
19545
19546 if (NI_RETCODE_SUCCESS != retval)
19547 {
19548 ni_aligned_free(start_buffer);
19549 }
19550
19551 return retval;
19552}
19553
19555 ni_network_perf_metrics_t *p_metrics)
19556{
19558 void *p_buffer = NULL;
19559 uint32_t dataLen;
19560 uint32_t ui32LBA = 0;
19561
19562 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
19563 if (!p_ctx || !p_metrics)
19564 {
19565 ni_log2(p_ctx, NI_LOG_ERROR,
19566 "ERROR: %s() passed parameters are null!, return\n", __func__);
19567 retval = NI_RETCODE_INVALID_PARAM;
19568 LRETURN;
19569 }
19570
19572 "6N") >= 0)
19573 {
19574 dataLen =
19576 ~(NI_MEM_PAGE_ALIGNMENT - 1);
19577 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
19578 {
19579 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
19580 NI_ERRNO, __func__);
19582 LRETURN;
19583 }
19584 memset(p_buffer, 0, sizeof(ni_network_perf_metrics_t));
19585
19586 ui32LBA =
19588 retval =
19590 p_buffer, dataLen, ui32LBA);
19591 if ((int32_t)retval != NI_RETCODE_SUCCESS)
19592 {
19593 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
19595 LRETURN;
19596 }
19597 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
19598 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
19599
19600 *p_metrics = *((ni_network_perf_metrics_t *)p_buffer);
19601 } else
19602 {
19603 p_metrics->total_cycles = (uint32_t)(-1);
19604 p_metrics->total_idle_cycles = (uint32_t)(-1);
19605 }
19606END:
19607
19608 ni_aligned_free(p_buffer);
19609 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
19610
19611 return retval;
19612}
19613
19614/*!*****************************************************************************
19615 * \brief Send namespace num / Opmode and SRIOv index/value to the device with
19616 * specified logic block address.
19617 *
19618 * \param[in] device_handle Device handle obtained by calling ni_device_open
19619 * \param[in] Key Represents either namespace num or opmode
19620 * \param[in] Value Represents either SRIOv index or opmode value
19621 *
19622 * \return On success
19623 * NI_RETCODE_SUCCESS
19624 * On failure
19625 * NI_RETCODE_ERROR_MEM_ALOC
19626 * NI_RETCODE_ERROR_NVME_CMD_FAILED
19627 ******************************************************************************/
19628ni_retcode_t ni_device_config_ns_qos(ni_device_handle_t device_handle,
19629 uint32_t key,
19630 uint32_t value)
19631{
19632 char buf[NI_DATA_BUFFER_LEN] = {'\0'};
19633 uint32_t *u32_buf = (uint32_t *)buf;
19634 u32_buf[0] = key;
19635 u32_buf[1] = value;
19636 // event handle could be ignored
19637 return ni_nvme_send_write_cmd(device_handle, NI_INVALID_EVENT_HANDLE,
19638 (void *)buf, NI_DATA_BUFFER_LEN,
19640}
19641
19643{
19644 char *CoreName;
19645 switch (eCoreType)
19646 {
19647 case ALL_CORE:
19648 CoreName = (char *)"all";
19649 break;
19650 case NVME_CORE:
19651 CoreName = (char *)"np";
19652 break;
19653 case EP_CORE:
19654 CoreName = (char *)"ep";
19655 break;
19656 case DP_CORE:
19657 CoreName = (char *)"dp";
19658 break;
19659 case TP_CORE:
19660 CoreName = (char *)"tp";
19661 break;
19662 case FP_CORE:
19663 CoreName = (char *)"fp";
19664 break;
19665 case FL_CORE:
19666 CoreName = (char *)"fl";
19667 break;
19668 default:
19669 CoreName = (char *)"Not Found";
19670 break;
19671 }
19672 return CoreName;
19673}
19674
19676{
19677 uint32_t lba;
19678 switch (eCoreType)
19679 {
19680 case NVME_CORE:
19682 break;
19683 case EP_CORE:
19684 lba = EP_LOG_OFFSET_IN_4K;
19685 break;
19686 case DP_CORE:
19687 lba = DP_LOG_OFFSET_IN_4K;
19688 break;
19689 case TP_CORE:
19690 lba = TP_LOG_OFFSET_IN_4K;
19691 break;
19692 case FP_CORE:
19693 lba = FP_LOG_OFFSET_IN_4K;
19694 break;
19695 case FL_CORE:
19696 lba = FL_LOG_OFFSET_IN_4K;
19697 break;
19698 default:
19699 ni_log(NI_LOG_ERROR, "%s:() Invalid core ID:%u\n", __func__, eCoreType);
19700 lba = 0;
19701 break;
19702 }
19703
19704 return lba;
19705}
19706
19707static int ni_write_fl_log_decoded_file(void *p_data, uint32_t buf_len, FILE *p_file)
19708{
19709 uint32_t fllen;
19710 uint32_t flsign;
19711 uint32_t log_lines;
19712 uint64_t payload_u;
19713 size_t payload_len;
19714 size_t max_payload;
19715 const uint8_t *in;
19716 uint8_t *out;
19717 size_t i, j;
19718
19719 if (buf_len < 4 || !p_data || !p_file)
19720 return -1;
19721
19722 memcpy(&flsign, p_data, sizeof(flsign));
19723 if (flsign != FL_SIGNATURE)
19724 {
19725 return -4;
19726 }
19727 memcpy(&fllen, (const uint8_t *)p_data + 4, sizeof(fllen));
19728 log_lines = fllen & 0xFFFFFFU;
19729 payload_u = (uint64_t)log_lines * 128ULL;
19730 max_payload = (size_t)buf_len - 4;
19731 payload_len = (payload_u > max_payload) ? max_payload : (size_t)payload_u;
19732
19733 in = (const uint8_t *)p_data + 8;
19734 out = (uint8_t *)malloc(payload_len ? payload_len : 1);
19735 if (!out)
19736 return -2;
19737
19738 for (i = 0, j = 0; i < payload_len; i++)
19739 if (in[i] != 0)
19740 out[j++] = in[i];
19741
19742 if (j > 0 && fwrite(out, 1, j, p_file) != j) {
19743 free(out);
19744 return -3;
19745 }
19746 free(out);
19747 return 0;
19748}
19749
19750ni_retcode_t ni_dump_log_single_core(ni_session_context_t *p_ctx, void* p_data, uint32_t core_id, bool gen_log_file)
19751{
19752 int32_t rc;
19753 uint32_t lba = 0;
19754 uint32_t data_len = CPU_LOG_BUFFER_SIZE;
19755 char *core_name = NULL;
19756 FILE *p_file = NULL;
19758
19759 if (!p_ctx || !p_data)
19760 {
19761 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR invalid pointer p_ctx %p p_data %p\n",
19762 __func__, __LINE__, p_ctx, p_data);
19764 }
19765
19766 if (core_id == FL_CORE)
19767 {
19769 memset(p_data, 0, CPU_FL_LOG_BUFFER_SIZE * CPU_FL_LOG_BUFFER_LEN);
19770 }
19771 else
19772 {
19773 memset(p_data, 0, CPU_LOG_BUFFER_SIZE);
19774 }
19775 *(uint8_t *)p_data = 0x55;
19776
19777 lba = ni_get_log_lba((ni_core_type_t)core_id);
19778 if (lba == 0)
19779 {
19780 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR core_id %u\n",
19781 __func__, __LINE__, core_id);
19783 }
19784
19785 core_name = ni_get_core_name((ni_core_type_t)core_id);
19786
19787 rc = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_data, data_len, lba);
19788
19789 if (rc != NI_RETCODE_SUCCESS)
19790 {
19791 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR %d: nvme read %s core failed\n",
19792 __func__, __LINE__, rc, core_name);
19793 }
19794 else if (gen_log_file)
19795 {
19796 //generate log file e.g. raw_dp_slot_0_0000.bin
19797 char filename[32] = "raw_";
19798 ni_strcat(filename, 32, core_name);
19799 ni_strcat(filename, 32, "_slot_");
19800#ifdef __linux__
19801 bool pcie_id_name = false;
19802 char devFilePath[1024] = {0};
19803 char devFDPath[1024] = {0};
19804 char pcie[64] = {0};
19805 char domain[5] = {0}, slot[3] = {0}, dev[3] = {0}, func[2] = {0};
19806 //p_ctx->blk_dev_name might be empty so look up the file name
19807 snprintf(devFDPath, sizeof(devFDPath), "/proc/self/fd/%d", p_ctx->blk_io_handle);
19808 ssize_t len = readlink(devFDPath, devFilePath, sizeof(devFilePath)-1);
19809 if (len != -1) {
19810 devFilePath[len] = '\0';
19811 }
19812 if (strstr(devFilePath, "/dev/nvme") != NULL)
19813 {
19814 get_dev_pcie_addr(devFilePath, pcie, domain, slot, dev, func);
19815 if (strlen(pcie) > 0 && strlen(slot) > 0 && strlen(domain) > 0)
19816 {
19817 ni_strcat(filename, 32, slot);
19818 ni_strcat(filename, 32, "_");
19819 ni_strcat(filename, 32, domain);
19820 pcie_id_name = true;
19821 }
19822 }
19823 if (!pcie_id_name)
19824 {
19825 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: For dev %d can't look up PCI domain and slot info. Defaulting to slot=hw_id and domain=0000\n",
19826 __func__, __LINE__, p_ctx->blk_io_handle);
19827 char num[4] = {0};
19828 snprintf(num, 4, "%d", p_ctx->hw_id);
19829 ni_strcat(filename, 32, num);
19830 ni_strcat(filename, 32, "_0000");
19831 }
19832 ni_strcat(filename, 32, ".bin");
19833 ni_log2(p_ctx, NI_LOG_INFO, "For dev %d %s core %s creating file %s\n",
19834 p_ctx->blk_io_handle, devFilePath, core_name, filename);
19835#else
19836 char num[4] = {0};
19837 snprintf(num, 4, "%02x", p_ctx->hw_id);
19838 ni_strcat(filename, 32, num);
19839 ni_strcat(filename, 32, "_0000");
19840 ni_strcat(filename, 32, ".bin");
19841 ni_log2(p_ctx, NI_LOG_INFO, "For dev %d core %s creating file %s\n",
19842 p_ctx->blk_io_handle, core_name, filename);
19843#endif
19844 ni_fopen(&p_file, filename, "wb");
19845
19846 if (p_file)
19847 {
19848 if (core_id == FL_CORE)
19849 {
19850 int wrc = ni_write_fl_log_decoded_file(p_data, data_len, p_file);
19851 if (wrc == -2)
19852 {
19853 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: FL log decode: malloc failed\n",
19854 __func__, __LINE__);
19855 retval = NI_RETCODE_FAILURE;
19856 }
19857 else if (wrc == -3)
19858 {
19859 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: FL log decode: fwrite failed\n",
19860 __func__, __LINE__);
19861 retval = NI_RETCODE_FAILURE;
19862 }
19863 else if (wrc == -1)
19864 {
19865 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: FL log decode: invalid buffer\n",
19866 __func__, __LINE__);
19867 retval = NI_RETCODE_FAILURE;
19868 }
19869 else if (wrc == -4)
19870 {
19871 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: FL log decode: invalid signature\n",
19872 __func__, __LINE__);
19873 retval = NI_RETCODE_FAILURE;
19874 }
19875
19876 }
19877 else if (fwrite((uint8_t *)p_data ,
19878 data_len, 1, p_file) != 1)
19879 {
19880 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: Error: writing data %u bytes error!\n",
19881 __func__, __LINE__, data_len);
19882 ni_log2(p_ctx, NI_LOG_ERROR, "Error: ferror rc = %d\n", ferror(p_file));
19883 retval = NI_RETCODE_FAILURE;
19884 }
19885 if (fflush(p_file))
19886 {
19887 ni_log2(p_ctx, NI_LOG_ERROR, "Error: writing data frame flush failed! errno %d\n",
19888 ferror(p_file));
19889 retval = NI_RETCODE_FAILURE;
19890 }
19891 fclose(p_file);
19892 }
19893 else
19894 {
19895 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: Error: cannot open %s\n",
19896 __func__, __LINE__, filename);
19897 retval = NI_RETCODE_FAILURE;
19898 }
19899 }
19900
19901 return retval;
19902}
19903
19904ni_retcode_t ni_dump_log_all_cores(ni_session_context_t *p_ctx, void* p_data, bool gen_log_file)
19905{
19906 int i = 1;
19907 int max_cores = 0;
19908
19909 if (!p_ctx || !p_data)
19910 {
19911 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR invalid pointer p_ctx %p p_data %p\n",
19912 __func__, __LINE__, p_ctx, p_data);
19914 }
19915
19917 "6t1") < 0)
19918 {
19919 max_cores = FP_CORE;
19920 }
19921 else
19922 {
19923 max_cores = FL_CORE;
19924 }
19925 for (i = NVME_CORE; i<= max_cores; i++)
19926 {
19927 ni_dump_log_single_core(p_ctx, p_data, i, gen_log_file);
19928 p_data = (void*)((uint8_t *)p_data + CPU_LOG_BUFFER_SIZE);
19929 }
19930
19931 return NI_RETCODE_SUCCESS;
19932}
19933
19934/*!*****************************************************************************
19935 * \brief Generates and writes a nvme command with sgl list
19936 *
19937 * \param[in] p_ctx Pointer to source card session
19938 * \param[in] pSrcFrame Pointer to source P2P frame
19939 * \param[in] dmaAddrs Destination DMA address on target device
19940 *
19941 * \return on success
19942 * NI_RETCODE_SUCCESS
19943 * on failure
19944 * NI_RETCODE_INVALID_PARAM
19945 * NI_RETCODE_ERROR_INVALID_SESSION
19946 * NI_RETCODE_ERROR_MEM_ALOC
19947 * NI_RETCODE_ERROR_NVME_CMD_FAILED
19948*******************************************************************************/
19950 ni_frame_t *pSrcFrame,
19951 const ni_p2p_sgl_t *dmaAddrs)
19952
19953{
19954 void *p_buffer = NULL;
19955 ni_retcode_t retval;
19956 uint32_t ui32LBA = 0;
19957 niFrameSurface1_t *pSurface;
19958 uint8_t *p_data;
19959 uint16_t ui16Direction = NI_P2P_SEND;
19960 uint32_t i;
19961
19962 if (dmaAddrs->ui32NumEntries > NI_MAX_P2P_SGL_ENTRIES)
19963 {
19964 ni_log2(p_ctx, NI_LOG_ERROR, "Too many SGL entries\n");
19965 retval = NI_RETCODE_INVALID_PARAM;
19966 LRETURN;
19967 }
19968
19969 /* allocate memory aligned buffer */
19970 retval = ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN);
19971 if (retval != 0)
19972 {
19974 LRETURN;
19975 }
19976
19977 pSurface = (niFrameSurface1_t *) pSrcFrame->p_data[3];
19978
19979 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
19980
19981 p_data = (uint8_t *) p_buffer;
19982
19983 /* Add payload */
19984 memcpy(p_data, &dmaAddrs->ui64DMAAddr[0], 8); // dummy data, not used
19985 memcpy(p_data + 8, &dmaAddrs->ui32DMALen[0], 4); // dummy data, not used
19986 memcpy(p_data + 12, &pSurface->ui16FrameIdx, 2); // dummy data, not used
19987 memcpy(p_data + 14, MAGIC_P2P_VALUE, 4);
19988 memcpy(p_data + 18, &ui16Direction, 2);
19989
19990 /* if any SGL entry exceeds the DMA engine max transfer size (>16MB or >24-bit),
19991 * then split the entry into two or more entries that are <=16MB */
19992 {
19993 uint32_t ui32NeedsSplit = 0;
19994 uint32_t ui32EntryIdx = 0;
19995
19996 for (ui32EntryIdx = 0; ui32EntryIdx < dmaAddrs->ui32NumEntries; ui32EntryIdx++)
19997 {
19998 if (dmaAddrs->ui32DMALen[ui32EntryIdx] > NI_DMA_SGL_MAX_XFER_SIZE)
19999 {
20000 ui32NeedsSplit = 1;
20001 break;
20002 }
20003 }
20004
20005 if (ui32NeedsSplit)
20006 {
20007 ni_p2p_sgl_t sSplitSgl;
20008 uint32_t ui32SglIdx = 0;
20009 uint32_t ui32OrigEntries = dmaAddrs->ui32NumEntries;
20010
20011 memset(&sSplitSgl, 0, sizeof(sSplitSgl));
20012 for (ui32EntryIdx = 0;
20013 ui32EntryIdx < ui32OrigEntries && ui32SglIdx < NI_MAX_P2P_SGL_ENTRY;
20014 ui32EntryIdx++)
20015 {
20016 uint64_t ui64BaseAddr = dmaAddrs->ui64DMAAddr[ui32EntryIdx];
20017 uint32_t ui32RemainingData = dmaAddrs->ui32DMALen[ui32EntryIdx];
20018 uint32_t ui32Offset = 0;
20019
20020 while (ui32RemainingData > 0 && ui32SglIdx < NI_MAX_P2P_SGL_ENTRY)
20021 {
20022 uint32_t ui32Seg = (ui32RemainingData > NI_DMA_SGL_MAX_XFER_SIZE)
20023 ? NI_DMA_SGL_MAX_XFER_SIZE : ui32RemainingData;
20024 sSplitSgl.ui64DMAAddr[ui32SglIdx] = ui64BaseAddr + ui32Offset;
20025 sSplitSgl.ui32DMALen[ui32SglIdx] = ui32Seg;
20026 ui32Offset += ui32Seg;
20027 ui32RemainingData -= ui32Seg;
20028 ui32SglIdx++;
20029 }
20030
20031 if (ui32RemainingData > 0)
20032 {
20033 ni_log2(p_ctx, NI_LOG_ERROR,
20034 "%s: SGL overflow: table full (%u slots) at entry"
20035 " %u/%u, %u bytes unprocessed\n",
20036 __func__, NI_MAX_P2P_SGL_ENTRY,
20037 ui32EntryIdx, ui32OrigEntries, ui32RemainingData);
20038 retval = NI_RETCODE_INVALID_PARAM;
20039 LRETURN;
20040 }
20041 }
20042
20043 if (ui32EntryIdx < ui32OrigEntries)
20044 {
20045 ni_log2(p_ctx, NI_LOG_ERROR,
20046 "%s: SGL overflow: table full (%u slots), "
20047 "%u/%u entries not processed\n",
20048 __func__, NI_MAX_P2P_SGL_ENTRY,
20049 ui32OrigEntries - ui32EntryIdx, ui32OrigEntries);
20050 retval = NI_RETCODE_INVALID_PARAM;
20051 LRETURN;
20052 }
20053
20054 sSplitSgl.ui32NumEntries = ui32SglIdx;
20055
20056 ni_log2(p_ctx, NI_LOG_INFO,
20057 "%s: SGL split: %u original entr%s -> %u chunks "
20058 "(max 0x%X bytes/chunk)\n", __func__,
20059 ui32OrigEntries, ui32OrigEntries == 1 ? "y" : "ies",
20060 ui32SglIdx, NI_DMA_SGL_MAX_XFER_SIZE);
20061
20062 memcpy(p_data + 20, &sSplitSgl.ui32NumEntries, 4);
20063 for (i = 0; i < sSplitSgl.ui32NumEntries; i++)
20064 {
20065 memcpy(&p_data[24] + (i * 8), &sSplitSgl.ui64DMAAddr[i], 8);
20066 }
20067 for (i = 0; i < sSplitSgl.ui32NumEntries; i++)
20068 {
20069 memcpy(&p_data[24] + (sSplitSgl.ui32NumEntries * 8) + (i * 4),
20070 &sSplitSgl.ui32DMALen[i], 4);
20071 }
20072 }
20073 else
20074 {
20075 memcpy(p_data + 20, &dmaAddrs->ui32NumEntries, 4);
20076 for (i = 0; i < dmaAddrs->ui32NumEntries; i++)
20077 {
20078 memcpy(&p_data[24] + (i * 8), &dmaAddrs->ui64DMAAddr[i], 8);
20079 }
20080 for (i = 0; i < dmaAddrs->ui32NumEntries; i++)
20081 {
20082 memcpy(&p_data[24] + (dmaAddrs->ui32NumEntries * 8) + (i * 4),
20083 &dmaAddrs->ui32DMALen[i], 4);
20084 }
20085 }
20086 }
20087
20089
20090 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, NI_INVALID_DEVICE_HANDLE,
20091 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
20092
20093 if (retval < 0)
20094 {
20095 ni_log2(p_ctx, NI_LOG_ERROR, "%s: NVME command failed %d\n", __func__, retval);
20096 ni_aligned_free(p_buffer);
20098 LRETURN;
20099 }
20100
20101END:
20102 if (p_buffer != NULL)
20103 ni_aligned_free(p_buffer);
20104 return retval;
20105}
20106
20108 ni_session_context_t *p_ctx,
20109 const ni_p2p_sgl_t *dmaAddrs,
20110 ni_frame_t *pDstFrame)
20111{
20112 void *p_buffer = NULL;
20113 ni_retcode_t retval;
20114 uint32_t ui32LBA = 0;
20115 niFrameSurface1_t *pSurface;
20116 uint8_t *p_data;
20117 uint16_t ui16Direction = NI_P2P_RECV;
20118 uint32_t ui32Dummy = 0;
20119 uint32_t i;
20120
20121 if (dmaAddrs->ui32NumEntries > NI_MAX_P2P_SGL_ENTRIES)
20122 {
20123 ni_log2(p_ctx, NI_LOG_ERROR, "Too many SGL entries\n");
20124 retval = NI_RETCODE_INVALID_PARAM;
20125 LRETURN;
20126 }
20127
20128 /* allocate memory aligned buffer */
20129 retval = ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN);
20130 if (retval != 0)
20131 {
20133 LRETURN;
20134 }
20135
20136 pSurface = (niFrameSurface1_t *) pDstFrame->p_data[3];
20137
20138 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
20139
20140 p_data = (uint8_t *) p_buffer;
20141
20142 /* Add payload */
20143 memcpy(p_data, &dmaAddrs->ui64DMAAddr[0], 8); // dummy data, not used for p2p read
20144 memcpy(p_data + 8, &ui32Dummy, 4); // dummy data, not used for p2p read
20145 memcpy(p_data + 12, &pSurface->ui16FrameIdx, 2); // dummy data, not used for p2p read
20146 memcpy(p_data + 14, MAGIC_P2P_VALUE, 4);
20147 memcpy(p_data + 18, &ui16Direction, 2);
20148 memcpy(p_data + 20, &dmaAddrs->ui32NumEntries, 4);
20149
20150 for (i = 0; i < dmaAddrs->ui32NumEntries; i++)
20151 {
20152 memcpy(&p_data[24] + (i*8), &dmaAddrs->ui64DMAAddr[i], 8);
20153 }
20154
20155 for (i = 0; i < dmaAddrs->ui32NumEntries; i++)
20156 {
20157 memcpy(&p_data[24] + (dmaAddrs->ui32NumEntries * 8) + (i * 4), &dmaAddrs->ui32DMALen[i], 4);
20158 }
20159
20161
20162 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
20163 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
20164
20165 if (retval < 0)
20166 {
20167 ni_log2(p_ctx, NI_LOG_ERROR, "%s: NVME command failed\n", __func__);
20168 ni_aligned_free(p_buffer);
20170 LRETURN;
20171 }
20172
20173END:
20174 if (p_buffer != NULL)
20175 ni_aligned_free(p_buffer);
20176 return retval;
20177}
20178
20179int lower_pixel_rate(const ni_load_query_t *pQuery, uint32_t ui32CurrentLowest)
20180{
20181 return (pQuery->total_pixel_load < ui32CurrentLowest) ? 1 : 0;
20182}
20183
20184/*!******************************************************************************
20185 * \brief set cpu affinity based on numa node
20186 *
20187 * \param[in] p_ctx pointer to session context
20188 *
20189 * \return NI_RETCODE_SUCCESS
20190 * NI_RETCODE_ERROR_MEM_ALOC
20191 *******************************************************************************/
20193{
20194#if defined(__linux__) && defined(XCODER_ENABLE_CPU_AFFINITY)
20195 int numa_node;
20196 if (numa_available() == -1) {
20197 ni_log2(p_ctx, NI_LOG_INFO, "Warning: %s() NUMA not available.\n",
20198 __func__);
20199 }
20200 else
20201 {
20202 numa_node = ni_rsrc_get_numa_node(p_ctx->blk_xcoder_name);
20203
20204 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): device name %s, numa node %d\n",
20205 __func__, p_ctx->blk_xcoder_name, numa_node);
20206
20207 if (numa_node < 0)
20208 {
20209 ni_log2(p_ctx, NI_LOG_INFO, "Warning: %s() %s NUMA not available.\n",
20210 __func__, p_ctx->blk_dev_name);
20211 }
20212 else
20213 {
20214#if defined(LIBNUMA_API_VERSION) && (LIBNUMA_API_VERSION == 2)
20215 struct bitmask *node_mask = numa_allocate_nodemask();
20216 if (!node_mask)
20217 {
20218 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() numa_allocate_cpumask failed.\n",
20219 __func__);
20221 }
20222 numa_bitmask_setbit(node_mask, numa_node);
20223 numa_bind(node_mask);
20224 numa_bitmask_free(node_mask);
20225#else
20226 nodemask_t node_mask;
20227 nodemask_zero(&node_mask);
20228 nodemask_set(&node_mask, numa_node);
20229 numa_bind(&node_mask);
20230#endif
20231 }
20232 }
20233#endif
20234 return NI_RETCODE_SUCCESS;
20235}
20236
20237#ifdef PRINT_FW_LOGS
20243static inline bool is_log_start_marker(const uint8_t* data) {
20244 return (data[0] == FW_LOG_START_DELIMITER_0 && data[1] == FW_LOG_START_DELIMITER_1);
20245}
20246
20252static inline bool is_log_end_marker(const uint8_t* data) {
20253 return (data[0] == FW_LOG_END_DELIMITER_0 && data[1] == FW_LOG_END_DELIMITER_1);
20254}
20255
20261static inline uint64_t extract_timestamp(uint8_t* timestamp_bytes) {
20262 uint64_t timestamp = 0;
20263 // Little-endian extraction
20264 for (int i = 0; i < 8; i++) {
20265 timestamp |= ((uint64_t)timestamp_bytes[i] << (i * 8));
20266 }
20267 return timestamp;
20268}
20269
20277static void ni_find_latest_complete_log(const uint8_t* data, size_t data_size,
20278 log_entry_info_t* latest_entry) {
20279 int index = 0;
20280 uint64_t timestamp = 0, max_timestamp = 0;
20281 log_entry_header_t* header;
20282 uint64_t data_start;
20283 bool found_end;
20284 const uint8_t* end_ptr;
20285
20286 // Initialize latest entry with default values
20287 latest_entry->timestamp = 0;
20288 latest_entry->wrap_around = false;
20289 latest_entry->start_ptr = NULL;
20290 latest_entry->end_ptr = NULL;
20291
20292 while (index < data_size - sizeof(log_entry_trailer_t)) {
20293 // Search for start marker (0x5AA5)
20294 if (!is_log_start_marker(data + index)) {
20295 index++;
20296 continue;
20297 }
20298
20299 // Verify there's enough space for a complete log header
20300 if (index + sizeof(log_entry_header_t) > data_size) {
20301 break;
20302 }
20303
20304 header = (log_entry_header_t*)(data + index);
20305 timestamp = extract_timestamp(header->timestamp);
20306
20307 // Basic timestamp validation (skip invalid/zero timestamps)
20308 if (timestamp == 0) {
20309 index++;
20310 continue;
20311 }
20312
20313 data_start = index + sizeof(log_entry_header_t);
20314 found_end = false;
20315 end_ptr = NULL;
20316
20317 // Search for corresponding end marker (0xA55A)
20318 for (uint64_t j = data_start; j < data_size - sizeof(log_entry_trailer_t); j++) {
20319 if (is_log_end_marker(data + j)) {
20320 found_end = true;
20321 end_ptr = data + j + sizeof(log_entry_trailer_t); // Point after end marker
20322 break;
20323 }
20324 }
20325
20326 if (found_end && end_ptr != NULL) {
20327 // Track the entry with maximum timestamp (latest log)
20328 if (timestamp > max_timestamp) {
20329 max_timestamp = timestamp;
20330 latest_entry->start_ptr = data + index;
20331 latest_entry->end_ptr = end_ptr;
20332 latest_entry->timestamp = timestamp;
20333 latest_entry->wrap_around = false;
20334 }
20335 else
20336 {
20337 latest_entry->wrap_around = true;
20338 }
20339
20340 // Continue search from after the end marker
20341 index = end_ptr - data;
20342 } else {
20343 // No end marker found, continue searching
20344 index++;
20345 }
20346 }
20347
20348 return ;
20349}
20350
20360static void ni_extract_64k_from_end_marker(const uint8_t* data, size_t data_size,
20361 const uint8_t* end_marker_ptr,
20362 uint8_t* output, bool wrap_around) {
20363 uint64_t end_marker_offset = end_marker_ptr - data;
20364 uint64_t extract_start;
20365
20366 ni_log(NI_LOG_ERROR,"End marker position: %zu\n", end_marker_offset);
20367
20368 if (end_marker_offset >= PRINT_FW_LOG_SIZE) {
20369 // Enough data available before end marker
20370 extract_start = end_marker_offset - PRINT_FW_LOG_SIZE;
20371 memcpy(output, data + extract_start, PRINT_FW_LOG_SIZE);
20372 } else if (wrap_around) {
20373 // Wrap around buffer: end + beginning
20374 uint64_t first_part_size = PRINT_FW_LOG_SIZE - end_marker_offset;
20375 uint64_t second_part_size = end_marker_offset;
20376
20377 memcpy(output, data + data_size - first_part_size, first_part_size);
20378
20379 if (second_part_size > 0) {
20380 memcpy(output + first_part_size, data, second_part_size);
20381 }
20382 } else {
20383 // Not enough usefull data, extract from beginning
20384 memcpy(output, data, PRINT_FW_LOG_SIZE);
20385 }
20386
20387 return ;
20388}
20389
20396ni_retcode_t ni_extract_64k_from_latest_log_end(const uint8_t* data, uint8_t* output) {
20398 log_entry_info_t entries;
20399 if (data == NULL || output == NULL) {
20401 }
20402
20403 // Find all complete log entries
20404 ni_find_latest_complete_log(data, CPU_LOG_BUFFER_SIZE, &entries);
20405
20406 if (entries.timestamp == 0) {
20407 ni_log(NI_LOG_ERROR, "Get fw log timestamp == 0,"
20408 " it is not expected, So will print the first 64K fw logs\n");
20409 memcpy(output, data, PRINT_FW_LOG_SIZE);
20410 return ret;
20411 }
20412
20413 // Extract 64KB data
20414 ni_extract_64k_from_end_marker(
20415 data, CPU_LOG_BUFFER_SIZE, entries.end_ptr, output, entries.wrap_around);
20416
20417 return ret;
20418}
20419
20427ni_retcode_t ni_device_print_firmware_logs(ni_session_context_t *p_ctx,
20428 const uint8_t *p_data, uint32_t core_id) {
20430 uint8_t *output = NULL;
20431
20432 if (!p_ctx || !p_data) {
20433 ni_log2(p_ctx, NI_LOG_ERROR, "%s:%d: ERROR invalid pointer p_ctx %p\n",
20434 __func__, __LINE__, p_ctx);
20436 }
20437
20438 ni_log(NI_LOG_ERROR, "%s start print %s log, session id %lu\n",
20439 __func__, ni_get_core_name((ni_core_type_t)core_id), p_ctx->session_id);
20440
20441 // Allocate output buffer
20442 output = malloc(PRINT_FW_LOG_SIZE);
20443 if (output == NULL) {
20444 ni_log(NI_LOG_ERROR, "Failed to allocate output buffer\n");
20445 return NI_RETCODE_FAILURE;
20446 }
20447
20448 // Extract 64KB data from latest log
20449 ret = ni_extract_64k_from_latest_log_end(p_data, output);
20450
20451 // Print extracted data in 256-byte chunks with delimiters
20452 if (ret == NI_RETCODE_SUCCESS) {
20453 uint8_t print_buffer[260]; // 256 + 4 delimiter bytes
20454 int chunks = PRINT_FW_LOG_SIZE / 256;
20455
20456 for (int i = 0; i < chunks; i++) {
20457 uint8_t* ptr = print_buffer;
20458
20459 // Start delimiter
20460 *ptr++ = 0x5B;
20461 *ptr++ = 0xB5;
20462
20463 // Copy data chunk
20464 memcpy(ptr, output + (i * 256), 256);
20465 ptr += 256;
20466
20467 // End delimiter
20468 *ptr++ = 0xB5;
20469 *ptr++ = 0x5B;
20470
20471 // Print hex representation
20472 for (int j = 0; j < sizeof(print_buffer); j++) {
20473 ni_log(NI_LOG_ERROR, "%02X", print_buffer[j]);
20474 }
20475 ni_log(NI_LOG_ERROR, "\n");
20476 }
20477 } else {
20478 ni_log(NI_LOG_ERROR, "%s failed ret %d\n", __func__, ret);
20479 }
20480 // Cleanup
20481 free(output);
20482 return ret;
20483}
20484
20495ni_retcode_t ni_device_get_and_print_firmware_logs(ni_session_context_t *p_ctx)
20496{
20498 bool gen_log_file = false;
20499 void *p_log_buffer = NULL;
20500 int i;
20501 int max_cores;
20502 if(!p_ctx)
20503 {
20504 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR invalid pointer p_ctx %p\n",
20505 __func__, __LINE__, p_ctx);
20507 }
20508 ni_log(NI_LOG_ERROR, "%s enter, session_id %lu, blk_dev_name %s, hw_id %d\n",
20509 __func__, p_ctx->session_id, p_ctx->blk_dev_name, p_ctx->hw_id);
20510
20511 if (ni_posix_memalign(&p_log_buffer, sysconf(_SC_PAGESIZE), CPU_LOG_BUFFER_SIZE))
20512 {
20513 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate log buffer\n",
20514 NI_ERRNO, __func__);
20516 }
20517
20519 "6t1") < 0)
20520 {
20521 max_cores = FP_CORE;
20522 }
20523 else
20524 {
20525 max_cores = FL_CORE;
20526 }
20527
20528 for (i = NVME_CORE; i<= max_cores; i++)
20529 {
20530 memset(p_log_buffer, 0, CPU_LOG_BUFFER_SIZE);
20531 retval = ni_dump_log_single_core(p_ctx, p_log_buffer, i, gen_log_file);
20532 if (retval != NI_RETCODE_SUCCESS)
20533 {
20534 ni_log2(p_ctx, NI_LOG_ERROR, "ni_dump_log_single_core failed\n");
20535 LRETURN;
20536 }
20537
20538 retval = ni_device_print_firmware_logs(p_ctx, p_log_buffer, i);
20539 if (retval != NI_RETCODE_SUCCESS)
20540 {
20541 ni_log2(p_ctx, NI_LOG_ERROR, "ni_device_print_firmware_logs failed\n");
20542 LRETURN;
20543 }
20544 }
20545
20546END:
20547
20548 ni_aligned_free(p_log_buffer);
20549 return retval;
20550}
20551#endif
#define NI_XCODER_REVISION_API_MAJOR_VER_IDX
Definition ni_defs.h:99
#define NI_MAX_NUM_SW_FRAME_DATA_POINTERS
Definition ni_defs.h:246
#define END
Definition ni_defs.h:338
#define NI_XCODER_REVISION
Definition ni_defs.h:98
#define NI_GET_MIN_HWDESC_P2P_BUF_ID(x)
Definition ni_defs.h:282
@ nvme_cmd_xcoder_write
Definition ni_defs.h:586
@ nvme_cmd_xcoder_read
Definition ni_defs.h:587
#define NI_FIFO_SZ
Definition ni_defs.h:305
#define NI_GET_MAX_HWDESC_FRAME_INDEX(x)
Definition ni_defs.h:292
@ NI_XCODER_QUADRA
Definition ni_defs.h:347
struct _ni_session_statistic_t ni_session_statistic_t
#define CPU_FL_LOG_BUFFER_LEN
Definition ni_defs.h:375
#define NI_MAX_CONTEXTS_PER_HW_INSTANCE
Definition ni_defs.h:248
#define NI_MAX_DEVICES_PER_HW_INSTANCE
Definition ni_defs.h:251
#define NI_MAX_NUM_OF_DECODER_OUTPUTS
Definition ni_defs.h:255
ni_device_type_t
Definition ni_defs.h:356
@ NI_DEVICE_TYPE_SCALER
Definition ni_defs.h:362
@ NI_DEVICE_TYPE_AI
Definition ni_defs.h:363
@ NI_DEVICE_TYPE_DECODER
Definition ni_defs.h:360
@ NI_DEVICE_TYPE_UPLOAD
Definition ni_defs.h:367
@ NI_DEVICE_TYPE_ENCODER
Definition ni_defs.h:361
@ NI_DEVICE_TYPE_XCODER_MAX
Definition ni_defs.h:364
#define NI_ERRNO
Definition ni_defs.h:229
ni_core_type_t
Definition ni_defs.h:382
@ FP_CORE
Definition ni_defs.h:388
@ ALL_CORE
Definition ni_defs.h:383
@ EP_CORE
Definition ni_defs.h:385
@ TP_CORE
Definition ni_defs.h:387
@ NVME_CORE
Definition ni_defs.h:384
@ DP_CORE
Definition ni_defs.h:386
@ FL_CORE
Definition ni_defs.h:389
#define CPU_LOG_BUFFER_SIZE
Definition ni_defs.h:373
#define NI_GET_MAX_HWDESC_P2P_BUF_ID(x)
Definition ni_defs.h:283
#define NI_MAX_PACKET_SZ
Definition ni_defs.h:239
#define CPU_FL_LOG_BUFFER_SIZE
Definition ni_defs.h:374
#define NETINT_PCI_VENDOR_ID
Definition ni_defs.h:129
#define ni_assert(expression)
Definition ni_defs.h:341
@ NI_SCALER_OPCODE_IPOVLY
Definition ni_defs.h:600
@ NI_SCALER_OPCODE_OVERLAY
Definition ni_defs.h:596
@ NI_SCALER_OPCODE_SCALE
Definition ni_defs.h:592
@ NI_SCALER_OPCODE_WATERMARK
Definition ni_defs.h:601
@ NI_SCALER_OPCODE_STACK
Definition ni_defs.h:597
@ NI_SCALER_OPCODE_ROTATE
Definition ni_defs.h:598
@ NI_SCALER_OPCODE_AI_ALIGN
Definition ni_defs.h:604
#define PRINT_FW_LOG_SIZE
Definition ni_defs.h:378
#define NI_MEM_PAGE_ALIGNMENT
Definition ni_defs.h:263
#define NI_FW_META_DATA_SZ
Definition ni_defs.h:320
#define QUADRA
Definition ni_defs.h:123
#define LRETURN
Definition ni_defs.h:337
ni_retcode_t
Definition ni_defs.h:445
@ NI_RETCODE_PARAM_ERROR_INTRA_PERIOD
Definition ni_defs.h:464
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_BIG
Definition ni_defs.h:517
@ NI_RETCODE_PARAM_ERROR_BRATE
Definition ni_defs.h:459
@ NI_RETCODE_PARAM_ERROR_HVS_QP_EN
Definition ni_defs.h:476
@ NI_RETCODE_FAILURE
Definition ni_defs.h:447
@ NI_RETCODE_PARAM_ERROR_VBV_BUFFER_SIZE
Definition ni_defs.h:463
@ NI_RETCODE_EAGAIN
Definition ni_defs.h:548
@ NI_RETCODE_PARAM_ERROR_CUSIZE_MODE_8X8_EN
Definition ni_defs.h:505
@ NI_RETCODE_PARAM_ERROR_CUSIZE_MODE_32X32_EN
Definition ni_defs.h:507
@ NI_RETCODE_PARAM_ERROR_RCENABLE
Definition ni_defs.h:495
@ NI_RETCODE_PARAM_ERROR_MX_DELTA_QP
Definition ni_defs.h:482
@ NI_RETCODE_PARAM_ERROR_LOOK_AHEAD_DEPTH
Definition ni_defs.h:536
@ NI_RETCODE_PARAM_ERROR_CONF_WIN_R
Definition ni_defs.h:490
@ NI_RETCODE_ERROR_INVALID_SESSION
Definition ni_defs.h:452
@ NI_RETCODE_PARAM_ERROR_CU_SIZE_MODE
Definition ni_defs.h:469
@ NI_RETCODE_PARAM_ERROR_CONF_WIN_BOT
Definition ni_defs.h:486
@ NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
Definition ni_defs.h:540
@ NI_RETCODE_PARAM_ERROR_MN_QP
Definition ni_defs.h:478
@ NI_RETCODE_NVME_SC_INVALID_PARAMETER
Definition ni_defs.h:563
@ NI_RETCODE_PARAM_ERROR_PIC_WIDTH
Definition ni_defs.h:499
@ NI_RETCODE_PARAM_ERROR_CONF_WIN_TOP
Definition ni_defs.h:484
@ NI_RETCODE_PARAM_ERROR_CONF_WIN_L
Definition ni_defs.h:488
@ NI_RETCODE_PARAM_ERROR_DECODING_REFRESH_TYPE
Definition ni_defs.h:503
@ NI_RETCODE_PARAM_ERROR_AREA_TOO_BIG
Definition ni_defs.h:521
@ NI_RETCODE_PARAM_ERROR_FRATE
Definition ni_defs.h:457
@ NI_RETCODE_NVME_SC_WRITE_BUFFER_FULL
Definition ni_defs.h:553
@ NI_RETCODE_NVME_SC_VPU_RECOVERY
Definition ni_defs.h:566
@ NI_RETCODE_SUCCESS
Definition ni_defs.h:446
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_SMALL
Definition ni_defs.h:519
@ NI_RETCODE_PARAM_WARN
Definition ni_defs.h:545
@ NI_RETCODE_ERROR_INVALID_HANDLE
Definition ni_defs.h:530
@ NI_RETCODE_PARAM_INVALID_VALUE
Definition ni_defs.h:456
@ NI_RETCODE_ERROR_RESOURCE_UNAVAILABLE
Definition ni_defs.h:453
@ NI_RETCODE_PARAM_ERROR_CU_LVL_RC_EN
Definition ni_defs.h:474
@ NI_RETCODE_PARAM_ERROR_INTRA_QP
Definition ni_defs.h:466
@ NI_RETCODE_PARAM_ERROR_MAXNUMMERGE
Definition ni_defs.h:496
@ NI_RETCODE_NVME_SC_RESOURCE_UNAVAILABLE
Definition ni_defs.h:555
@ NI_RETCODE_PARAM_ERROR_GOP_PRESET
Definition ni_defs.h:467
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_BIG
Definition ni_defs.h:513
@ NI_RETCODE_ERROR_NVME_CMD_FAILED
Definition ni_defs.h:451
@ NI_RETCODE_PARAM_ERROR_USR_RMD_ENC_PARAM
Definition ni_defs.h:492
@ NI_RETCODE_PARAM_ERROR_PIC_HEIGHT
Definition ni_defs.h:501
@ NI_RETCODE_NVME_SC_VPU_RSRC_INSUFFICIENT
Definition ni_defs.h:567
@ NI_RETCODE_ERROR_MEM_ALOC
Definition ni_defs.h:450
@ NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
Definition ni_defs.h:541
@ NI_RETCODE_PARAM_ERROR_OOR
Definition ni_defs.h:512
@ NI_RETCODE_PARAM_ERROR_CUSIZE_MODE_16X16_EN
Definition ni_defs.h:506
@ NI_RETCODE_ERROR_VPU_RECOVERY
Definition ni_defs.h:534
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_SMALL
Definition ni_defs.h:515
@ NI_RETCODE_PARAM_ERROR_CUSTOM_GOP
Definition ni_defs.h:497
@ NI_RETCODE_INVALID_PARAM
Definition ni_defs.h:448
@ NI_RETCODE_PARAM_ERROR_TOO_SMALL
Definition ni_defs.h:509
@ NI_RETCODE_PARAM_ERROR_MX_QP
Definition ni_defs.h:480
#define FL_SIGNATURE
Definition ni_defs.h:379
#define IS_XCODER_DEVICE_TYPE(t)
Definition ni_defs.h:429
#define NI_MAX_4K_FPS_QUADRA
Definition ni_defs.h:249
#define NI_MAX_P2P_SGL_ENTRY
Definition ni_defs.h:121
ni_retcode_t ni_frame_buffer_alloc_dl(ni_frame_t *p_frame, int video_width, int video_height, int pixel_format)
Allocate preliminary memory for the frame buffer based on provided parameters.
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...
void ni_device_session_context_free(ni_session_context_t *p_ctx)
Free previously allocated session context.
int ni_device_session_hwdl(ni_session_context_t *p_ctx, ni_session_data_io_t *p_data, niFrameSurface1_t *hwdesc)
Reads YUV data from hw descriptor stored location on device.
ni_retcode_t ni_frame_buffer_alloc(ni_frame_t *p_frame, int video_width, int video_height, int alignment, int metadata_flag, int factor, int hw_frame_count, int is_planar)
Allocate preliminary memory for the frame buffer based on provided parameters. Applicable to YUV420 P...
ni_retcode_t ni_device_capability_query2(ni_device_handle_t device_handle, ni_device_capability_t *p_cap, bool device_in_ctxt)
Query device and return device capability structure This function had replaced ni_device_capability_q...
ni_session_context_t * ni_device_session_context_alloc_init(void)
Allocate and initialize a new ni_session_context_t struct.
ni_retcode_t ni_query_vf_ns_id(ni_device_handle_t device_handle, ni_device_vf_ns_id_t *p_dev_ns_vf, uint8_t fw_rev[])
Query VF and NS id from device.
#define atoi(p_str)
ni_retcode_t ni_decoder_frame_buffer_alloc(ni_buf_pool_t *p_pool, ni_frame_t *p_frame, int alloc_mem, int video_width, int video_height, int alignment, int factor, int is_planar)
Allocate memory for decoder frame buffer based on provided parameters; the memory is retrieved from a...
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.
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,...
Public definitions for operating NETINT video processing devices for video processing.
#define NI_MIN_HEIGHT
@ SESSION_RUN_STATE_NORMAL
@ SESSION_RUN_STATE_SEQ_CHANGE_DRAINING
@ AV1_CODEC_PROFILE_MAIN
#define NI_PARAM_MAX_HEIGHT
#define AV_CODEC_DEFAULT_BITRATE
@ XCODER_TEST_RECONF_OFF
@ NI_POOL_TYPE_NONE
@ NI_POOL_TYPE_NORMAL
@ NI_POOL_TYPE_P2P
#define NI_NOPTS_VALUE
#define NI_CC_SEI_BYTE5
#define NI_MAX_ENCODER_QUERY_RETRIES
#define NI_MIN_WIDTH
#define NI_CC_SEI_TRAILER_LEN
#define NI_NUM_OF_PIXELS_1440P
@ NI_QUADRA_PREDICTED_FRAME
@ NI_QUADRA_BIDIR_PREDICTED_FRAME
@ NI_QUADRA_INTRA_FRAME
#define NI_AV1_INVALID_BUFFER_INDEX
#define NI_HDR10P_SEI_BYTE2
#define NI_CC_SEI_BYTE6
struct _niFrameSurface1 niFrameSurface1_t
@ NI_PIXEL_PLANAR_FORMAT_SEMIPLANAR
@ NI_PIXEL_PLANAR_MAX
@ NI_PIXEL_PLANAR_FORMAT_TILED4X4
@ NI_PIXEL_PLANAR_FORMAT_PLANAR
#define NI_ENC_REPEAT_HEADERS_ALL_I_FRAMES
struct _ni_network_layer_params_t ni_network_layer_params_t
#define NI_PARAM_AV1_MAX_HEIGHT
#define NI_SCALER_FLAG_PC
#define NI_MIN_RESOLUTION_HEIGHT_SCALER
#define NI_MAX_SEI_DATA
#define NI_MAX_RESOLUTION_RGBA_WIDTH
#define NI_CC_SEI_HDR_H264_LEN
#define NI_MAX_GOP_NUM
#define NI_HDR10P_SEI_BYTE0
#define NI_ENC_MIN_RESOLUTION_HEIGHT
struct _ni_instance_mgr_detail_status_v1 ni_instance_mgr_detail_status_v1_t
#define NI_CUSTOMIZE_ROI_QP_NUM
Max number of entries per line supported for the qp number.
#define GC620_RGBA8888
#define NI_MAX_FRAME_SIZE
@ NI_DEC_CROP_MODE_MANUAL
#define PRESET_DEFAULT_BITRATE
#define NI_PARAM_AV1_MAX_WIDTH
#define NI_EC_POLICY_LIMITED_ERROR
#define NI_MIN_RESOLUTION_WIDTH
#define NI_MAX_RESOLUTION_WIDTH
#define NI_MAX_SLICE_SIZE
@ NI_H265_USERDATA_FLAG_UNREGISTERED_PRE
@ NI_H265_USERDATA_FLAG_MASTERING_COLOR_VOL
@ NI_H265_USER_DATA_FLAG_CONTENT_LIGHT_LEVEL_INFO
@ NI_H265_USERDATA_FLAG_UNREGISTERED_SUF
#define NI_CC_SEI_BYTE2
#define NI_EC_ERR_THRESHOLD_DEFAULT
#define NI_ENC_MIN_RESOLUTION_WIDTH
struct _ni_network_perf_metrics ni_network_perf_metrics_t
#define NI_MIN_BITRATE
#define NI_HDR10P_SEI_HDR_H264_LEN
#define NI_MAX_BITRATE
@ H264_CODEC_PROFILE_EXTENDED
@ H264_CODEC_PROFILE_HIGH
@ H264_CODEC_PROFILE_BASELINE
@ H264_CODEC_PROFILE_MAIN
#define NI_CC_SEI_BYTE1
#define NI_PARAM_AV1_MAX_AREA
#define NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL
Max number of lines supported for qpoffset level.
#define NI_INVALID_SESSION_ID
@ HEVC_CODEC_PROFILE_MAIN10
@ HEVC_CODEC_PROFILE_MAIN
#define NI_AI_FLAG_IOVEC
#define NI_MAX_RESOLUTION_AREA
#define NI_HDR10P_SEI_BYTE1
#define NI_SCALER_FLAG_P2
@ VODEO_CODEC_ID_HEVC
@ VODEO_CODEC_ID_H264
@ VODEO_CODEC_ID_AV1
enum _ni_codec_format ni_codec_format_t
This is an enumeration for supported codec formats.
struct _ni_scaler_params_t ni_scaler_params_t
#define NI_MAX_RESOLUTION_RGBA_HEIGHT
#define NI_CC_SEI_BYTE4
#define MOTION_CONSTRAINED_QUALITY_MODE
#define NI_NUM_OF_PIXELS_1080P
@ NI_QUADRA_AV1_PROFILE_MAIN
#define NI_CC_SEI_BYTE7
#define NI_MIN_RESOLUTION_HEIGHT
@ NI_DDR_PRIORITY_NONE
@ NI_DDR_PRIORITY_RESET
#define NI_MAX_TX_RETRIES
#define NI_EC_POLICY_BEST_EFFORT_OUT_DC
#define NI_AI_FLAG_IO
#define NI_MIN_RESOLUTION_WIDTH_SCALER
#define NI_MAX_FRAMERATE
#define NI_MAX_SPATIAL_LAYERS
#define NI_HDR10P_SEI_HDR_HEVC_LEN
@ NI_CODEC_HW_UPLOAD
@ NI_CODEC_HW_NONE
@ NI_CODEC_HW_DOWNLOAD
@ NI_CODEC_HW_ENABLE
@ NI_CODEC_HW_PAYLOAD_OFFSET
#define NI_CC_SEI_BYTE0
@ NI_CODEC_FORMAT_H265
@ NI_CODEC_FORMAT_AV1
@ NI_CODEC_FORMAT_H264
@ NI_CODEC_FORMAT_JPEG
@ NI_CODEC_FORMAT_VP9
@ NI_PIX_FMT_ARGB
@ NI_PIX_FMT_P010LE
@ NI_PIX_FMT_YUV420P
@ NI_PIX_FMT_ABGR
@ NI_PIX_FMT_10_TILED4X4
@ NI_PIX_FMT_BGR0
@ NI_PIX_FMT_RGBA
@ NI_PIX_FMT_NV12
@ NI_PIX_FMT_8_TILED4X4
@ NI_PIX_FMT_BGRA
@ NI_PIX_FMT_YUV420P10LE
#define GC620_ABGR8888
#define NI_HDR10P_SEI_BYTE5
#define NI_PARAM_MAX_WIDTH
#define GC620_ARGB8888
@ PIC_TYPE_IDR
@ PIC_NOT_CODED
@ PIC_TYPE_I
struct _ni_network_layer_info ni_network_layer_info_t
itu_frame_type
@ ITU_FRAME_TYPE_NONE
@ ITU_FRAME_TYPE_B
@ ITU_FRAME_TYPE_P
@ ITU_FRAME_TYPE_I
struct _ni_sei_header ni_sei_header_t
#define NI_CC_SEI_BYTE3
#define NI_HDR10P_SEI_BYTE3
#define NI_SCALER_FLAG_IO
@ NI_PRESETS_NONE
@ NI_VQ_FASTER
@ NI_VQ_SLOWER
@ NI_VQ_FAST
@ NI_VQ_SLOW
@ NI_VQ_MEDIUM
@ NI_VQ_VERYSLOW
@ NI_VQ_VERYFAST
#define NI_EC_POLICY_DEFAULT
@ NI_CUS_ROI_DISABLE
#define NI_MAX_RESOLUTION_HEIGHT
@ NI_QUADRA_HEVC_PROFILE_MAIN
@ NI_QUADRA_HEVC_PROFILE_MAIN10
#define NI_MAX_REF_PIC
#define GC620_BGRX8888
@ NI_QUADRA_H264_PROFILE_BASELINE
@ NI_QUADRA_H264_PROFILE_HIGH
@ NI_QUADRA_H264_PROFILE_MAIN
@ NI_QUADRA_H264_PROFILE_EXTENDED
struct _ni_instance_mgr_detail_status ni_instance_mgr_detail_status_t
#define NI_HDR10P_SEI_BYTE4
#define NI_CC_SEI_HDR_HEVC_LEN
struct _ni_frameclone_desc ni_frameclone_desc_t
ni_retcode_t ni_encoder_session_open(ni_session_context_t *p_ctx)
Open a xcoder encoder instance.
void SwapSWBytes(uint8_t *buf, uint32_t bytes)
ni_retcode_t ni_ai_alloc_hwframe(ni_session_context_t *p_ctx, int width, int height, int options, int pool_size, int frame_index)
ni_retcode_t ni_config_instance_set_decoder_ppu_params(ni_session_context_t *p_ctx, void *p_dec_ppu_config, int buffer_size)
Send a p_config command to configure decoding parameters.
ni_retcode_t ni_get_memory_offset(ni_session_context_t *p_ctx, const niFrameSurface1_t *hwdesc, uint32_t *p_offset)
Get an address offset from a hw descriptor.
enum _ni_t35_sei_mesg_type ni_t35_sei_mesg_type_t
ni_retcode_t ni_scaler_config_frame(ni_session_context_t *p_ctx, ni_frame_config_t *p_cfg)
config a frame in the scaler
ni_retcode_t ni_scaler_multi_config_frame(ni_session_context_t *p_ctx, ni_frame_config_t p_cfg_in[], int numInCfgs, ni_frame_config_t *p_cfg_out)
config multiple frames in the scaler
ni_retcode_t ni_decoder_session_copy_internal(ni_session_context_t *src_p_ctx, ni_session_context_t *dst_p_ctx)
Copy a xcoder decoder worker thread info.
int ni_hwupload_session_write(ni_session_context_t *p_ctx, ni_frame_t *p_frame, niFrameSurface1_t *hwdesc)
Send a YUV p_frame to upload session.
ni_retcode_t ni_encoder_session_sequence_change(ni_session_context_t *p_ctx, ni_resolution_t *p_resolution)
Send sequnce change to a xcoder encoder instance.
int ni_decoder_session_write(ni_session_context_t *p_ctx, ni_packet_t *p_packet)
Send a video p_packet to decoder.
ni_retcode_t ni_config_instance_set_encoder_frame_params(ni_session_context_t *p_ctx, ni_encoder_frame_params_t *p_params)
Send a p_config command to configure encoding p_frame parameters.
ni_retcode_t ni_decoder_session_close(ni_session_context_t *p_ctx, int eos_recieved)
Close a xcoder decoder instance.
void ni_populate_device_capability_struct(ni_device_capability_t *p_cap, void *p_data, ni_device_handle_t device_handle, bool device_in_ctxt)
Get info from received xcoder capability.
ni_retcode_t ni_config_instance_set_write_len(ni_session_context_t *p_ctx, ni_device_type_t device_type, uint32_t len)
Send a p_config command to set the length for the incoming write packet.
ni_retcode_t ni_config_instance_set_sequence_change(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_resolution_t *p_resolution)
Send a p_config command to inform encoder sequence change.
ni_retcode_t ni_hwupload_session_query_buffer_avail(ni_session_context_t *p_ctx)
Query and acquire buffer from xcoder upload instance.
ni_retcode_t ni_scaler_session_close(ni_session_context_t *p_ctx, int eos_received)
close a scaler session
ni_retcode_t ni_ai_session_write(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
ni_retcode_t ni_config_instance_hvsplus(ni_session_context_t *p_ctx)
ni_retcode_t ni_scaler_session_query_buffer_avail(ni_session_context_t *p_ctx)
Query and acquire buffer from xcoder scaler instance.
ni_retcode_t ni_set_cpu_affinity(ni_session_context_t *p_ctx)
set cpu affinity based on numa node
ni_retcode_t ni_config_instance_sos(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Send a p_config command for Start Of Stream.
ni_retcode_t ni_encoder_session_close(ni_session_context_t *p_ctx, int eos_recieved)
Close a xcoder encoder instance.
ni_retcode_t ni_ai_session_query_metrics(ni_session_context_t *p_ctx, ni_network_perf_metrics_t *p_metrics)
ni_retcode_t ni_dump_log_single_core(ni_session_context_t *p_ctx, void *p_data, uint32_t core_id, bool gen_log_file)
ni_retcode_t ni_encoder_session_send_eos(ni_session_context_t *p_ctx)
Flush encoder output.
ni_retcode_t ni_config_read_inout_layers(ni_session_context_t *p_ctx, ni_network_data_t *p_network)
int ni_decoder_session_read(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
Retrieve a YUV p_frame from decoder.
ni_retcode_t ni_encoder_metadata_buffer_alloc(ni_frame_t *p_frame, int extra_len)
Allocate memory for the metadata header and auxillary data for encoder input data.
void ni_set_custom_dec_template(ni_session_context_t *p_ctx, ni_decoder_config_t *p_cfg, ni_xcoder_params_t *p_src, uint32_t max_pkt_size)
Setup all xcoder configurations with custom parameters (Rev. B)
ni_retcode_t ni_ai_session_read(ni_session_context_t *p_ctx, ni_packet_t *p_packet)
ni_retcode_t ni_hwframe_clone(ni_session_context_t *p_ctx, ni_frameclone_desc_t *p_frameclone_desc)
Copy a src hw frame to a dst hw frame.
int ni_xcoder_session_query_detail(ni_session_context_t *p_ctx, ni_device_type_t device_type, void *detail_data, int ver)
Query current xcoder status.
ni_retcode_t ni_ai_alloc_dst_frame(ni_session_context_t *p_ctx, niFrameSurface1_t *p_out_surface)
ni_retcode_t ni_send_to_target_v2(ni_session_context_t *p_ctx, ni_frame_t *pSrcFrame, const ni_p2p_sgl_t *dmaAddrs)
Generates and writes a nvme command with sgl list.
#define HEVC_LEVEL_NUM
uint32_t ni_get_log_lba(ni_core_type_t eCoreType)
#define NI_XCODER_FAILURES_MAX
ni_retcode_t ni_config_instance_set_uploader_params(ni_session_context_t *p_ctx, uint32_t pool_size, uint32_t pool)
Send a p_config command to configure uploading parameters.
ni_retcode_t ni_decoder_session_open(ni_session_context_t *p_ctx)
Open a xcoder decoder instance.
ni_retcode_t ni_encoder_start_buffer_alloc(ni_frame_t *p_frame)
Allocate memory for the non-4k-aligned part at the start of YUV data for encoder input data.
ni_retcode_t ni_scaler_session_read_hwdesc(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
read a hardware descriptor from a scaler session
ni_retcode_t ni_uploader_session_close(ni_session_context_t *p_ctx)
Close an xcoder upload instance.
ni_retcode_t ni_scaler_alloc_frame(ni_session_context_t *p_ctx, int width, int height, int format, int options, int rectangle_width, int rectangle_height, int rectangle_x, int rectangle_y, int rgba_color, int frame_index)
allocate a frame in the scaler
ni_retcode_t ni_decoder_session_read_desc(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
Retrieve a hw desc p_frame from decoder.
void * ni_session_keep_alive_thread(void *arguments)
decoder keep alive thread function triggers every 1 second
_ni_t35_sei_mesg_type
@ NI_T35_SEI_HDR10_PLUS
@ NI_T35_SEI_CLOSED_CAPTION
void SwapSW32(uint32_t *buf, uint32_t bytes)
ni_retcode_t ni_check_common_params(ni_t408_config_t *p_param, ni_xcoder_params_t *p_src, char *p_param_err, uint32_t max_err_len)
#define MIN(x, y)
ni_retcode_t ni_recv_from_target(ni_session_context_t *p_ctx, const ni_p2p_sgl_t *dmaAddrs, ni_frame_t *pDstFrame)
void enqueue_ni_frame(ni_session_context_t *p_ctx, ni_frame_t *ni_frame, int32_t source_width, int32_t source_height)
char * ni_get_core_name(ni_core_type_t eCoreType)
ni_retcode_t ni_device_config_ns_qos(ni_device_handle_t device_handle, uint32_t key, uint32_t value)
Send namespace num / Opmode and SRIOv index/value to the device with specified logic block address.
#define DP_IPC_PASSTHRU
ni_retcode_t ni_config_instance_network_binary(ni_session_context_t *p_ctx, void *nb_data, uint32_t nb_size)
ni_retcode_t ni_query_instance_buf_info(ni_session_context_t *p_ctx, ni_instance_buf_info_rw_type_t rw_type, ni_device_type_t device_type, ni_instance_buf_info_t *p_inst_buf_info)
Query a particular xcoder instance to get buffer/data Info data.
int ni_query_detail_status(ni_session_context_t *p_ctx, ni_device_type_t device_type, void *p_detail_status, int ver)
Query a particular xcoder instance to get DetailStatus data.
int ni_get_planar_from_pixfmt(int pix_fmt)
Grab planar info from NI_PIX_FMT.
void calculate_psnr(ni_session_context_t *p_ctx, ni_packet_t *p_packet)
ni_retcode_t ni_query_stream_info(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_instance_mgr_stream_info_t *p_stream_info)
Query a particular xcoder instance to get Stream Info data.
ni_retcode_t ni_device_set_ddr_configuration(ni_session_context_t *p_ctx, uint8_t ddr_priority_mode)
Set DDR configuration of Quadra device.
int ni_hwupload_session_read_hwdesc(ni_session_context_t *p_ctx, niFrameSurface1_t *hwdesc)
Retrieve a HW descriptor of uploaded frame.
void ni_set_custom_template(ni_session_context_t *p_ctx, ni_encoder_config_t *p_cfg, ni_xcoder_params_t *p_src)
Setup all xcoder configurations with custom parameters (Rev. B)
ni_retcode_t ni_send_session_keep_alive(uint32_t session_id, ni_device_handle_t device_handle, ni_event_handle_t event_handle, void *p_data)
send a keep alive message to firmware
#define H264_LEVEL_NUM
ni_retcode_t ni_validate_custom_template(ni_session_context_t *p_ctx, ni_encoder_config_t *p_cfg, ni_xcoder_params_t *p_src, char *p_param_err, uint32_t max_err_len)
Perform validation on custom parameters (Rev. B)
int ni_xcoder_session_query(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Query current xcoder status.
ni_retcode_t ni_config_instance_set_scaler_params(ni_session_context_t *p_ctx, ni_scaler_params_t *p_params)
Send a p_config command to configure scaling parameters.
ni_retcode_t ni_device_get_ddr_configuration(ni_session_context_t *p_ctx)
Get DDR configuration of Quadra device.
int ni_create_frame(ni_frame_t *p_frame, uint32_t read_length, uint64_t *p_frame_offset, uint32_t *p_frame_dropped, bool is_hw_frame)
Get info from received p_frame.
ni_retcode_t ni_config_instance_eos(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Send a p_config command for End Of Stream.
#define AV1_LEVEL_NUM
ni_retcode_t ni_ai_session_read_hwdesc(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
read a hardware descriptor from a scaler session
ni_retcode_t ni_ai_query_network_ready(ni_session_context_t *p_ctx)
int ni_query_general_status(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_instance_mgr_general_status_t *p_gen_status)
Query a particular xcoder instance to get GeneralStatus data.
check_err_rc_option_t
#define MAX(x, y)
ni_retcode_t ni_check_ratecontrol_params(ni_encoder_config_t *p_cfg, char *p_param_err, uint32_t max_err_len)
int ni_query_eos(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_instance_mgr_stream_complete_t *p_stream_complete)
Query a particular xcoder instance to get End of Output data.
#define READ_U32_FROM_BUF_2BYTES(buf, byte_offset)
ni_retcode_t ni_config_instance_flush(ni_session_context_t *p_ctx, ni_device_type_t device_type)
Send a p_config command to flush the stream.
#define CHECK_VPU_RECOVERY(ret)
void SwapSW16(uint16_t *buf, uint32_t bytes)
#define READ_U32_FROM_BUF(buf, byte_offset)
ni_retcode_t ni_config_session_rw(ni_session_context_t *p_ctx, ni_session_config_rw_type_t rw_type, uint8_t enable, uint8_t hw_action, uint16_t frame_id)
Configure the read/write pipe for a session to control its behavior.
ni_retcode_t ni_decoder_session_send_eos(ni_session_context_t *p_ctx)
Send end of stream signal to the decoder.
ni_retcode_t ni_config_instance_set_decoder_params(ni_session_context_t *p_ctx, uint32_t max_pkt_size)
Send a p_config command to configure decoding parameters.
int ni_encoder_session_read(ni_session_context_t *p_ctx, ni_packet_t *p_packet)
#define MAX_BDF_LEN
ni_retcode_t ni_validate_custom_dec_template(ni_xcoder_params_t *p_src, ni_session_context_t *p_ctx, ni_decoder_config_t *p_cfg, char *p_param_err, uint32_t max_err_len)
Perform validation on custom dec parameters (Rev. B)
ni_retcode_t ni_uploader_session_open(ni_session_context_t *p_ctx)
Open a xcoder upload instance.
#define CHECK_ERR_RC(ctx, rc, info, opcode, type, hw_id, inst_id, opt)
ni_retcode_t ni_ai_session_open(ni_session_context_t *p_ctx)
#define MAGIC_P2P_VALUE
ni_retcode_t ni_config_instance_set_encoder_params(ni_session_context_t *p_ctx)
Send a p_config command to configure encoding parameters.
ni_retcode_t ni_clear_instance_buf(niFrameSurface1_t *surface)
clear a particular xcoder instance buffer/data
ni_retcode_t ni_query_session_statistic_info(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_session_statistic_t *p_session_statistic)
Query a particular xcoder session to get session statistics.
void ni_params_print(ni_xcoder_params_t *const p_encoder_params)
Print xcoder user configurations.
ni_retcode_t ni_ai_multi_config_frame(ni_session_context_t *p_ctx, ni_frame_config_t p_cfg_in[], int numInCfgs, ni_frame_config_t *p_cfg_out)
ni_retcode_t ni_ai_session_close(ni_session_context_t *p_ctx, int eos_recieved)
void ni_set_default_template(ni_session_context_t *p_ctx, ni_encoder_config_t *p_config)
Setup and initialize all xcoder configuration to default (Rev. B)
int lower_pixel_rate(const ni_load_query_t *pQuery, uint32_t ui32CurrentLowest)
void SwapSW64(uint64_t *buf, uint64_t bytes)
void ni_fix_VUI(uint8_t *vui, int pos, int value)
insert the 32 bits of integer value at bit position pos
int ni_get_bitdepth_factor_from_pixfmt(int pix_fmt)
Grab bitdepth factor from NI_PIX_FMT.
int ni_hwdownload_session_read(ni_session_context_t *p_ctx, ni_frame_t *p_frame, niFrameSurface1_t *hwdesc)
Retrieve a YUV p_frame from decoder.
#define AI_MODEL_TYPE_USM_FILTER
ni_retcode_t ni_decoder_session_flush(ni_session_context_t *p_ctx)
Flush decoder output.
#define HIGH_TIER
ni_retcode_t ni_query_session_stats(ni_session_context_t *p_ctx, ni_device_type_t device_type, ni_session_stats_t *p_session_stats, int rc, int opcode)
Query a particular session to get the stats info.
ni_retcode_t ni_dump_log_all_cores(ni_session_context_t *p_ctx, void *p_data, bool gen_log_file)
int ni_scaler_session_open(ni_session_context_t *p_ctx)
Open a xcoder scaler instance.
int ni_encoder_session_write(ni_session_context_t *p_ctx, ni_frame_t *p_frame)
Send a YUV p_frame to encoder.
int ni_hwdownload_by_frame_idx(niFrameSurface1_t *hwdesc, ni_frame_t *p_frame, int is_auto_dl)
Retrieve a YUV p_frame by frame index.
#define AI_MODEL_TYPE_HVSPLUS_FILTER
Private definitions used by ni_device_api.c for video processing tasks.
#define CU_SIZE_BIT_POSITION
#define NI_FW_ENC_BITSTREAM_META_DATA_SIZE_UNDER_MAJOR_6_MINOR_rc
#define AVC_MB_MODE_BYTE_OFFSET
struct _ni_instance_mgr_stream_complete ni_instance_mgr_stream_complete_t
#define NI_SESSION_CLOSE_RETRY_MAX
#define AVC_MB_MODE_BIT_POSITION
@ GOP_PRESET_IDX_CUSTOM
@ GOP_PRESET_IDX_HIERARCHICAL_IPPPP
@ GOP_PRESET_IDX_SP
@ GOP_PRESET_IDX_DEFAULT
@ GOP_PRESET_IDX_NONE
@ GOP_PRESET_IDX_IBBBP
#define CU_SIZE_BITS
#define AVC_RDCOST_BIT_POSITION
struct _ni_network_buffer_info ni_network_buffer_info_t
#define INTRACOST_BITS
#define INTERCOST_BIT_POSITION
#define CU_MODE_BITS
#define INTRA_PART_MODE_BYTE_OFFSET
#define CU_INFO_OUTPUT_SIZE_V1
#define RDCOST_OTHER_BYTE_OFFSET
#define RDCOST_OTHER_BITS
#define NI_FW_ENC_BITSTREAM_META_DATA_SIZE_UNDER_MAJOR_6_MINOR_sM
#define FW_LOG_END_DELIMITER_1
ni_session_config_rw_type_t
@ SESSION_WRITE_CONFIG
@ SESSION_READ_CONFIG
#define NI_P2P_RECV
struct _ni_session_config_rw ni_session_config_rw_t
struct _ni_ai_config_t ni_ai_config_t
struct _ni_decoder_config_t ni_decoder_config_t
struct _ni_instance_mgr_stream_info ni_instance_mgr_stream_info_t
struct _ni_instance_buf_info ni_instance_buf_info_t
#define AVC_INTRA_PART_MODE_BIT_POSITION
#define RDCOST_BIT_POSITION
#define NI_P2P_SEND
#define NI_RETRY_INTERVAL_100US
#define INTER_PRED_IDC_BYTE_OFFSET
#define INTER_PRED_IDC_BITS
#define FW_LOG_END_DELIMITER_0
#define CU_MODE_BIT_POSITION
struct _ni_session_stats ni_session_stats_t
#define NI_RETRY_INTERVAL_200US
#define INTRA_PART_MODE_BIT_POSITION
#define NI_QUADRA_MEMORY_CONFIG_SR_4G
#define RDCOST_BYTE_OFFSET
#define INTRA_PART_MODE_BITS
#define AVC_MB_MODE_BITS
#define RDCOST_BITS
#define INTRACOST_BIT_POSITION
@ ni_xcoder_resource_recovery
#define AVC_INTRA_PART_MODE_BYTE_OFFSET
#define QP_BYTE_OFFSET
#define QP_BIT_POSITION
#define NI_DMA_SGL_MAX_XFER_SIZE
#define RDCOST_OTHER_BIT_POSITION
#define INTER_PRED_IDC_BIT_POSITION
struct _ni_encoder_config_t ni_encoder_config_t
#define AVC_INTRA_PART_MODE_BITS
#define AVC_RDCOST_BYTE_OFFSET
#define CU_SIZE_BYTE_OFFSET
struct _ni_metadata_enc_bstream ni_metadata_enc_bstream_t
#define AVC_INTER_PRED_IDC_BITS
#define AVC_INTER_PRED_IDC_BIT_POSITION
struct _ni_instance_mgr_allocation_info ni_instance_mgr_allocation_info_t
#define FW_LOG_START_DELIMITER_1
#define FW_LOG_START_DELIMITER_0
#define NI_QUADRA_MEMORY_CONFIG_SR
#define NI_MAX_AI_NETWORK_BINARY_BUFFER_QUERY_RETRIES
struct _ni_encoder_frame_params ni_encoder_frame_params_t
#define NI_MAX_P2P_SGL_ENTRIES
#define NI_MAX_DEC_SESSION_READ_QUERY_EOS_RETRIES
#define INTRACOST_BYTE_OFFSET
struct _ni_instance_mgr_general_status ni_instance_mgr_general_status_t
#define TUNE_BFRAME_VISUAL_MEDIUM
struct _ni_resolution ni_resolution_t
#define CU_MODE_BYTE_OFFSET
#define NI_HWDESC_UNIFIED_MEMBIN_SIZE
#define NI_FW_ENC_BITSTREAM_META_DATA_SIZE
#define FRAME_CHUNK_INDEX_SIZE
#define QP_BITS
ni_instance_buf_info_rw_type_t
@ INST_BUF_INFO_RW_WRITE
@ INST_BUF_INFO_RW_READ
@ INST_BUF_INFO_R_ACQUIRE
@ INST_BUF_INFO_RW_WRITE_BUSY
@ INST_BUF_INFO_RW_UPLOAD
@ INST_BUF_INFO_RW_WRITE_BY_EP
@ INST_BUF_INFO_RW_READ_BY_AI
@ INST_BUF_INFO_RW_READ_BUSY
#define AVC_RDCOST_BITS
#define INTERCOST_BITS
#define AVC_INTER_PRED_IDC_BYTE_OFFSET
#define NI_MAX_SEGMENT_NUM
#define INTERCOST_BYTE_OFFSET
#define NI_QUADRA_MEMORY_CONFIG_DR
#define NI_AI_HW_ALIGN_SIZE
#define NI_FW_ENC_BITSTREAM_META_DATA_SIZE_UNDER_MAJOR_6_MINOR_o
#define NI_MINIMUM_CROPPED_LENGTH
int hwdl_frame(ni_session_context_t *p_ctx, ni_session_data_io_t *p_session_data, ni_frame_t *p_src_frame, int output_format)
Download hw frames by HwDesc.
void * ni_lat_meas_q_add_entry(ni_lat_meas_q_t *frame_time_q, uint64_t abs_time, int64_t ts_time)
Add a new entry to latency queue.
uint64_t ni_lat_meas_q_check_latency(ni_lat_meas_q_t *frame_time_q, uint64_t abs_time, int64_t ts_time)
Check latency of a frame referenced by its timestamp.
Utility definitions for measuring frame/packet processing time in NETINT video processing devices.
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
uint64_t ni_log_get_utime()
Get time for logs with microsecond timestamps.
Definition ni_log.c:308
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition ni_log.c:183
#define NI_ERRNO_LEN
Definition ni_log.h:51
@ NI_LOG_DEBUG
Definition ni_log.h:64
@ NI_LOG_TRACE
Definition ni_log.h:65
@ NI_LOG_ERROR
Definition ni_log.h:62
@ NI_LOG_INFO
Definition ni_log.h:63
int32_t ni_nvme_send_read_cmd(ni_device_handle_t handle, ni_event_handle_t event_handle, void *p_data, uint32_t data_len, uint32_t lba)
Compose an io read command.
Definition ni_nvme.c:554
int32_t ni_nvme_send_write_cmd(ni_device_handle_t handle, ni_event_handle_t event_handle, void *p_data, uint32_t data_len, uint32_t lba)
Compose a io write command.
Definition ni_nvme.c:660
ni_retcode_t ni_nvme_check_error_code(int rc, int opcode, uint32_t xcoder_type, uint32_t hw_id, uint32_t *p_instance_id)
Check f/w error return code, and if it's a fatal one, terminate application's decoding/encoding proce...
Definition ni_nvme.c:62
Private definitions for interfacing with NETINT video processing devices over NVMe.
#define CONFIG_INSTANCE_UploadModel_W(sid, instance)
Definition ni_nvme.h:919
#define CONFIG_INSTANCE_SetAiHVSPlus_W(sid, instance)
Definition ni_nvme.h:861
#define QUERY_INSTANCE_UPLOAD_ID_R(sid, instance)
Definition ni_nvme.h:742
#define CONFIG_INSTANCE_SetScalerPara_W(sid, instance)
Definition ni_nvme.h:821
#define CONFIG_INSTANCE_SetSOS_W(sid, instance)
Definition ni_nvme.h:810
#define CONFIG_INSTANCE_SetP2P_W(sid, instance)
Definition ni_nvme.h:872
#define WRITE_METADATA_W(sid, instance)
Definition ni_nvme.h:679
#define LBA_BIT_OFFSET
Definition ni_nvme.h:627
#define CONFIG_SESSION_FRAME_COPY_W(sid)
Definition ni_nvme.h:913
#define FL_LOG_OFFSET_IN_4K
Definition ni_nvme.h:668
@ nvme_admin_cmd_xcoder_config
Definition ni_nvme.h:324
@ nvme_admin_cmd_xcoder_open
Definition ni_nvme.h:318
@ nvme_admin_cmd_xcoder_query
Definition ni_nvme.h:320
#define QUERY_INSTANCE_STREAM_INFO_R(sid, instance)
Definition ni_nvme.h:722
#define QUERY_INSTANCE_NL_V2_R(sid, instance)
Definition ni_nvme.h:773
#define WRITE_INSTANCE_W(sid, instance)
Definition ni_nvme.h:677
#define QUERY_INSTANCE_ACQUIRE_BUF(sid, instance)
Definition ni_nvme.h:744
#define QUERY_INSTANCE_NL_R(sid, instance)
Definition ni_nvme.h:761
#define QUERY_INSTANCE_RBUFF_SIZE_BUSY_R(sid, instance)
Definition ni_nvme.h:732
#define CONFIG_INSTANCE_SetEOS_W(sid, instance)
Definition ni_nvme.h:812
#define CONFIG_SESSION_DDR_PRIORITY_W(sid)
Definition ni_nvme.h:907
#define DOWNLOAD_FRAMEIDX_R(frame_id)
Definition ni_nvme.h:686
#define CONFIG_INSTANCE_SetScalerAlloc_W(sid, instance)
Definition ni_nvme.h:826
#define FP_LOG_OFFSET_IN_4K
Definition ni_nvme.h:667
#define QUERY_INSTANCE_HW_OUT_SIZE_R(sid, instance)
Definition ni_nvme.h:750
#define CONFIG_INSTANCE_Flush_W(sid, instance)
Definition ni_nvme.h:814
#define CONFIG_INSTANCE_SetPktSize_W(sid, instance)
Definition ni_nvme.h:850
#define NVME_LOG_OFFSET_IN_4K
Definition ni_nvme.h:663
#define CONFIG_INSTANCE_SetDecPpuPara_W(sid, instance)
Definition ni_nvme.h:819
#define CLOSE_SESSION_R(sid, instance)
Definition ni_nvme.h:704
#define QUERY_INSTANCE_RBUFF_SIZE_R(sid, instance)
Definition ni_nvme.h:726
#define CONFIG_INSTANCE_SetAiFrm_W(sid, instance)
Definition ni_nvme.h:866
#define QUERY_GENERAL_GET_STATUS_R(instance)
Definition ni_nvme.h:785
#define QUERY_SESSION_STATS_R(sid, instance)
Definition ni_nvme.h:710
#define EP_LOG_OFFSET_IN_4K
Definition ni_nvme.h:664
#define CONFIG_SESSION_Read_W(sid)
Definition ni_nvme.h:881
#define IDENTIFY_DEVICE_R
Definition ni_nvme.h:690
#define QUERY_INSTANCE_WBUFF_SIZE_R_BY_EP(sid, instance)
Definition ni_nvme.h:730
#define NI_DATA_BUFFER_LEN
Definition ni_nvme.h:626
#define QUERY_INSTANCE_EOS_R(sid, instance)
Definition ni_nvme.h:724
#define TP_LOG_OFFSET_IN_4K
Definition ni_nvme.h:666
#define QUERY_DETAIL_GET_STATUS_R(instance)
Definition ni_nvme.h:788
#define QUERY_INSTANCE_AI_INFO_R(sid, instance)
Definition ni_nvme.h:717
#define CONFIG_SESSION_KeepAlive_W(sid)
Definition ni_nvme.h:879
#define CONFIG_INSTANCE_SetEncRoiQpMap_W(sid, instance)
Definition ni_nvme.h:854
#define QUERY_INSTANCE_METRICS_R(sid, instance)
Definition ni_nvme.h:779
#define CONFIG_INSTANCE_SetEncFramePara_W(sid, instance)
Definition ni_nvme.h:848
#define QUERY_INSTANCE_CUR_STATUS_INFO_R(sid, instance)
Definition ni_nvme.h:715
#define QUERY_INSTANCE_NL_SIZE_R(sid, instance)
Definition ni_nvme.h:756
#define CLEAR_INSTANCE_BUF_W(frame_id)
Definition ni_nvme.h:886
#define CONFIG_INSTANCE_SetAiPara_W(sid, instance)
Definition ni_nvme.h:856
#define QUERY_INSTANCE_WBUFF_SIZE_BUSY_R(sid, instance)
Definition ni_nvme.h:737
#define CONFIG_INSTANCE_SetSeqChange_W(sid, instance)
Definition ni_nvme.h:852
#define OPEN_ADD_CODEC(instance, codec, param)
Definition ni_nvme.h:699
#define NI_NVME_IDENTITY_CMD_DATA_SZ
Definition ni_nvme.h:38
#define CONFIG_SESSION_KeepAliveTimeout_W(sid)
Definition ni_nvme.h:890
#define CONFIG_INSTANCE_SetEncPara_W(sid, instance)
Definition ni_nvme.h:844
#define READ_INSTANCE_R(sid, instance)
Definition ni_nvme.h:683
#define QUERY_INSTANCE_WBUFF_SIZE_R(sid, instance)
Definition ni_nvme.h:728
#define QUERY_INSTANCE_NL_SIZE_V2_R(sid, instance)
Definition ni_nvme.h:767
#define QUERY_DETAIL_GET_STATUS_V1_R(instance)
Definition ni_nvme.h:790
@ nvme_config_xcoder_config_set_write_legth
Definition ni_nvme.h:435
@ nvme_config_xcoder_config_set_sequence_change
Definition ni_nvme.h:437
#define CONFIG_SESSION_SWVersion_W(sid)
Definition ni_nvme.h:896
#define CONFIG_SESSION_Write_W(sid)
Definition ni_nvme.h:883
#define OPEN_SESSION_CODEC(instance, codec, param)
Definition ni_nvme.h:697
#define CONFIG_INSTANCE_SetDecPara_W(sid, instance)
Definition ni_nvme.h:817
#define DP_LOG_OFFSET_IN_4K
Definition ni_nvme.h:665
#define CONFIG_GLOBAL_NAMESPACE_NUM
Definition ni_nvme.h:902
Definitions related to NETINT P2P kernel driver interface.
struct timeval current_time
int ni_rsrc_get_numa_node(char *device_name)
get linux numa_node
void ni_rsrc_free_device_context(ni_device_context_t *p_device_context)
Free previously allocated device context.
LIB_API ni_device_context_t * ni_rsrc_get_device_context(ni_device_type_t type, int guid)
Allocates and returns a pointer to ni_device_context_t struct based on provided device_type and guid....
Private definitions used by ni_rsrc_api.cpp for management of NETINT video processing devices.
void get_dev_pcie_addr(char *device_name, char *pcie, char *domain, char *slot, char *dev, char *func)
ni_retcode_t ni_timestamp_register(ni_queue_buffer_pool_t *p_buffer_pool, ni_timestamp_table_t *p_table, int64_t timestamp, uint64_t data_info)
Register timestamp in timestamp/frameoffset table.
Definition ni_util.c:1996
int ni_pthread_mutex_lock(ni_pthread_mutex_t *mutex)
thread mutex lock
Definition ni_util.c:4686
void ni_buffer_pool_free(ni_queue_buffer_pool_t *p_buffer_pool)
Definition ni_util.c:1412
void ni_dec_fme_buffer_pool_free(ni_buf_pool_t *p_buffer_pool)
Definition ni_util.c:1358
ni_retcode_t ni_strncpy(char *dest, size_t dmax, const char *src, size_t slen)
Definition ni_util.c:518
int ni_pthread_cond_signal(ni_pthread_cond_t *cond)
signal a condition
Definition ni_util.c:4880
int ni_posix_memalign(void **memptr, size_t alignment, size_t size)
Allocate aligned memory.
Definition ni_util.c:202
void ni_fmt_fw_api_ver_str(const char ver_str[], char fmt_str[])
Get formatted FW API version string from unformatted FW API version string.
Definition ni_util.c:4272
ni_retcode_t ni_strerror(char *dest, size_t dmax, int errnum)
Definition ni_util.c:656
void ni_calculate_sha256(const uint8_t aui8Data[], size_t ui32DataLength, uint8_t aui8Hash[])
Definition ni_util.c:4176
int32_t ni_dec_fme_buffer_pool_initialize(ni_session_context_t *p_ctx, int32_t number_of_buffers, int width, int height, int height_align, int factor)
Definition ni_util.c:1249
ni_retcode_t ni_timestamp_get_with_threshold(ni_timestamp_table_t *p_table, uint64_t frame_info, int64_t *p_timestamp, int32_t threshold, int32_t print, ni_queue_buffer_pool_t *p_buffer_pool)
Definition ni_util.c:2046
ni_retcode_t ni_strcat(char *dest, size_t dmax, const char *src)
Definition ni_util.c:689
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:2664
ni_retcode_t ni_fopen(FILE **fp, const char *filename, const char *mode)
Definition ni_util.c:983
int ni_pthread_sigmask(int how, const ni_sigset_t *set, ni_sigset_t *oldset)
examine and change mask of blocked signals
Definition ni_util.c:4934
ni_retcode_t ni_strcpy(char *dest, size_t dmax, const char *src)
Definition ni_util.c:453
uint32_t ni_ai_network_layer_size(ni_network_layer_params_t *p_param)
Definition ni_util.c:3989
int ni_pthread_cond_timedwait(ni_pthread_cond_t *cond, ni_pthread_mutex_t *mutex, const struct timespec *abstime)
wait on a condition
Definition ni_util.c:4900
ni_retcode_t ni_timestamp_init(ni_session_context_t *p_ctx, ni_timestamp_table_t **pp_table, const char *name)
Initialize timestamp handling.
Definition ni_util.c:1931
void ni_usleep(int64_t usec)
Definition ni_util.c:362
ni_retcode_t ni_queue_free(ni_queue_t *p_queue, ni_queue_buffer_pool_t *p_buffer_pool)
Free xcoder queue.
Definition ni_util.c:2434
uint64_t ni_gettime_ns(void)
Definition ni_util.c:2622
void ni_timestamp_scan_cleanup(ni_timestamp_table_t *pts_list, ni_timestamp_table_t *dts_list, ni_queue_buffer_pool_t *p_buffer_pool)
Definition ni_util.c:2054
int ni_pthread_mutex_unlock(ni_pthread_mutex_t *mutex)
thread mutex unlock
Definition ni_util.c:4712
int ni_cmp_fw_api_ver(const char ver1[], const char ver2[])
Compare two 3 character strings containing a FW API version. Handle comparision when FW API version f...
Definition ni_util.c:4302
Utility definitions.
#define XCODER_MAX_ENC_PIC_HEIGHT
Definition ni_util.h:115
#define NI_DEC_FRAME_BUF_POOL_SIZE_INIT
Definition ni_util.h:117
#define XCODER_MIN_ENC_PIC_WIDTH
Definition ni_util.h:112
#define COMPILE_ASSERT(condition)
Definition ni_util.h:102
#define XCODER_MAX_NUM_TEMPORAL_LAYER
Definition ni_util.h:108
#define ni_aligned_free(p_memptr)
Definition ni_util.h:400
#define XCODER_MIN_ENC_PIC_HEIGHT
Definition ni_util.h:113
#define XCODER_MAX_ENC_PIC_WIDTH
Definition ni_util.h:114
#define XCODER_FRAME_OFFSET_DIFF_THRES
Definition ni_util.h:105
#define ni_memfree(p_memptr)
Definition ni_util.h:410
payload format of HDR SEI content light level info
ni_gop_params_t pic_param[NI_MAX_GOP_NUM]
decoded payload format of HDR SEI mastering display colour volume
ni_decoder_output_config_t asOutputConfig[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int scale_wh[NI_MAX_NUM_OF_DECODER_OUTPUTS][2]
int scale_resolution_ceil[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int semi_planar[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int scale_round[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int scale_long_short_edge[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int force_8_bit[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int crop_mode[NI_MAX_NUM_OF_DECODER_OUTPUTS]
int crop_whxy[NI_MAX_NUM_OF_DECODER_OUTPUTS][4]
device capability type
uint8_t xcoder_cnt[NI_DEVICE_TYPE_XCODER_MAX]
ni_hw_capability_t xcoder_devices[NI_MAX_DEVICES_PER_HW_INSTANCE]
uint8_t fw_branch_name[256]
ni_lock_handle_t lock
ni_custom_gop_params_t custom_gop_params
struct _ni_encoder_cfg_params::@16 rc
int spatialLayerBitrate[NI_MAX_SPATIAL_LAYERS]
int av1OpLevel[NI_MAX_SPATIAL_LAYERS]
uint8_t ui8av1OpLevel[NI_MAX_SPATIAL_LAYERS]
int32_t i32spatialLayerBitrate[NI_MAX_SPATIAL_LAYERS]
ni_t408_config_t niParamT408
uint16_t rectangle_height
uint16_t force_pic_qp
uint8_t inconsecutive_transfer
uint32_t data_len[NI_MAX_NUM_DATA_POINTERS]
unsigned int sei_hdr_mastering_display_color_vol_offset
uint8_t * p_buffer
uint32_t crop_top
uint32_t error_ratio
uint32_t start_of_stream
unsigned int sei_hdr_content_light_level_info_offset
unsigned int vui_len
ni_iovec_t * iovec
unsigned int reconf_len
long long dts
uint32_t start_len[NI_MAX_NUM_DATA_POINTERS]
uint32_t start_buffer_size
uint32_t end_of_stream
uint8_t separate_metadata
unsigned int sei_hdr_plus_len
uint64_t pkt_pos
uint32_t metadata_buffer_size
uint32_t crop_right
unsigned int vui_offset
uint32_t crop_bottom
uint32_t video_width
unsigned int sei_hdr_plus_offset
long long pts
uint8_t * p_data[NI_MAX_NUM_DATA_POINTERS]
uint32_t total_start_len
unsigned int extra_data_len
uint8_t * p_start_buffer
uint32_t buffer_size
unsigned int sei_total_len
uint8_t separate_start
unsigned int sei_cc_len
unsigned int sei_cc_offset
unsigned int sei_user_data_unreg_len
uint32_t crop_left
ni_pic_type_t ni_pict_type
long long orignal_pts
uint8_t use_cur_src_as_long_term_pic
ni_custom_sei_set_t * p_custom_sei_set
uint16_t hor_adjust_offset
unsigned int sei_hdr_content_light_level_info_len
uint32_t iovec_num
uint8_t * p_metadata_buffer
unsigned int sei_hdr_mastering_display_color_vol_len
unsigned int sei_user_data_unreg_offset
uint8_t use_long_term_ref
uint32_t video_height
unsigned int roi_len
int32_t framerate_denom
int32_t framerate_num
ni_gop_rps_t rps[NI_MAX_REF_PIC]
uint8_t max_number_of_contexts
uint8_t * p_input_buffer
ni_instance_upload_ret_hwdesc_t hw_inst_ind
uint32_t size
uint64_t last_benchmark_time
Definition ni_lat_meas.h:42
uint32_t fw_share_mem_usage
uint32_t total_pixel_load
uint32_t fw_model_load
uint32_t fw_p2p_mem_usage
uint32_t fw_video_shared_mem_usage
uint32_t current_load
uint32_t total_contexts
uint32_t active_hwuploaders
uint32_t fw_video_mem_usage
union _ni_metadata_common::@27 ui64_data
ni_sei_header_t first_sei_header
ni_metadata_common_t metadata_common
ni_metadata_common_t metadata_common
ni_segment_t segment[NI_MAX_SEGMENT_NUM]
ni_network_layer_offset_t * inset
ni_network_layer_info_t linfo
ni_network_layer_offset_t * outset
ni_network_layer_params_t * in_param
ni_network_layer_params_t * out_param
uint8_t hw_max_number_of_contexts
Definition ni_nvme.h:75
uint8_t fw_build_id[256]
Definition ni_nvme.h:222
uint8_t ai8Fr[8]
Definition ni_nvme.h:97
uint8_t hw2_video_profile
Definition ni_nvme.h:201
uint8_t xcoder_num_h264_decoder_hw
Definition ni_nvme.h:160
uint8_t hw0_video_level
Definition ni_nvme.h:176
uint8_t xcoder_num_h264_encoder_hw
Definition ni_nvme.h:161
uint8_t hw0_codec_type
Definition ni_nvme.h:170
ni_nvme_identity_xcoder_hw_t xcoder_devices[NI_MAX_DEVICES_PER_HW_INSTANCE]
Definition ni_nvme.h:232
uint8_t hw1_codec_type
Definition ni_nvme.h:183
uint8_t hw2_codec_format
Definition ni_nvme.h:195
uint8_t hw1_video_level
Definition ni_nvme.h:189
uint8_t fw_commit_time[26]
Definition ni_nvme.h:219
uint8_t xcoder_num_h265_decoder_hw
Definition ni_nvme.h:162
uint8_t fw_commit_hash[41]
Definition ni_nvme.h:220
uint8_t xcoder_num_elements
Definition ni_nvme.h:229
uint8_t xcoder_num_devices
Definition ni_nvme.h:230
uint16_t ui16Cctemp
Definition ni_nvme.h:118
uint8_t hw1_codec_format
Definition ni_nvme.h:182
uint8_t hw3_codec_format
Definition ni_nvme.h:208
uint8_t hw3_video_level
Definition ni_nvme.h:215
uint16_t ui16Ssvid
Definition ni_nvme.h:94
uint8_t fw_branch_name[256]
Definition ni_nvme.h:218
uint8_t hw2_codec_type
Definition ni_nvme.h:196
uint16_t ui16Wctemp
Definition ni_nvme.h:117
uint8_t hw3_codec_type
Definition ni_nvme.h:209
uint8_t xcoder_num_hw
Definition ni_nvme.h:159
uint8_t ai8Sn[20]
Definition ni_nvme.h:95
uint8_t fw_build_time[26]
Definition ni_nvme.h:221
uint8_t memory_cfg
Definition ni_nvme.h:225
uint8_t xcoder_cnt[14]
Definition ni_nvme.h:231
uint8_t device_is_xcoder
Definition ni_nvme.h:155
uint16_t ui16Vid
Definition ni_nvme.h:93
uint8_t hw0_video_profile
Definition ni_nvme.h:175
uint8_t hw3_video_profile
Definition ni_nvme.h:214
uint8_t xcoder_num_h265_encoder_hw
Definition ni_nvme.h:163
uint8_t hw0_codec_format
Definition ni_nvme.h:169
uint8_t hw2_video_level
Definition ni_nvme.h:202
uint8_t hw1_video_profile
Definition ni_nvme.h:188
uint8_t ai8Mn[40]
Definition ni_nvme.h:96
uint32_t ui32NumEntries
Definition ni_defs.h:424
uint64_t ui64DMAAddr[NI_MAX_P2P_SGL_ENTRY]
Definition ni_defs.h:426
uint32_t ui32DMALen[NI_MAX_P2P_SGL_ENTRY]
Definition ni_defs.h:425
uint32_t data_len
uint32_t start_of_stream
long long dts
uint32_t end_of_stream
uint64_t pkt_pos
uint8_t scene_change_detected
uint32_t video_width
uint8_t still_image_detected
long long pts
ni_bitstream_features_t bitstream_features
uint32_t buffer_size
double average_psnr
uint32_t avg_frame_qp
uint32_t frame_type
ni_custom_sei_set_t * p_custom_sei_set
long long pos
uint32_t video_height
union _ni_session_config_rw::@20 uHWAccessField
ni_io_event_t * io_event
uint64_t pkt_offsets_index_min[NI_FIFO_SZ]
char blk_xcoder_name[MAX_CHAR_IN_DEVICE_NAME]
uint8_t itu_t_t35_hdr10p_sei_hdr_hevc[NI_HDR10P_SEI_HDR_HEVC_LEN]
ni_pthread_mutex_t mutex
ni_pthread_cond_t low_delay_sync_cond
ni_queue_buffer_pool_t * buffer_pool
ni_session_statistic_t session_statistic
char blk_dev_name[NI_MAX_DEVICE_NAME_LEN]
ni_device_handle_t sender_handle
ni_device_handle_t device_handle
int flags_array[NI_FIFO_SZ]
ni_load_query_t load_query
ni_pthread_mutex_t * pext_mutex
ni_custom_sei_set_t * pkt_custom_sei_set[NI_FIFO_SZ]
ni_device_handle_t auto_dl_handle
uint8_t sei_trailer[NI_CC_SEI_TRAILER_LEN]
ni_aio_context_t aio_context
ni_network_data_t * network_data
ni_framerate_t framerate
uint64_t pkt_offsets_index[NI_FIFO_SZ]
uint8_t itu_t_t35_cc_sei_hdr_hevc[NI_CC_SEI_HDR_HEVC_LEN]
volatile uint64_t last_access_time
char dev_xcoder_name[MAX_CHAR_IN_DEVICE_NAME]
uint8_t itu_t_t35_cc_sei_hdr_h264[NI_CC_SEI_HDR_H264_LEN]
unsigned short domain
ni_event_handle_t event_handle
ni_input_frame input_frame_fifo[120]
encoder:calculate PSNR start
ni_framerate_t last_framerate
uint32_t meta_size
Params used in VFR mode Done///.
uint8_t pending_bitstream_buffer_realloc
ni_device_handle_t blk_io_handle
uint32_t biggest_bitstream_buffer_allocated
int hvsplus_level
encoder:calculate PSNR end
ni_overall_load_query_t overall_load_query
uint64_t pkt_pos[NI_FIFO_SZ]
ni_timestamp_table_t * pts_table
ni_session_run_state_t session_run_state
ni_pthread_mutex_t low_delay_sync_mutex
uint8_t itu_t_t35_hdr10p_sei_hdr_h264[NI_HDR10P_SEI_HDR_H264_LEN]
int64_t pts_offsets[NI_FIFO_SZ]
ni_timestamp_table_t * dts_queue
uint32_t decoder_last_drop_frame_num
ni_frame_pool_type_t pool_type
ni_buf_pool_t * dec_fme_buf_pool
union _ni_session_data_io::@19 data
uint32_t ui32FramesBuffered
Definition ni_defs.h:399
uint32_t ui32FramesDropped
Definition ni_defs.h:402
uint8_t ui8AdditionalFramesDelay
Definition ni_defs.h:415
uint32_t ui32LastTransactionCompletionStatus
Definition ni_defs.h:408
uint32_t ui32FramesCorrupted
Definition ni_defs.h:417
uint32_t ui32LastErrorStatus
Definition ni_defs.h:410
uint32_t ui32RdBufAvailSize
Definition ni_defs.h:396
uint32_t ui32WrBufAvailSize
Definition ni_defs.h:395
uint32_t ui32LastErrorTransactionId
Definition ni_defs.h:409
uint32_t ui32FramesCompleted
Definition ni_defs.h:400
uint32_t ui32FramesOutput
Definition ni_defs.h:401
uint32_t ui32FramesErrorRatio
Definition ni_defs.h:418
uint32_t ui32Session_timestamp_high
uint32_t ui32LastTransactionCompletionStatus
uint32_t ui32LastErrorTransactionId
int32_t fixedBitRatio[NI_MAX_GOP_NUM]
ni_custom_gop_params_t custom_gop_params
ni_event_handle_t thread_event_handle
ni_pthread_mutex_t * p_mutex
ni_device_handle_t device_handle
volatile uint64_t * plast_access_time
ni_encoder_cfg_params_t cfg_enc_params
int8_t customize_roi_qp_map[NI_CUSTOMIZE_ROI_QPOFFSET_LEVEL][NI_CUSTOMIZE_ROI_QP_NUM]
ni_ddr_priority_mode_t ddr_priority_mode
ni_decoder_input_params_t dec_input_params
Log entry header structure.
uint8_t timestamp[8]
Log entry information structure.
const uint8_t * start_ptr
uint64_t timestamp
bool wrap_around
const uint8_t * end_ptr
Log entry trailer structure.
ni_decoder_output_picture_size sOutputPictureSize
ni_decode_cropping_rectangle sCroppingRectable