libxcoder 5.8.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 <stddef.h>
60#include <stdint.h>
61#include <string.h>
62#include <stdio.h>
63#include <stdlib.h>
64#include <math.h>
65#ifdef __linux__
66#include <stdint.h>
67#include <poll.h>
68#include "ni_p2p_ioctl.h"
69#endif
70#include "inttypes.h"
71#include "ni_nvme.h"
72#include "ni_device_api.h"
73#include "ni_device_api_priv.h"
74#include "ni_util.h"
75#include "ni_lat_meas.h"
76#include "ni_rsrc_priv.h"
77#ifdef NI_HAVE_MCTF
78#include "mctf.h"
79#endif
80#if defined(__linux__) && defined(XCODER_ENABLE_CPU_AFFINITY)
81#include <numa.h>
82#endif
83
84//Map the gopPresetIdx to gopSize,
85//gopPresetIdx -1: Adaptive Gop, using the biggest gopsize 8
86//gopPresetIdx 0 : Custom Gop as defined by -xcoder-gop
87//g_map_preset_to_gopsize[lookAheadEnable][gopPresetIdx + 1];
88//for the not support gopPresetIdx value, such as gopPresetIdx == 2, set g_map_preset_to_gopsize to -1
89static 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},
90 {8, 0, -1, -1, -1, 2, 4, -1, -1, 8, 1, -1, -1, -1, -1, -1, -1}};
91#define MIN(x,y) (((x)>(y))?(y):(x))
92#define MAX(x,y) (((x)<(y))?(y):(x))
93#define HEVC_LEVEL_NUM 13
94#define H264_LEVEL_NUM 20
95#define AV1_LEVEL_NUM 14
96#define HIGH_TIER 1
97static const uint64_t max_sample_rate_second_h265[ HEVC_LEVEL_NUM ] =
98{
99 552960, 3686400, 7372800, 16588800, 33177600, 66846720, 133693440, 267386880,
100 534773760, 1069547520, 1069547520, 2139095040, 4278190080
101};
102static const uint64_t max_sample_rate_second_h264[ H264_LEVEL_NUM ] =
103{
104 (uint64_t)1485*256, (uint64_t)1485*256, (uint64_t)3000*256, (uint64_t)6000*256, (uint64_t)11880*256, (uint64_t)11880*256, (uint64_t)19800*256, (uint64_t)20250*256,
105 (uint64_t)40500*256, (uint64_t)108000*256, (uint64_t)216000*256, (uint64_t)245760*256, (uint64_t)245760*256,
106 (uint64_t)522240*256, (uint64_t)589824*256, (uint64_t)983040*256, (uint64_t)2073600*256,
107 (uint64_t)4177920*256, (uint64_t)8355840*256, (uint64_t)16711680*256
108};
109static const uint64_t max_sample_rate_second_av1[ AV1_LEVEL_NUM ] =
110{
111 5529600, 10454400, /*0, 0,*/ 24969600, 39938400, 77856768, 155713536,
112 273715200, 547430400, 1094860800, 1176502272, 1176502272, 2189721600, 4379443200, 4706009088
113};
114
115static const uint32_t max_pic_size_h265[ HEVC_LEVEL_NUM ] =
116{
117 36864, 122880, 245760, 552960, 983040, 2228224, 2228224, 8912896,
118 8912896, 8912896, 35651584, 35651584, 35651584
119};
120static const uint32_t max_pic_size_h264[ H264_LEVEL_NUM ] =
121{
122 99*256, 99*256, 396*256, 396*256, 396*256, 396*256, 792*256, 1620*256,
123 1620*256, 3600*256, 5120*256, 8192*256, 8192*256,
124 8704*256, 22080*256, 36864*256, 36864*256,
125 139264*256, 139264*256, 139264*256
126};
127static const uint32_t max_pic_size_av1[ AV1_LEVEL_NUM ] =
128{
129 147456, 278784, 665856, 1065024, 2359296, 2359296,
130 8912896, 8912896, 8912896, 8912896, 35651584, 35651584, 35651584, 35651584
131};
132
133static const uint32_t max_cpb_second_h265[ HEVC_LEVEL_NUM ] =
134{
135 350000, 1500000, 3000000, 6000000, 10000000, 12000000, 20000000,
136 25000000, 40000000, 60000000, 60000000, 120000000, 240000000
137};
138static const uint32_t max_cpb_hightier_second_h265[ HEVC_LEVEL_NUM ] =
139{
140 350000, 1500000, 3000000, 6000000, 10000000, 30000000, 50000000,
141 100000000, 160000000, 240000000, 240000000, 480000000, 800000000
142};
143static const uint32_t max_cpb_second_h264[ H264_LEVEL_NUM ] =
144{
145 175000, 350000, 500000, 1000000, 2000000, 2000000, 4000000, 4000000,
146 10000000, 14000000, 20000000, 25000000, 62500000,
147 62500000, 135000000, 240000000, 240000000,
148 240000000, 480000000, 800000000
149};
150static const uint32_t max_cpb_second_av1[ AV1_LEVEL_NUM ] =
151{
152 1500000, 3000000, 6000000, 10000000, 12000000, 20000000,
153 30000000, 40000000, 60000000, 60000000, 60000000, 100000000, 160000000, 160000000
154};
155static const uint32_t max_cpb_hightier_second_av1[ AV1_LEVEL_NUM ] =
156{
157 0, 0, 0, 0, 30000000, 50000000,
158 100000000, 160000000, 240000000, 240000000, 240000000, 480000000, 800000000, 800000000
159};
160static const uint32_t max_bitrate_h264[ H264_LEVEL_NUM ] =
161{
162 64000, 128000, 192000, 384000, 768000, 2000000, 4000000, 4000000,
163 10000000, 14000000, 20000000, 20000000, 50000000,
164 50000000, 135000000, 240000000, 240000000,
165 240000000, 480000000, 800000000
166};
167
168#define MAGIC_P2P_VALUE "p2p"
169#define AI_MODEL_TYPE_HVSPLUS_FILTER 3
170#define AI_MODEL_TYPE_USM_FILTER 4
171
172typedef enum _ni_t35_sei_mesg_type // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
173{
177
178typedef enum
179{
180 OPT_1 = 1, // is a combination of OPT_3 and OPT_2 in that order
181 OPT_2 = 2, // returns NI_RETCODE_FAILURE after NI_XCODER_FAILURES_MAX attempts, and LRETURNs for failures
182 OPT_3 = 3 // queries session statistics
184
185// Preset configuration lookup table
195
196static const PresetConfig preset_configs[] = {
197 [NI_VQ_VERYFAST] = {1, 0, GOP_PRESET_IDX_SP, 1000, 1, 0.0f, -1.0f},
198 [NI_VQ_FASTER] = {2, 0, GOP_PRESET_IDX_SP, 1000, 1, 0.0f, -1.0f},
199 [NI_VQ_FAST] = {3, 0, GOP_PRESET_IDX_SP, 1000, 1, 0.0f, -1.0f},
200 [NI_VQ_MEDIUM] = {1, 16, GOP_PRESET_IDX_DEFAULT, 3000, 0, 0.0f, 0.0f},
201 [NI_VQ_SLOW] = {2, 16, GOP_PRESET_IDX_DEFAULT, 3000, 0, 0.0f, 0.0f},
202 [NI_VQ_SLOWER] = {3, 16, GOP_PRESET_IDX_DEFAULT, 3000, 0, 0.0f, 0.0f},
203 [NI_VQ_VERYSLOW] = {3, 40, GOP_PRESET_IDX_DEFAULT, 3000, 0, 0.0f, 0.0f}
204};
205
206static uint8_t g_itu_t_t35_cc_sei_hdr_hevc[NI_CC_SEI_HDR_HEVC_LEN] = {
207 0x00, 0x00, 0x00, 0x01, // NAL start code 00 00 00 01
208 0x4e,
209 0x01, // nal_unit_header() {forbidden bit=0 nal_unit_type=39,
210 // nuh_layer_id=0 nuh_temporal_id_plus1=1)
211 0x04, // payloadType= 4 (user_data_registered_itu_t_t35)
212 0 + 11, // payLoadSize= ui16Len + 11; to be set (index 7)
213 0xb5, // itu_t_t35_country_code =181 (North America)
214 0x00,
215 0x31, // itu_t_t35_provider_code = 49
216 0x47, 0x41, 0x39,
217 0x34, // ATSC_user_identifier = "GA94"
218 0x03, // ATSC1_data_user_data_type_code=3
219 0 | 0xc0, // (ui16Len/3) | 0xc0 (to be set; index 16) (each CC character
220 //is 3 bytes)
221 0xFF // em_data = 255
222};
223
224static uint8_t g_itu_t_t35_hdr10p_sei_hdr_hevc[NI_HDR10P_SEI_HDR_HEVC_LEN] = {
225 0x00, 0x00, 0x00, 0x01, // NAL start code 00 00 00 01
226 0x4e,
227 0x01, // nal_unit_header() {forbidden bit=0 nal_unit_type=39,
228 // nuh_layer_id=0 nuh_temporal_id_plus1=1)
229 0x04, // payloadType= 4 (user_data_registered_itu_t_t35)
230 0x00, // payLoadSize; to be set (index 7)
231 0xb5, // u8 itu_t_t35_country_code =181 (North America)
232 //0x00,
233 //0x3c, // u16 itu_t_t35_provider_code = 0x003c
234 //0x00,
235 //0x01, // u16 itu_t_t35_provider_oriented_code = 0x0001
236 // payLoadSize count starts from itu_t_t35_provider_code and goes until
237 // and including trailer
238};
239
240static uint8_t g_itu_t_t35_cc_sei_hdr_h264[NI_CC_SEI_HDR_H264_LEN] = {
241 0x00, 0x00, 0x00, 0x01, // NAL start code 00 00 00 01
242 0x06, // nal_unit_header() {forbidden bit=0 nal_ref_idc=0, nal_unit_type=6
243 0x04, // payloadType= 4 (user_data_registered_itu_t_t35)
244 0 + 11, // payLoadSize= ui16Len + 11; to be set (index 6)
245 0xb5, // itu_t_t35_country_code =181 (North America)
246 0x00,
247 0x31, // itu_t_t35_provider_code = 49
248 0x47, 0x41, 0x39,
249 0x34, // ATSC_user_identifier = "GA94"
250 0x03, // ATSC1_data_user_data_type_code=3
251 0 | 0xc0, // (ui16Len/3) | 0xc0 (to be set; index 15) (each CC character
252 //is 3 bytes)
253 0xFF // em_data = 255
254};
255
256static uint8_t g_itu_t_t35_hdr10p_sei_hdr_h264[NI_HDR10P_SEI_HDR_H264_LEN] = {
257 0x00, 0x00, 0x00, 0x01, // NAL start code 00 00 00 01
258 0x06, // nal_unit_header() {forbidden bit=0 nal_ref_idc=0, nal_unit_type=6
259 0x04, // payloadType= 4 (user_data_registered_itu_t_t35)
260 0x00, // payLoadSize; to be set (index 6)
261 0xb5, // itu_t_t35_country_code =181 (North America)
262 //0x00,
263 //0x3c, // u16 itu_t_t35_provider_code = 0x003c
264 //0x00,
265 //0x01, // u16 itu_t_t35_provider_oriented_code = 0x0001
266 // payLoadSize count starts from itu_t_t35_provider_code and goes until
267 // and including trailer
268};
269
270static uint8_t g_itu_t_t35_cc_sei_hdr_av1[NI_CC_SEI_HDR_AV1_LEN] = {
271 0x2a, // OBU Header (Type: Metadata, Has Size: True)
272 0 + 11, // OBU Size (Metadata Type + T.35 Payload + Marker); to be set
273 0x04, // Metadata Type (METADATA_TYPE_ITUT_T35)
274 0xb5, // itu_t_t35_country_code = 181 (North America)
275 0x00, // itu_t_t35_provider_code (Terminal)
276 0x31, // itu_t_t35_provider_code = 49
277 0x47, // "G"
278 0x41, // "A"
279 0x39, // "9"
280 0x34, // "4" (ATSC_user_identifier)
281 0x03, // ATSC1_data_user_data_type_code = 3
282 0 | 0xc0, // (cc_count) | 0xc0; to be set
283 0xff // Marker bits / em_data
284};
285
286static uint8_t g_itu_t_t35_hdr10p_sei_hdr_av1[NI_HDR10P_SEI_HDR_AV1_LEN] = {
287 0x2a, // OBU Header (Type 5: Metadata, Has Size: 1)
288 0, // OBU Size (to be set: payload_bytes + 2)
289 0x04, // Metadata Type (METADATA_TYPE_ITUT_T35)
290 0xb5 // itu_t_t35_country_code = 181 (North America)
291};
292
293static uint8_t g_sei_trailer[NI_CC_SEI_TRAILER_LEN] = {
294 0xFF, // marker_bits = 255
295 0x80 // RBSP trailing bits - rbsp_stop_one_bit and 7 rbsp_alignment_zero_bit
296};
297
298#define NI_XCODER_FAILURES_MAX 25
299#define DP_IPC_PASSTHRU 0xFFFFFFFF
300
301#ifdef _WIN32
302#ifdef XCODER_SELF_KILL_ERR
303#undef XCODER_SELF_KILL_ERR
304#endif
305#endif
306
307#ifdef PRINT_FW_LOGS
308ni_retcode_t ni_device_get_and_print_firmware_logs(ni_session_context_t *p_ctx);
309#endif
310
311void SwapSWBytes(uint8_t *buf, uint32_t bytes)
312{
313 uint32_t i;
314 for (i = 0; i < bytes; i += 2)
315 {
316 uint8_t val = buf[i];
317 buf[i] = buf[i + 1];
318 buf[i + 1] = val;
319 }
320}
321
322void SwapSW16(uint16_t *buf, uint32_t bytes)
323{
324 uint32_t i, words = (bytes + 1) / 2;
325
326 for (i = 0; i < words; i += 2)
327 {
328 uint16_t val = buf[i];
329 buf[i] = buf[i + 1];
330 buf[i + 1] = val;
331 }
332}
333
334void SwapSW32(uint32_t *buf, uint32_t bytes)
335{
336 uint32_t i, words = (bytes + 3) / 4;
337 for (i = 0; i < words; i += 2)
338 {
339 uint32_t val = buf[i];
340 buf[i] = buf[i + 1];
341 buf[i + 1] = val;
342 }
343}
344
345void SwapSW64(uint64_t *buf, uint64_t bytes)
346{
347 uint64_t i, words = (bytes + 7) / 8;
348 for (i = 0; i < words; i += 2)
349 {
350 uint64_t val = buf[i];
351 buf[i] = buf[i + 1];
352 buf[i + 1] = val;
353 }
354}
355
356static void memcpyToPelByBits (uint8_t *dst_u8, uint8_t *src, int width, int height, int dst_stride, int src_stride, int srcValidBitsDepth)
357{
358 int i, j;
359 uint8_t bitsDepth = srcValidBitsDepth;
360 uint32_t mask = (1<<bitsDepth)-1;
361 uint16_t *dst = (uint16_t *)dst_u8;
362
363 //fast for byte write
364 if (bitsDepth == 8)
365 {
366 for (j = 0; j < height; j ++)
367 {
368 for (i = 0; i< width; i ++)
369 dst_u8[i] = src[i] & 0xff;
370
371 src += src_stride;
372 dst_u8 += dst_stride;
373 }
374 return;
375 }
376
377 //for arbitrary bits
378 for (j = 0; j < height; j ++)
379 {
380 uint8_t *src_line = src;
381 uint32_t cache = 0, cache_bits = 0;
382 for (i = 0; i< width; i ++)
383 {
384 while(cache_bits < bitsDepth)
385 {
386 cache |= ((*src_line++) << cache_bits);
387 cache_bits += 8;
388 }
389
390 if (cache_bits >= bitsDepth)
391 {
392 dst[i] = cache & mask;
393 cache >>= bitsDepth;
394 cache_bits -= bitsDepth;
395 }
396 }
397
398 src += src_stride;
399 dst += dst_stride;
400 }
401}
402
403/*
404static void write_(FILE *fp, uint8_t *data, int32_t width, int32_t height, int32_t stripe)
405{
406 int32_t i;
407
408 for (i = 0; i < height; i++)
409 {
410 if (fwrite(data, sizeof(uint8_t ), width, fp) < (size_t)width)
411 {
412 return;
413 }
414 data += stripe;
415 }
416}
417*/
418
419static void trace_recon_tile2raster_y(FILE *fRecon, uint8_t *mem, int width, int height,
420 int leftOffset, int topOffset,
421 int src_stride, int pixDepth, uint8_t *luma_mem_temp)
422{
423 (void)fRecon;
424 int i;
425 int write_data_len = 0;
426 int bytesPerPix = (pixDepth == 8 ? 1 : 2);
427 uint8_t *tmp_mem = (uint8_t *)malloc((size_t)bytesPerPix*src_stride);
428 int num_tiles = (leftOffset + width + 3) / 4 - leftOffset/4;
429 if(tmp_mem == NULL)
430 return;
431 mem += topOffset/4*4*src_stride + leftOffset/4*16*pixDepth/8;
432 for(i = topOffset/4*4; i < topOffset + height; i += 4) {
433 memcpyToPelByBits(tmp_mem, mem, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
434 if(i >= topOffset && i < topOffset + height){
435 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
436 memcpy(luma_mem_temp + write_data_len, tmp_mem + (ptrdiff_t)(leftOffset & 3) * bytesPerPix, (size_t)width * bytesPerPix);
437 write_data_len += width * bytesPerPix;
438 }
439 memcpyToPelByBits(tmp_mem, mem+4*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
440 if(i+1 >= topOffset && i+1 < topOffset + height)
441 {
442 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
443 memcpy(luma_mem_temp + write_data_len, tmp_mem + (ptrdiff_t)(leftOffset & 3) * bytesPerPix, (size_t)width * bytesPerPix);
444 write_data_len += width * bytesPerPix;
445 }
446 memcpyToPelByBits(tmp_mem, mem+8*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
447 if(i+2 >= topOffset && i+2 < topOffset + height)
448 {
449 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
450 memcpy(luma_mem_temp + write_data_len, tmp_mem + (ptrdiff_t)(leftOffset & 3) * bytesPerPix, (size_t)width * bytesPerPix);
451 write_data_len += width * bytesPerPix;
452 }
453 memcpyToPelByBits(tmp_mem, mem+12*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
454 if(i+3 >= topOffset && i+3 < topOffset + height)
455 {
456 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
457 memcpy(luma_mem_temp + write_data_len, tmp_mem + (ptrdiff_t)(leftOffset & 3) * bytesPerPix, (size_t)width * bytesPerPix);
458 write_data_len += width * bytesPerPix;
459 }
460 mem += (ptrdiff_t)4*src_stride;
461 }
462 free(tmp_mem);
463}
464
465static void trace_recon_tile2raster_uv(FILE *fRecon, uint8_t *mem_uv, int width, int height,
466 int leftOffset, int topOffset,
467 int src_stride, int pixDepth, uint8_t *ch_mem_temp)
468{
469 (void)fRecon;
470 int i, j, k;
471 int bytesPerPix = (pixDepth == 8 ? 1 : 2);
472 uint8_t *tmp_mem = (uint8_t *)malloc((size_t)bytesPerPix*src_stride*2);
473 int num_tiles = 2*((leftOffset + width + 3) / 4 - leftOffset/4);
474 if(tmp_mem == NULL)
475 return;
476 uint8_t *mem;
477 int uv;
478 int write_data_len = 0;
479 memset(tmp_mem, 0x00, (size_t)bytesPerPix * src_stride * 2);
480 for(uv = 0; uv <= 1; uv ++) {
481 mem = mem_uv + (ptrdiff_t)(topOffset/4)*8*src_stride + (ptrdiff_t)(leftOffset/4)*32*pixDepth/8;
482 for(i = topOffset/4*4; i < topOffset + height; i += 4) {
483 if(i >= topOffset && i < topOffset + height) {
484 memcpyToPelByBits(tmp_mem, mem, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
485 for(j = uv, k = 0; j < 4 * num_tiles; j += 2, k++) {
486 if(bytesPerPix == 1)
487 tmp_mem[k] = tmp_mem[j];
488 else
489 ((uint16_t*)tmp_mem)[k] = ((uint16_t*)tmp_mem)[j];
490 }
491 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
492 memcpy(ch_mem_temp + write_data_len, tmp_mem + (ptrdiff_t)(leftOffset & 3) * bytesPerPix, (size_t)width * bytesPerPix);
493 write_data_len += width * bytesPerPix;
494 }
495 if(i+1 >= topOffset && i+1 < topOffset + height) {
496 memcpyToPelByBits(tmp_mem, mem+4*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
497 for(j = uv, k = 0; j < 4 * num_tiles; j += 2, k++) {
498 if(bytesPerPix == 1)
499 tmp_mem[k] = tmp_mem[j];
500 else
501 ((uint16_t*)tmp_mem)[k] = ((uint16_t*)tmp_mem)[j];
502 }
503 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
504 memcpy(ch_mem_temp + write_data_len, tmp_mem + (ptrdiff_t)(leftOffset & 3) * bytesPerPix, (size_t)width * bytesPerPix);
505 write_data_len += width * bytesPerPix;
506 }
507 if(i+2 >= topOffset && i+2 < topOffset + height) {
508 memcpyToPelByBits(tmp_mem, mem+8*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
509 for(j = uv, k = 0; j < 4 * num_tiles; j += 2, k++) {
510 if(bytesPerPix == 1)
511 tmp_mem[k] = tmp_mem[j];
512 else
513 ((uint16_t*)tmp_mem)[k] = ((uint16_t*)tmp_mem)[j];
514 }
515 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
516 memcpy(ch_mem_temp + write_data_len, tmp_mem + (ptrdiff_t)(leftOffset & 3) * bytesPerPix, (size_t)width * bytesPerPix);
517 write_data_len += width * bytesPerPix;
518 }
519 memcpyToPelByBits(tmp_mem, mem+12*pixDepth/8, 4, num_tiles, 4, 16*pixDepth/8, pixDepth);
520 if(i+3 >= topOffset && i+3 < topOffset + height) {
521 for(j = uv, k = 0; j < 4 * num_tiles; j += 2, k++) {
522 if(bytesPerPix == 1)
523 tmp_mem[k] = tmp_mem[j];
524 else
525 ((uint16_t*)tmp_mem)[k] = ((uint16_t*)tmp_mem)[j];
526 }
527 // write_(fRecon, tmp_mem + (leftOffset & 3)*bytesPerPix, width*bytesPerPix, 1, src_stride);
528 memcpy(ch_mem_temp + write_data_len, tmp_mem + (ptrdiff_t)(leftOffset & 3) * bytesPerPix, (size_t)width * bytesPerPix);
529 write_data_len += width * bytesPerPix;
530 }
531 mem += (ptrdiff_t)8*src_stride;
532 }
533 }
534 free(tmp_mem);
535}
536
537static double calc_noise(uint8_t *p1, uint8_t *p2, int size)
538{
539 double sum;
540 double diff;
541 int i;
542
543 sum = 0;
544 for (i = 0; i < size; i++)
545 {
546 diff = p1[i] - p2[i];
547 sum += diff * diff;
548 }
549
550 return sum;
551}
552
553/*!*****************************************************************************
554 * \brief Download hw frames by HwDesc.
555 *
556 * \param
557 *
558 * \return 0 if successful, < 0 otherwise
559 ******************************************************************************/
560static int hwdl_frame(ni_session_context_t *p_ctx,
561 ni_session_data_io_t *p_session_data, ni_frame_t *p_src_frame,
562 int pixel_format)
563{
564 niFrameSurface1_t *src_surf = (niFrameSurface1_t *)(p_src_frame->p_data[3]);
565 int ret = 0;
566
567 ret = ni_frame_buffer_alloc_dl(&(p_session_data->data.frame),
568 src_surf->ui16width, src_surf->ui16height,
569 pixel_format);
570
571 if (ret != NI_RETCODE_SUCCESS)
572 {
574 }
575
576 p_ctx->is_auto_dl = false;
577 ret = ni_device_session_hwdl(p_ctx, p_session_data, src_surf);
578 if (ret <= 0)
579 {
580 ni_frame_buffer_free(&p_session_data->data.frame);
581 return ret;
582 }
583 return ret;
584}
585
587{
588 // char dump_file_tile[256];
589 // char dump_file_raster[256];
590 //FILE *fout_tile = NULL;
591 FILE *fout_raster = NULL;
592 // snprintf(dump_file_tile, sizeof(dump_file_tile), "output-%04ld-tile.yuv", (long)p_ctx->pkt_num - 1);
593 // snprintf(dump_file_raster, sizeof(dump_file_raster), "output-%04ld-raster.yuv", (long)p_ctx->pkt_num - 1);
594 // fout_tile = fopen(dump_file_tile, "wb");
595 // fout_raster = fopen(dump_file_raster, "wb");
596 // FILE *f_out = fopen("out.yuv", "a");
597 int bit_depth = (p_ctx->pixel_format == NI_PIX_FMT_YUV420P10LE || p_ctx->pixel_format == NI_PIX_FMT_P010LE) ? 10 : 8;
598
600
601 // only h.265 psnr_y is supported by HW
602 p_ctx->psnr_y = p_packet->psnr_y = (float)(p_meta->ui16psnr_y / 1000.0);
603
604 if (((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode != 3 &&
605 (p_meta->reconLumaSize != 0 || p_meta->reconChromaSize != 0))
606 {
607 uint32_t lum_sz = 0;
608 uint32_t chr_sz = 0;
609 uint8_t *luma_mem_temp = NULL;
610 uint8_t *ch_mem_temp = NULL;
611 int width = (int)p_ctx->actual_video_width;
612 int height = (int)p_ctx->active_video_height;//p_meta->reconLumaSize / p_meta->reconLumaWidth;
613
614 uint8_t *luma_mem = (uint8_t *)p_packet->p_data + p_packet->data_len - p_meta->reconChromaSize - p_meta->reconLumaSize;
615 uint8_t *ch_mem = (uint8_t *)p_packet->p_data + p_packet->data_len - p_meta->reconChromaSize;
616
617 int bit_scale = (p_ctx->pixel_format == NI_PIX_FMT_YUV420P10LE || p_ctx->pixel_format == NI_PIX_FMT_P010LE) ? 5 : 4;
618 lum_sz = (2 * p_meta->frameCropTopOffset + height + 3) / 4 * p_meta->reconLumaWidth * bit_scale;
619 chr_sz = (p_meta->frameCropTopOffset + height / 2 + 1) / 2 * p_meta->reconChromaWidth * bit_scale;
620 if (p_meta->reconLumaSize)
621 {
622 uint32_t luma_size = (bit_depth == 8) ? p_meta->reconLumaSize : p_meta->reconLumaSize * 2;
623 luma_mem_temp = (uint8_t *)malloc(luma_size);
624 memset(luma_mem_temp, 0x00, luma_size);
625 }
626 if (p_meta->reconChromaSize)
627 {
628 uint32_t ch_size = (bit_depth == 8) ? p_meta->reconChromaSize : p_meta->reconChromaSize * 2;
629 ch_mem_temp = (uint8_t *)malloc(ch_size);
630 memset(ch_mem_temp, 0x00, ch_size);
631 }
635 if (p_meta->reconLumaSize != 0)
636 {
637 SwapSWBytes(luma_mem, lum_sz);
638 SwapSW16((uint16_t *)luma_mem, lum_sz);
639 SwapSW32((uint32_t *)luma_mem, lum_sz);
640 SwapSW64((uint64_t *)luma_mem, lum_sz);
641 trace_recon_tile2raster_y (fout_raster, luma_mem, width, height,
642 2 * p_meta->frameCropLeftOffset, 2 * p_meta->frameCropTopOffset,
643 p_meta->reconLumaWidth, bit_depth, luma_mem_temp);
644 ni_log2(p_ctx, NI_LOG_DEBUG, "lum_sz %d reconLumaSize %d width %d reconLumaWidth %d\n",
645 lum_sz, p_meta->reconLumaSize, width, p_meta->reconLumaWidth);
646 // fflush(fout_raster);
647 }
648
649 if (p_meta->reconChromaSize != 0)
650 {
651 SwapSWBytes(ch_mem, chr_sz);
652 SwapSW16((uint16_t *)ch_mem, chr_sz);
653 SwapSW32((uint32_t *)ch_mem, chr_sz);
654 SwapSW64((uint64_t *)ch_mem, chr_sz);
655 trace_recon_tile2raster_uv(fout_raster, ch_mem, width / 2, height / 2,
657 p_meta->reconChromaWidth, bit_depth, ch_mem_temp);
658 ni_log2(p_ctx, NI_LOG_DEBUG, "chr_sz %d reconChromaSize %d reconChromaWidth %d\n",
659 chr_sz, p_meta->reconChromaSize, p_meta->reconChromaWidth);
660 // fflush(fout_raster);
661 }
662
663 // fwrite((uint8_t *)p_packet->p_data + sizeof(ni_metadata_enc_bstream_t) + (p_packet->data_len - p_meta->reconLumaSize - p_meta->reconChromaSize),
664 // p_meta->reconLumaSize + p_meta->reconChromaSize, 1, fout_tile);
665
669 if (((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode < 3)
670 {
671 do
672 {
673 int max;
674 double noise_y = 0.0, noise_u = 0.0, noise_v = 0.0, noise_yuv = 0.0;
675 double power_y = 0.0, power_u = 0.0, power_v = 0.0, power_yuv = 0.0;
676 double psnr_y = 0.0, psnr_u = 0.0, psnr_v = 0.0, psnr_yuv = 0.0;
677
679 // FILE *f_out_raster = (FILE *)fopen(dump_file_raster, "rb");
680 // fread(luma_mem_temp, width * height , 1, f_out_raster);
681 // fread(ch_mem_temp, width * height / 2, 1, f_out_raster);
682 // fflush(f_out_raster);
683 // fclose(f_out_raster);
684
685 max = (1 << 8) - 1;
686 power_y = 1.0 * max * max * width * height;
687 power_u = power_y / 4.0;
688 power_v = power_y / 4.0;
689 power_yuv = power_y * 3.0 / 2.0;
690
691 uint8_t *p_y_src_buf = NULL;
692 uint8_t *p_u_src_buf = NULL;
693 uint8_t *p_v_src_buf = NULL;
694 for (int i = 0; i < 120; i++)
695 {
696 if (p_ctx->input_frame_fifo[i].p_input_buffer != NULL &&
697 p_ctx->input_frame_fifo[i].pts == p_meta->frame_tstamp)
698 {
699 p_y_src_buf = p_ctx->input_frame_fifo[i].p_input_buffer;
700 p_u_src_buf = p_y_src_buf + (size_t)p_ctx->input_frame_fifo[i].video_width * p_ctx->input_frame_fifo[i].video_height;
701 p_v_src_buf = p_u_src_buf + (size_t)(p_ctx->input_frame_fifo[i].video_width / 2) * (p_ctx->input_frame_fifo[i].video_height / 2);
702
703 p_ctx->input_frame_fifo[i].usable = 1;
704 ni_log2(p_ctx, NI_LOG_DEBUG, "%s %d i %d pkt_num %ld frame_num %ld frame_tstamp %lld\n",
705 __FUNCTION__, __LINE__, i, p_ctx->pkt_num, p_ctx->frame_num, p_meta->frame_tstamp);
706 break;
707 }
708 }
709 if (p_y_src_buf != NULL)
710 {
711 if (p_meta->reconLumaSize != 0)
712 {
713 noise_y = calc_noise(p_y_src_buf, luma_mem_temp, width * height);
714 }
715 else if (p_meta->ui16psnr_y != 0)
716 {
717 noise_y = power_y / pow(10, p_ctx->psnr_y / 10); // This is used for calculation noise_yuv for psnr_yuv
718 }
719
720 if (p_meta->reconChromaSize != 0)
721 {
722 noise_u = calc_noise(p_u_src_buf, ch_mem_temp, (width / 2) * (height / 2));
723 noise_v = calc_noise(p_v_src_buf, ch_mem_temp + (ptrdiff_t)(width / 2) * (height / 2), (width / 2) * (height / 2));
724 }
725 noise_yuv = noise_y + noise_u + noise_v;
726
727 //This is for the case when encoding some very simple picture
728 //this case the quality is very good. sometimes the noise_y may be zero
729 noise_y = noise_y < 1 ? 1 : noise_y;
730 noise_u = noise_u < 1 ? 1 : noise_u;
731 noise_v = noise_v < 1 ? 1 : noise_v;
732 noise_yuv = noise_yuv < 1 ? 1 : noise_yuv;
733
734 if (p_meta->reconLumaSize != 0)
735 {
736 psnr_y = 10 * log10(power_y / noise_y);
737 }
738 else if (p_meta->ui16psnr_y != 0)
739 {
740 psnr_y = p_ctx->psnr_y;
741 }
742
743 if (p_meta->reconChromaSize != 0)
744 {
745 psnr_u = 10 * log10(power_u / noise_u);
746 psnr_v = 10 * log10(power_v / noise_v);
747 }
748 psnr_yuv = 10 * log10(power_yuv / noise_yuv);
749 p_ctx->psnr_y = p_packet->psnr_y = psnr_y;
750 p_ctx->psnr_u = p_packet->psnr_u = psnr_u;
751 p_ctx->psnr_v = p_packet->psnr_v = psnr_v;
752 p_ctx->average_psnr = p_packet->average_psnr = psnr_yuv;
753 }
754 } while(0);
755 }
756 else
757 {
758 // get recontructed frame here
759 // int h = 0;
760 // luma
761 // for (h = 0; h < height; h++)
762 // {
763 // fwrite(luma_mem_temp + (width * h), 1, width, f_out);
764 // }
765 //chroma
766 // for (h = 0; h < height; h++)
767 // {
768 // fwrite(ch_mem_temp + ((width / 2) * h), 1, width / 2, f_out);
769 // }
770 // fclose(f_out);
771 }
772
773 if (luma_mem_temp)
774 {
775 free(luma_mem_temp);
776 luma_mem_temp = NULL;
777 }
778 if (ch_mem_temp)
779 {
780 free(ch_mem_temp);
781 ch_mem_temp = NULL;
782 }
783 // fflush(fout_tile);
784 // fclose(fout_tile);
785 // fflush(fout_raster);
786 // fclose(fout_raster);
787 //}
788 }
789
790 if(p_meta->reconChromaSize == 0)
791 {
792 p_ctx->psnr_u = p_ctx->psnr_v = 0;
793 p_ctx->average_psnr = p_ctx->psnr_y;
794 }
795 if (p_meta->reconLumaSize == 0 && p_meta->ui16psnr_y == 0)
796 {
797 p_ctx->psnr_y = 0;
798 p_ctx->average_psnr = (p_ctx->psnr_u + p_ctx->psnr_v) / 2;
799 }
800
801
802 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",
803 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);
804
805 p_packet->data_len -= p_meta->reconLumaSize + p_meta->reconChromaSize;
806}
807
808/* Macro to read 2 consecutive bytes from buffer starting at byte_offset and combine them into a uint32_t (little-endian) */
809#define READ_U32_FROM_BUF_2BYTES(buf, byte_offset) \
810 ((uint32_t)(buf)[(byte_offset)] | \
811 ((uint32_t)(buf)[(byte_offset)+1] << 8))
812
813/* Macro to read 4 consecutive bytes from buffer starting at byte_offset and combine them into a uint32_t (little-endian) */
814#define READ_U32_FROM_BUF(buf, byte_offset) \
815 ((uint32_t)(buf)[(byte_offset)] | \
816 ((uint32_t)(buf)[(byte_offset)+1] << 8) | \
817 ((uint32_t)(buf)[(byte_offset)+2] << 16) | \
818 ((uint32_t)(buf)[(byte_offset)+3] << 24))
819
820static void parse_cu_info(ni_session_context_t *p_ctx, uint8_t *cuInfoBuf, ni_encoder_cu_info *pEncCuInfo)
821{
822 uint32_t data;
823
824 if (!p_ctx || !cuInfoBuf || !pEncCuInfo)
825 {
826 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n",
827 __func__);
828 return;
829 }
830
831 // AVC
833 {
834 pEncCuInfo->cuSize = 16;
835 pEncCuInfo->cuMode = (cuInfoBuf[AVC_MB_MODE_BYTE_OFFSET] >> AVC_MB_MODE_BIT_POSITION) & ((1 << AVC_MB_MODE_BITS) - 1);
836 data = READ_U32_FROM_BUF(cuInfoBuf, AVC_RDCOST_BYTE_OFFSET);
837 pEncCuInfo->cost = (data >> AVC_RDCOST_BIT_POSITION) & ((1 << AVC_RDCOST_BITS) - 1);
838 if (pEncCuInfo->cuMode == 1) // intra
840 else
842 }
843 // HEVC & AV1
844 else
845 {
846 uint8_t cuSizeId = ((cuInfoBuf[CU_SIZE_BYTE_OFFSET] >> CU_SIZE_BIT_POSITION) & ((1 << CU_SIZE_BITS) - 1));
847 pEncCuInfo->cuSize = 8 * (1 << (cuSizeId + 3));
848 pEncCuInfo->cuMode = (cuInfoBuf[CU_MODE_BYTE_OFFSET] >> CU_MODE_BIT_POSITION) & ((1 << CU_MODE_BITS) - 1);
849 data = READ_U32_FROM_BUF(cuInfoBuf, RDCOST_BYTE_OFFSET);
850 pEncCuInfo->cost = (data >> RDCOST_BIT_POSITION) & ((1 << RDCOST_BITS) - 1);
851 if (pEncCuInfo->cuMode == 1) // intra
853 else
855 }
856
857 // COMMON
859 pEncCuInfo->costOfOtherMode = (data >> RDCOST_OTHER_BIT_POSITION) & ((1 << RDCOST_OTHER_BITS) - 1);
860 data = READ_U32_FROM_BUF(cuInfoBuf, INTRACOST_BYTE_OFFSET);
861 pEncCuInfo->costIntraSatd = (data >> INTRACOST_BIT_POSITION) & ((1 << INTRACOST_BITS) - 1);
862 data = READ_U32_FROM_BUF(cuInfoBuf, INTERCOST_BYTE_OFFSET);
863 pEncCuInfo->costInterSatd = (data >> INTERCOST_BIT_POSITION) & ((1 << INTERCOST_BITS) - 1);
864 data = READ_U32_FROM_BUF_2BYTES(cuInfoBuf, QP_BYTE_OFFSET);
865 pEncCuInfo->qp = (data >> QP_BIT_POSITION) & ((1 << QP_BITS) - 1);
866}
867
868
869static void get_bitstream_features_from_cu_info(ni_session_context_t *p_ctx, ni_packet_t *p_packet)
870{
871 if (!p_ctx || !p_packet)
872 {
873 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n",
874 __func__);
875 return;
876 }
877
879 if (p_meta->cuInfoSize != 0)
880 {
881 // bitstream features related parameters
882 uint8_t max_qp = 0;
883 int total_cu_count = 0;
884 int analyzed_mbs = 0; // intra 16x16, intra 8x8, intra 4x4 and inter blocks
885 int num_intra_block_blocks = 0; // intra 4x4 and 8x8 blocks (counted in 4x4)
886 int num_intra_plane_blocks = 0; // intra 16x16 blocks (counted in 4x4)
887 uint64_t qp_sum = 0;
888 uint64_t inter_pred_L0_qp_sum = 0;
889 uint64_t intra_plane_qp_sum = 0;
890 uint64_t intra_block_qp_sum = 0;
891 int inter_pred_L0_count = 0;
892 //int inter_pred_L1_count = 0;
893 //int inter_pred_BI_count = 0;
894 ni_bitstream_features_t *bitstream_features = &p_packet->bitstream_features;
895
896 // CU info related parameters
897 ni_encoder_cu_info cuInfo = {0};
898 uint8_t *ctuOffset = (uint8_t *)p_packet->p_data + p_packet->data_len - p_meta->cuInfoSize;
899 uint8_t *cuData = ctuOffset + p_meta->cuInfoTableSize + p_meta->aqInfoSize;
900 uint32_t *ctuTable = (uint32_t *)ctuOffset;
901 uint8_t *cuInfoBuf;
902 int width = (int)p_ctx->actual_video_width;
903 int height = (int)p_ctx->active_video_height;
904 int ctu_per_row;
905 int ctu_per_column;
906 int iCtuX, iCtuY, nCu, iCu;
907 int iCtu = 0;
908
909 // AVC
911 {
912 ctu_per_row = (width + 16 - 1) / 16;
913 ctu_per_column = (height + 16 - 1) / 16;
914 }
915 // HEVC & AV1
916 else
917 {
918 ctu_per_row = (width + 64 - 1) / 64;
919 ctu_per_column = (height + 64 - 1) / 64;
920 }
921
922 // check encoding pass CU info
923 for (iCtuY = 0; iCtuY < ctu_per_column; iCtuY++)
924 {
925 for (iCtuX = 0; iCtuX < ctu_per_row; iCtuX++)
926 {
927 // get number of CUs in CTU
929 {
930 nCu = 1;
931 // set CU info buffer pointer to this MB
932 cuInfoBuf = cuData + (ptrdiff_t)iCtu * CU_INFO_OUTPUT_SIZE_V1;
933 }
934 else
935 {
936 nCu = (int)ctuTable[iCtu];
937 if (iCtu)
938 nCu -= (int)ctuTable[iCtu - 1];
939 // set CU info buffer pointer to this CTU
940 cuInfoBuf = cuData + (ptrdiff_t)(iCtu ? ctuTable[iCtu - 1] : 0) * CU_INFO_OUTPUT_SIZE_V1;
941 }
942
943 // check each inter CU's MV
944 for (iCu = 0; iCu < nCu; iCu++)
945 {
946 parse_cu_info(p_ctx, cuInfoBuf, &cuInfo);
947
948 total_cu_count++;
949 qp_sum += cuInfo.qp;
950 max_qp = cuInfo.qp > max_qp ? cuInfo.qp : max_qp;
951 //ni_log2(p_ctx, NI_LOG_TRACE, "mb %d (%d, %d) mb_qp %u\n", iCtuY * ctu_per_row + iCtuX, iCtuX, iCtuY, cuInfo.qp);
952
953 if (cuInfo.cuMode == 1) // intra
954 {
955 if (cuInfo.intraPartMode == 0) // Intra_2Nx2N (or 16x16 for AVC)
956 {
957 analyzed_mbs++;
958 num_intra_plane_blocks += (cuInfo.cuSize / 4) * (cuInfo.cuSize / 4);
959 intra_plane_qp_sum += 16ULL * cuInfo.qp;
960 }
961 else // Intra_NxN (or 8x8, 4x4 for AVC)
962 {
963 analyzed_mbs += 16;
964 num_intra_block_blocks += (cuInfo.cuSize / 4) * (cuInfo.cuSize / 4);
965 intra_block_qp_sum += 16ULL * cuInfo.qp;
966 }
967 //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",
968 // p_ctx->pkt_num, total_cu_count, cuInfo.cost, cuInfo.costOfOtherMode, cuInfo.costIntraSatd, cuInfo.costInterSatd, cuInfo.intraPartMode, analyzed_mbs);
969 }
970 else // inter
971 {
972 analyzed_mbs++;
973 if (cuInfo.interPredIdc == 0) // Inter_L0
974 {
975 inter_pred_L0_count += 16;
976 inter_pred_L0_qp_sum += 16ULL * cuInfo.qp;
977 }
978 else if (cuInfo.interPredIdc == 1) // Inter_L1
979 {
980 // backward prediction blocks not stored in bitstream_features
981 //inter_pred_L1_count += 16;
982 }
983 else // Inter_BI
984 {
985 // bi-prediction blocks not stored in bitstream_features
986 //inter_pred_BI_count += 16;
987 if (p_ctx->p_session_config)
988 {
990 int32_t gop_preset_index = api_param->cfg_enc_params.gop_preset_index;
991 // for low delay gop patterns, bi-prediction blocks are also forward prediction blocks
992 if (gop_preset_index == 3 || gop_preset_index == 7)
993 {
994 inter_pred_L0_count += 16;
995 inter_pred_L0_qp_sum += 16ULL * cuInfo.qp;
996 }
997 }
998 else
999 {
1000 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_session_config is null!\n",
1001 __func__);
1002 }
1003 }
1004 }
1005
1006 cuInfoBuf+=CU_INFO_OUTPUT_SIZE_V1;
1007 }
1008 // move forward CU info offset
1009 iCtu++;
1010 }
1011 }
1012
1013 bitstream_features->average_qp = (float)qp_sum / (float)total_cu_count;
1014 bitstream_features->initial_qp = p_meta->ppsInitQp;
1015 bitstream_features->max_qp = max_qp;
1016 bitstream_features->avg_forward_pred_block_qp = inter_pred_L0_count > 0 ? (float)inter_pred_L0_qp_sum / (float)inter_pred_L0_count : (float)max_qp;
1017 bitstream_features->analyzed_mbs = analyzed_mbs;
1018 bitstream_features->avg_intra_block_qp = num_intra_block_blocks > 0 ? (float)intra_block_qp_sum / (float)num_intra_block_blocks : (float)max_qp;
1019 bitstream_features->avg_intra_plane_qp = num_intra_plane_blocks > 0 ? (float)intra_plane_qp_sum / (float)num_intra_plane_blocks : (float)max_qp;
1020 bitstream_features->num_intra_block_blocks = num_intra_block_blocks;
1021 bitstream_features->num_intra_plane_blocks = num_intra_plane_blocks;
1022 bitstream_features->num_skip_blocks = (int)(p_meta->skipCu8Num * 4);
1023 bitstream_features->num_forward_pred_blocks = inter_pred_L0_count - bitstream_features->num_skip_blocks;
1024 //ni_log2(p_ctx, NI_LOG_TRACE, "total_qp %llu mb_cnt %d av_qp %.2f\n",
1025 // qp_sum, total_cu_count, p_packet->average_qp);
1026 }
1027}
1028
1029// Check for critical failures.
1030// Invalid parameters or resource busy do not account for failures that cause error count to be incremented so they can be retried indefinitely
1031static ni_retcode_t check_err_rc(
1032 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)
1033{
1034 ni_retcode_t retval = rc;
1035 ni_session_stats_t stat = {0};
1036 uint16_t ui16ErrorCount = 0;
1037 uint32_t ui32LastErrorStatus = 0;
1038
1039 if(opt == OPT_1 || opt == OPT_3)
1040 {
1041 retval = ni_query_session_stats(ctx, type, &stat, rc, opcode);
1042 ui16ErrorCount = stat.ui16ErrorCount;
1043 ui32LastErrorStatus = stat.ui32LastErrorStatus;
1044 }
1045
1046 if (retval != NI_RETCODE_SUCCESS)
1047 {
1048 ni_log2(ctx, NI_LOG_ERROR, "Query for statistics failed with %d!\n", retval);
1049#ifdef PRINT_FW_LOGS
1050 ni_device_get_and_print_firmware_logs(ctx);
1051#endif
1052 return NI_RETCODE_FAILURE;
1053 }
1054
1055 if(opt == OPT_1)
1056 {
1057 retval = ni_nvme_check_error_code((int)stat.ui32LastTransactionCompletionStatus, opcode, type, hw_id, inst_id);
1058
1059 if(!retval)
1060 retval = ni_nvme_check_error_code((int)ui32LastErrorStatus, opcode, type, hw_id, inst_id);
1061 }
1062 else if(opt == OPT_2){
1063 if(!stat_full){
1064 ni_log2(ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n", __func__);
1065#ifdef PRINT_FW_LOGS
1066 ni_device_get_and_print_firmware_logs(ctx);
1067#endif
1069 }
1070 retval = ni_nvme_check_error_code((int)stat_full->ui32LastTransactionCompletionStatus, opcode, type, hw_id, inst_id);
1071 ui16ErrorCount = stat_full->ui16ErrorCount;
1072 ui32LastErrorStatus = stat_full->ui32LastErrorStatus;
1073 /* re-query error status for transactionId 0xFFFF */
1074 if(stat_full->ui32LastErrorTransactionId == 0xFFFF &&
1075 ui16ErrorCount > 0 && !retval &&
1076 type == NI_DEVICE_TYPE_DECODER)
1077 {
1078 retval = ni_nvme_check_error_code((int)ui32LastErrorStatus, opcode, type, hw_id, inst_id);
1079 }
1080 }
1081 else if(opt == OPT_3)
1082 {
1083 retval = ni_nvme_check_error_code((int)stat.ui32LastTransactionCompletionStatus, opcode, type, hw_id, inst_id);
1084 }
1085
1086 if (retval)
1087 {
1088 ni_log2(ctx,
1090 "Persistent failures detected, %s() line-%d: session_no 0x%x "
1091 "sess_err_count %u inst_err_no %u\n",
1092 func, line, *(inst_id), ui16ErrorCount,
1093 ui32LastErrorStatus);
1094#ifdef PRINT_FW_LOGS
1095 ni_device_get_and_print_firmware_logs(ctx);
1096#endif
1097#ifdef XCODER_SELF_KILL_ERR
1098 if(opt != OPT_3)
1099 {
1100 kill(getpid(), SIGTERM);
1101 }
1102#endif
1103 }
1104
1105 return retval;
1106}
1107
1108//Following macros will only check for critical failures.
1109//After the macro runs, rc should contain the status of the last command sent
1110//For non-critical failures, it is assumed in the code that eventually after enough retries, a command will succeed.
1111//Invalid parameters or resource busy do not account for failures that cause error count to be incremented so they can be retried indefinitely
1112#define CHECK_ERR_RC(ctx, rc, info, opcode, type, hw_id, inst_id, opt) \
1113 { \
1114 (rc) = check_err_rc(ctx, rc, info, opcode, type, hw_id, inst_id, opt, __func__, __LINE__); \
1115 if((rc) && ((opt) != OPT_3)) LRETURN; \
1116 }
1117
1118#define CHECK_VPU_RECOVERY(ret) \
1119 { \
1120 if (NI_RETCODE_NVME_SC_VPU_RECOVERY == (ret)) \
1121 { \
1122 ni_log(NI_LOG_ERROR, "Error, vpu reset.\n"); \
1123 (ret) = NI_RETCODE_ERROR_VPU_RECOVERY; \
1124 LRETURN; \
1125 } \
1126 }
1127
1128// ctx->decoder_low_delay is used as condition wait timeout for both decoder
1129// and encoder send/recv multi-thread in low delay mode.
1130static void low_delay_wait(ni_session_context_t* p_ctx)
1131{
1132 const char *name = p_ctx->device_type == NI_DEVICE_TYPE_DECODER ? \
1133 "decoder" : "encoder";
1134 if (p_ctx->async_mode && p_ctx->decoder_low_delay > 0)
1135 {
1136 int ret;
1137 uint64_t abs_time_ns;
1138 struct timespec ts;
1139
1140 ni_log2(p_ctx, NI_LOG_DEBUG, "%s waiting for %s recv thread\n", __FUNCTION__, name);
1141
1142 abs_time_ns = ni_gettime_ns();
1143 abs_time_ns += p_ctx->decoder_low_delay * 1000000LL;
1144 ts.tv_sec = (time_t)(abs_time_ns / 1000000000LL);
1145 ts.tv_nsec = (long)(abs_time_ns % 1000000000LL);
1146
1148 while (p_ctx->low_delay_sync_flag)
1149 {
1150 // In case of dead lock on waiting for notification from recv thread.
1153 &p_ctx->low_delay_sync_mutex, &ts);
1155 if (ret == ETIMEDOUT)
1156 {
1157 p_ctx->low_delay_sync_flag = 0;
1158 }
1159 }
1161 }
1162}
1163
1164static void low_delay_signal(ni_session_context_t* p_ctx)
1165{
1166 const char *name = p_ctx->device_type == NI_DEVICE_TYPE_DECODER ? \
1167 "decoder" : "encoder";
1168 if (p_ctx->async_mode && p_ctx->decoder_low_delay > 0)
1169 {
1170 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: wake up %s send thread\n", __FUNCTION__, name);
1172 p_ctx->low_delay_sync_flag = 0;
1175 }
1176}
1177
1178static void query_sleep(ni_session_context_t* p_ctx)
1179{
1180 if (p_ctx->async_mode)
1181 {
1182 // To avoid IO spam on NP core from queries and high volumens on latency.
1186 }
1187}
1188
1189// create folder bearing the card name (nvmeX) if not existing
1190// start working inside this folder: nvmeX
1191// find the earliest saved and/or non-existing stream folder and use it as
1192// the pkt saving destination; at most 128 such folders to be checked/created;
1193// folder name is in the format of: streamY, where Y is [1, 128]
1194static void decoder_dump_dir_open(ni_session_context_t *p_ctx)
1195{
1196#ifdef _WIN32
1197#elif __linux__ || __APPLE__
1198 FILE *fp = NULL;
1199 char dir_name[128] = {0};
1200 char file_name[512] = {0};
1201 ni_device_context_t *p_device_context;
1202 DIR *dir;
1203 struct dirent *stream_folder;
1204 int curr_stream_idx = 0;
1205 int earliest_stream_idx = 0;
1206 int max_exist_idx = 0;
1207 int32_t tmp_val;
1208 time_t earliest_time = 0;
1209 struct stat file_stat;
1210
1211 p_device_context =
1213 if (!p_device_context)
1214 {
1215 ni_log2(p_ctx, NI_LOG_ERROR, "Error retrieve device context for decoder guid %d\n",
1216 p_ctx->hw_id);
1217 return;
1218 }
1219
1220 flock(p_device_context->lock, LOCK_EX);
1221
1222 ni_strcpy(dir_name, sizeof(dir_name), &p_ctx->dev_xcoder_name[5]);
1223 if (0 != access(dir_name, F_OK))
1224 {
1225 if (0 != mkdir(dir_name, S_IRWXU | S_IRWXG | S_IRWXO))
1226 {
1227 ni_log2(p_ctx, NI_LOG_ERROR, "Error create folder %s, errno %d\n", dir_name,
1228 NI_ERRNO);
1229 } else
1230 {
1231 ni_log2(p_ctx, NI_LOG_DEBUG, "Created pkt folder for: %s\n", dir_name);
1232 }
1233 }
1234
1235 dir = opendir(dir_name);
1236 if (NULL == dir)
1237 {
1238 ni_log2(p_ctx, NI_LOG_ERROR, "Error %d: failed to open directory %s\n",
1239 NI_ERRNO, dir_name);
1240 } else
1241 {
1242 // have a quick first pass of streamY folders, and if existing Y < 128,
1243 // create a new folder Y+1 directly without checking existing ones'
1244 // content
1245 while ((stream_folder = readdir(dir))) // NOLINT(concurrency-mt-unsafe) - thread-local dir handle, no shared DIR*
1246 {
1247 if (!strncmp(stream_folder->d_name, "stream", strlen("stream")))
1248 {
1249 if (ni_strtoi(&(stream_folder->d_name[strlen("stream")]),
1250 &tmp_val) != NI_RETCODE_SUCCESS)
1251 {
1252 ni_log2(p_ctx, NI_LOG_ERROR,
1253 "ERROR: %s(): invalid stream index '%s'\n",
1254 __func__, stream_folder->d_name);
1255 continue;
1256 }
1257 curr_stream_idx = (int)tmp_val;
1258 if (curr_stream_idx > 0)
1259 {
1260 if (curr_stream_idx > max_exist_idx)
1261 {
1262 max_exist_idx = curr_stream_idx;
1263 }
1264 if (NI_MAX_CONTEXTS_PER_HW_INSTANCE == curr_stream_idx)
1265 {
1266 break;
1267 }
1268 }
1269 }
1270 }
1271
1272 // if less than 128 streams created then create a new one, otherwise have
1273 // to pick the stream folder that has the earliest modified file which
1274 // is most likely done by finished session.
1275 if (max_exist_idx < NI_MAX_CONTEXTS_PER_HW_INSTANCE)
1276 {
1277 curr_stream_idx = max_exist_idx + 1;
1278 } else
1279 {
1280 rewinddir(dir);
1281 while ((stream_folder = readdir(dir))) // NOLINT(concurrency-mt-unsafe) - thread-local dir handle, no shared DIR*
1282 {
1283 // go through each of these streamY folders and get modified
1284 // time of the first pkt-* file to simplify the searching
1285 if (!strncmp(stream_folder->d_name, "stream", strlen("stream")))
1286 {
1287 (void)snprintf(file_name, sizeof(file_name), "%s/%s/pkt-0001.bin",
1288 dir_name, stream_folder->d_name);
1289
1290 if (ni_strtoi(&(stream_folder->d_name[strlen("stream")]),
1291 &tmp_val) != NI_RETCODE_SUCCESS)
1292 {
1293 ni_log2(p_ctx, NI_LOG_ERROR,
1294 "ERROR: %s(): invalid stream index '%s'\n",
1295 __func__, stream_folder->d_name);
1296 continue;
1297 }
1298 curr_stream_idx = (int)tmp_val;
1299
1300 if (curr_stream_idx > 0 && 0 == access(file_name, F_OK))
1301 {
1302 // just take pkt-0001 file timestamp to simplify search
1303 if (stat(file_name, &file_stat))
1304 {
1305 ni_log2(p_ctx, NI_LOG_ERROR, "Error %d: failed to stat file %s\n",
1306 NI_ERRNO,
1307 file_name);
1308 } else
1309 {
1310 if (0 == earliest_stream_idx ||
1311 file_stat.st_mtime < earliest_time)
1312 {
1313 earliest_stream_idx = curr_stream_idx;
1314 earliest_time = file_stat.st_mtime;
1315 }
1316 }
1317 } // check first file in streamX
1318 } // go through each streamX folder
1319 } // read all files in nvmeY
1320
1321 curr_stream_idx = earliest_stream_idx;
1322
1323 // set the access/modified time of chosen pkt file to NOW so its
1324 // stream folder won't be taken by other sessions.
1325 (void)snprintf(file_name, sizeof(file_name), "%s/stream%03d/pkt-0001.bin",
1326 dir_name, curr_stream_idx);
1327 if (utime(file_name, NULL))
1328 {
1329 ni_log2(p_ctx, NI_LOG_ERROR, "Error utime %s\n", file_name);
1330 }
1331 } // 128 streams in nvmeY already
1332 closedir(dir);
1333 }
1334
1335 (void)snprintf(p_ctx->stream_dir_name, sizeof(p_ctx->stream_dir_name),
1336 "%s/stream%03d", dir_name, curr_stream_idx);
1337
1338 if (0 != access(p_ctx->stream_dir_name, F_OK))
1339 {
1340 if (0 != mkdir(p_ctx->stream_dir_name, S_IRWXU | S_IRWXG | S_IRWXO))
1341 {
1342 ni_log2(p_ctx, NI_LOG_ERROR, "Error create stream folder %s, errno %d\n",
1343 p_ctx->stream_dir_name, NI_ERRNO);
1344 } else
1345 {
1346 ni_log2(p_ctx, NI_LOG_DEBUG, "Created stream sub folder: %s\n",
1347 p_ctx->stream_dir_name);
1348 }
1349 } else
1350 {
1351 ni_log2(p_ctx, NI_LOG_DEBUG, "Reusing stream sub folder: %s\n",
1352 p_ctx->stream_dir_name);
1353 }
1354
1355 flock(p_device_context->lock, LOCK_UN);
1356 ni_rsrc_free_device_context(p_device_context);
1357
1358 (void)snprintf(file_name, sizeof(file_name), "%s/process_session_id.txt",
1359 p_ctx->stream_dir_name);
1360
1361 ni_fopen(&fp, file_name, "wb");
1362 if (fp)
1363 {
1364 char number[64] = {'\0'};
1365 ni_log2(p_ctx, NI_LOG_DEBUG, "Decoder pkt dump log created: %s\n", file_name);
1366 (void)snprintf(number, sizeof(number), "proc id: %ld\nsession id: %u\n",
1367 (long)getpid(), p_ctx->session_id);
1368 (void)fwrite(number, strlen(number), 1, fp);
1369 (void)fclose(fp);
1370 } else
1371 {
1372 ni_log2(p_ctx, NI_LOG_ERROR, "Error create decoder pkt dump log: %s\n", file_name);
1373 }
1374#endif
1375}
1376
1377#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OPEN_HARMONY__) && !defined(_ANDROID)
1378#define MAX_BDF_LEN 16
1379
1380// dev_name pattern: nvmeXnY
1381// pci_addr pattern: dddd:bb:dd.f
1382static int find_pci_address(const char *dev_name, char *pci_addr) {
1383 char sys_block_path[256];
1384
1385 (void)snprintf(sys_block_path, sizeof(sys_block_path), "/sys/class/block/%s/device", dev_name);
1386
1387 char *real_sysfs_path = realpath(sys_block_path, NULL);
1388 if (!real_sysfs_path) {
1389 perror("realpath failed");
1390 return -1;
1391 }
1392
1393 // Walk backward in the resolved path to find a segment that matches PCI BDF format
1394 char *p = real_sysfs_path + strlen(real_sysfs_path);
1395
1396 while (p > real_sysfs_path) {
1397 p = strrchr(real_sysfs_path, '/');
1398 if (!p) break;
1399
1400 char segment[MAX_BDF_LEN];
1401 ni_strncpy(segment, MAX_BDF_LEN, p + 1, (MAX_BDF_LEN-1));
1402 segment[MAX_BDF_LEN - 1] = '\0';
1403
1404 unsigned domain, bus, dev, func;
1405 if (sscanf(segment, "%x:%x:%x.%x", &domain, &bus, &dev, &func) == 4) { // NOLINT(cert-err34-c) - return value checked
1406 ni_strncpy(pci_addr, MAX_BDF_LEN, segment, MAX_BDF_LEN - 1);
1407 pci_addr[MAX_BDF_LEN - 1] = '\0';
1408 free(real_sysfs_path);
1409 return 0;
1410 }
1411
1412 *p = '\0'; // truncate path to move to the previous segment
1413 }
1414
1415 free(real_sysfs_path);
1416 return -1;
1417}
1418
1419// open netint p2p driver and fill the pcie address to p_ctx
1420static ni_retcode_t p2p_fill_pcie_address(ni_session_context_t *p_ctx)
1421{
1422#if defined(_WIN32) || defined(__APPLE__) || defined(__OPEN_HARMONY__)
1423 (void)p_ctx;
1424 return NI_RETCODE_FAILURE;
1425#else
1426 int ret = 0;
1427 char pci_addr[16];
1428 struct stat bstat;
1429 char *p_dev;
1430 char *dom, *bus, *dev, *fnc;
1431#ifdef _ANDROID
1432 char syspath[256];
1433 FILE *fp;
1434#endif
1435
1436 if(!p_ctx)
1437 {
1438 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() parameter is NULL\n",__func__);
1439 return NI_RETCODE_FAILURE;
1440 }
1441
1442 p_ctx->netint_fd = open("/dev/netint", O_RDWR);
1443 if (p_ctx->netint_fd < 0)
1444 {
1445 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Can't open device /dev/netint\n");
1446 return NI_RETCODE_FAILURE;
1447 }
1448
1449 p_dev = &p_ctx->dev_xcoder_name[0];
1450 if (stat(p_dev, &bstat) < 0)
1451 {
1452 ni_log2(p_ctx, NI_LOG_ERROR, "failed to get stat of file %s\n", p_dev);
1453 return NI_RETCODE_FAILURE;
1454 }
1455
1456 if ((bstat.st_mode & S_IFMT) != S_IFBLK)
1457 {
1458 ni_log2(p_ctx, NI_LOG_ERROR, "%s is not a block device\n", p_dev);
1459 return NI_RETCODE_FAILURE;
1460 }
1461
1462#ifdef _ANDROID
1463 ret = snprintf(syspath, sizeof(syspath) - 1,
1464 "/sys/block/%s/device/address",
1465 p_dev + 5);
1466 syspath[ret] = '\0';
1467
1468 FILE *fp = NULL;
1469 ni_fopen(&fp, syspath, "r");
1470 if (fp == NULL)
1471 {
1472 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read address\n");
1473 return NI_RETCODE_FAILURE;
1474 }
1475
1476 if (fgets(pci_addr, sizeof(pci_addr), fp) == NULL)
1477 {
1478 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read line from address\n");
1479 (void)fclose(fp);
1480 return NI_RETCODE_FAILURE;
1481 }
1482
1483 (void)fclose(fp);
1484#else
1485 ret = find_pci_address(p_dev + 5, pci_addr);
1486 if (ret != 0)
1487 {
1488 return NI_RETCODE_FAILURE;
1489 }
1490#endif
1491
1492 // pci_addr pattern: 0000:04:00.0
1493 ni_log2(p_ctx, NI_LOG_INFO, "PCI address string = %12.12s\n", pci_addr);
1494
1495 errno = 0;
1496 p_ctx->domain = strtoul(pci_addr, &dom, 16);
1497 if (errno < 0)
1498 {
1499 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read PCI domain\n");
1500 return NI_RETCODE_FAILURE;
1501 }
1502
1503 errno = 0;
1504 p_ctx->bus = strtoul(dom + 1, &bus, 16);
1505 if (errno < 0)
1506 {
1507 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read PCI bus\n");
1508 return NI_RETCODE_FAILURE;
1509 }
1510
1511 errno = 0;
1512 p_ctx->dev = strtoul(bus + 1, &dev, 16);
1513
1514 if (errno < 0)
1515 {
1516 ni_log2(p_ctx, NI_LOG_ERROR, "Failed to read PCI device\n");
1517 return NI_RETCODE_FAILURE;
1518 }
1519
1520 errno = 0;
1521 p_ctx->fn = strtoul(dev + 1, &fnc, 16);
1522
1523 if (errno < 0)
1524 {
1525 ni_log2(p_ctx, NI_LOG_ERROR, "Falied to read PCI function\n");
1526 return NI_RETCODE_FAILURE;
1527 }
1528
1529 ni_log2(p_ctx, NI_LOG_DEBUG, "PCI address parsed = %04x:%02x:%02x.%x\n",
1530 p_ctx->domain, p_ctx->bus, p_ctx->dev, p_ctx->fn);
1531
1532 return NI_RETCODE_SUCCESS;
1533#endif
1534}
1535#endif
1536
1537#if __linux__ || __APPLE__
1538#if !defined(_ANDROID) && !defined(__OPENHARMONY__)
1539#ifndef DISABLE_BACKTRACE_PRINT
1540void ni_print_backtrace() {
1541 void* callstack[128];
1542 int frames = backtrace(callstack, 128);
1543 char** strs = backtrace_symbols(callstack, frames);
1544
1545 ni_log(NI_LOG_ERROR, "Call stack:\n");
1546 for (int i = 0; i < frames; ++i) {
1547 ni_log(NI_LOG_ERROR, "%s\n", strs[i]);
1548 }
1549
1550 free((void *)strs);
1551}
1552#endif
1553#endif
1554#endif
1555
1556/*!******************************************************************************
1557 * \brief Open a xcoder decoder instance
1558 *
1559 * \param
1560 *
1561 * \return
1562*******************************************************************************/
1564{
1566 ni_xcoder_params_t *p_param = NULL;
1567 void* p_buffer = NULL;
1568 uint32_t ui32LBA = 0;
1569 char fmt_fw_api_ver1[5], fmt_fw_api_ver2[5];
1570
1571 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
1572
1573 if (!p_ctx)
1574 {
1575 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n",
1576 __func__);
1577 retval = NI_RETCODE_INVALID_PARAM;
1578 LRETURN;
1579 }
1580
1581 if (p_ctx->p_session_config)
1582 {
1583 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
1584 ni_params_print(p_param);
1585
1586 // Select the CPU based on the NUMA node.
1587 if (p_param->enableCpuAffinity)
1588 {
1589#if defined(__linux__) && defined(XCODER_ENABLE_CPU_AFFINITY)
1590 retval = ni_set_cpu_affinity(p_ctx);
1591 if (NI_RETCODE_SUCCESS != retval)
1592 {
1593 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ni_set_cpu_affinity failed, ret=%d\n",
1594 __func__, retval);
1595 LRETURN;
1596 }
1597#else
1598 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): not support enableCpuAffinity parameter, "
1599 "enable with [./build.sh -c] on linux\n", __func__);
1600#endif
1601 }
1602 }
1603
1604 //Create the session if the create session flag is set
1605 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
1606 {
1608 p_ctx->pts_table = NULL;
1609 p_ctx->dts_queue = NULL;
1610 p_ctx->p_leftover = NULL;
1611 p_ctx->buffer_pool = NULL;
1612 p_ctx->dec_fme_buf_pool = NULL;
1613 p_ctx->prev_size = 0;
1614 p_ctx->sent_size = 0;
1615 p_ctx->status = 0;
1616 p_ctx->key_frame_type = 0;
1617 p_ctx->ready_to_close = 0;
1618 p_ctx->max_retry_fail_count[0] = p_ctx->max_retry_fail_count[1] = 0;
1619 p_ctx->rc_error_count = 0;
1620 p_ctx->frame_num = 0;
1621 p_ctx->pkt_num = 0;
1622 p_ctx->pkt_index = 0;
1623 p_ctx->session_timestamp = 0;
1624 p_ctx->is_dec_pkt_512_aligned = 0;
1625 p_ctx->p_all_zero_buf = NULL;
1626 p_ctx->last_pkt_pos = 0;
1627 p_ctx->last_frame_offset = 0;
1628 p_ctx->last_frame_dropped = 0;
1630 memset((void *)p_ctx->pkt_custom_sei_set, 0, NI_FIFO_SZ * sizeof(ni_custom_sei_set_t *));
1631
1632 //malloc zero data buffer
1633 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
1635 {
1636 ni_log2(p_ctx, NI_LOG_ERROR,
1637 "ERROR %d: %s() alloc decoder all zero buffer failed\n",
1638 NI_ERRNO, __func__);
1640 LRETURN;
1641 }
1642 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
1643
1644 //malloc data buffer
1645 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
1646 {
1647 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
1648 NI_ERRNO, __func__);
1651 LRETURN;
1652 }
1653 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
1654
1655 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
1656 //In case we can open sesison, the session id would become valid.
1657 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
1658 (uint16_t)NI_INVALID_SESSION_ID;
1659
1660 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
1661 ui32LBA = OPEN_SESSION_CODEC(NI_DEVICE_TYPE_DECODER, ni_htonl(p_ctx->codec_format), p_ctx->hw_action);
1662 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
1663 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
1664 if (retval != NI_RETCODE_SUCCESS)
1665 {
1666 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR ni_nvme_send_read_cmd\n");
1667 LRETURN;
1668 }
1669 //Open will return a session status structure with a valid session id if it worked.
1670 //Otherwise the invalid session id set before the open command will stay
1671 p_ctx->session_id = ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
1672 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
1673 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
1674 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
1675 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
1676 {
1677 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_ctx->device_handle=0x%" PRIx64 ", "
1678 "p_ctx->hw_id=%d, p_ctx->session_id=%d\n", __func__,
1679 (int64_t)p_ctx->device_handle, p_ctx->hw_id, p_ctx->session_id);
1681 LRETURN;
1682 }
1683 ni_log2(p_ctx, NI_LOG_DEBUG, "Decoder open session ID:0x%x, timestamp:%" PRIu64 "\n",
1684 p_ctx->session_id, p_ctx->session_timestamp);
1685
1686 //Send keep alive timeout Info
1687 uint64_t keep_alive_timeout =
1688 (uint64_t)p_ctx->keep_alive_timeout * 1000000; //send us to FW
1689 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
1690 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
1691 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
1692 keep_alive_timeout);
1694 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
1695 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
1697 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
1698 CHECK_VPU_RECOVERY(retval);
1699
1700 if (NI_RETCODE_SUCCESS != retval)
1701 {
1702 ni_log2(p_ctx, NI_LOG_ERROR,
1703 "ERROR %s(): nvme write keep_alive_timeout command "
1704 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
1705 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
1707 LRETURN;
1708 }
1709
1710 // Send SW version to FW if FW API version is >= 6.2
1712 "62") >= 0)
1713 {
1714 // Send SW version to session manager
1715 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
1716 memcpy(p_buffer, NI_XCODER_REVISION, sizeof(uint64_t));
1718 ni_fmt_fw_api_ver_str((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], &fmt_fw_api_ver2[0]);
1719 ni_log2(p_ctx, NI_LOG_DEBUG, "%s libxcoder FW API ver %s, FW FW API ver %s\n",
1720 __func__, fmt_fw_api_ver1, fmt_fw_api_ver2);
1721 ui32LBA = CONFIG_SESSION_SWVersion_W(p_ctx->session_id);
1722 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
1723 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
1724 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
1725 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
1726 CHECK_VPU_RECOVERY(retval);
1727
1728 if (NI_RETCODE_SUCCESS != retval)
1729 {
1730 ni_log2(p_ctx, NI_LOG_ERROR,
1731 "ERROR %s(): nvme write sw_version command "
1732 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
1733 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
1735 LRETURN;
1736 }
1737 }
1738
1739 //VP9 requires a scaler session to be opened internally and attached as
1740 //well
1741 if(p_ctx->codec_format == NI_CODEC_FORMAT_VP9)
1742 {
1743 ni_log2(p_ctx, NI_LOG_DEBUG, "Adding scaling session to Vp9 decoder\n");
1744 ui32LBA = OPEN_ADD_CODEC(NI_DEVICE_TYPE_SCALER, ni_htonl(NI_SCALER_OPCODE_SCALE), ni_htons(p_ctx->session_id));
1745 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
1746 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
1747
1748 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_open,
1749 p_ctx->device_type, p_ctx->hw_id,
1750 &(p_ctx->session_id), OPT_1);
1751 if (NI_RETCODE_SUCCESS != retval)
1752 {
1753 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR couldn't add vp9 scaler to decoding session\n");
1754 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s():p_ctx->device_handle=0x%" PRIx64 ", "
1755 "p_ctx->hw_id=%d, p_ctx->session_id=%d\n", __func__,
1756 (int64_t)p_ctx->device_handle,p_ctx->hw_id, p_ctx->session_id);
1757 ni_decoder_session_close(p_ctx, 0);
1758 LRETURN;
1759 }
1760 }
1761
1762 ni_log2(p_ctx, NI_LOG_DEBUG,
1763 "%s(): p_ctx->device_handle=0x%" PRIx64 ", p_ctx->hw_id=%d, "
1764 "p_ctx->session_id=%d\n",
1765 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
1766 p_ctx->session_id);
1767 }
1768
1769 //start dec config
1770 retval = ni_config_instance_set_decoder_params(p_ctx, 0);
1771 if (NI_RETCODE_SUCCESS != retval)
1772 {
1773 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);
1774 //ni_decoder_session_close(p_ctx, 0); //close happens on above
1776 LRETURN;
1777 }
1778 //end dec config
1779
1780 // init for frame pts calculation
1781 p_ctx->is_first_frame = 1;
1782 p_ctx->last_pts = NI_NOPTS_VALUE;
1783 p_ctx->last_dts = NI_NOPTS_VALUE;
1784 p_ctx->last_dts_interval = 0;
1785 p_ctx->last_pts_interval = 0;
1786 p_ctx->pts_correction_last_dts = INT64_MIN;
1787 p_ctx->pts_correction_last_pts = INT64_MIN;
1788
1789 //p_ctx->p_leftover = malloc(NI_MAX_PACKET_SZ * 2);
1790 p_ctx->p_leftover = malloc((size_t)p_ctx->max_nvme_io_size * 2);
1791 if (!p_ctx->p_leftover)
1792 {
1793 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Cannot allocate leftover buffer.\n",
1794 __func__);
1796 //ni_decoder_session_close(p_ctx, 0);
1797 LRETURN;
1798 }
1799
1800 ni_timestamp_init(p_ctx, &p_ctx->pts_table, "dec_pts");
1801 ni_timestamp_init(p_ctx, &p_ctx->dts_queue, "dec_dts");
1802
1803 if (p_param && p_param->ddr_priority_mode > NI_DDR_PRIORITY_NONE)
1804 {
1805 retval = ni_device_set_ddr_configuration(p_ctx, p_param->ddr_priority_mode);
1806 if (NI_RETCODE_SUCCESS != retval)
1807 {
1808 char errmsg[NI_ERRNO_LEN] = {0};
1810 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ddr priority setting failure for %s\n",
1811 __func__, errmsg);
1812 LRETURN;
1813 }
1814 }
1815
1816 if (p_ctx->force_low_delay)
1817 {
1820 "6r3") < 0)
1821 {
1822 p_ctx->force_low_delay = false; // forceLowDelay not available for fw < 6r3
1823 ni_log2(p_ctx, NI_LOG_INFO, "Warn %s(): forceLowDelay is not available for fw < 6r3\n",
1824 __func__);
1825 }
1826 }
1827
1828 p_ctx->active_video_width = 0;
1829 p_ctx->active_video_height = 0;
1830 p_ctx->actual_video_width = 0;
1831 p_ctx->pixel_format_changed = 0;
1832
1833 ni_log2(p_ctx, NI_LOG_DEBUG,
1834 "%s(): p_ctx->device_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
1835 "p_ctx->session_id=%d\n",
1836 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
1837 p_ctx->session_id);
1838
1839 if (p_param && p_param->dec_input_params.nb_save_pkt)
1840 {
1841 decoder_dump_dir_open(p_ctx);
1842 }
1843
1844#ifdef XCODER_DUMP_DATA
1845 char dir_name[256] = {0};
1846
1847 (void)snprintf(dir_name, sizeof(dir_name), "%ld-%u-dec-fme", (long)getpid(),
1848 p_ctx->session_id);
1849 DIR *dir = opendir(dir_name);
1850 if (!dir && ENOENT == NI_ERRNO)
1851 {
1852 mkdir(dir_name, S_IRWXU | S_IRWXG | S_IRWXO);
1853 ni_log2(p_ctx, NI_LOG_DEBUG, "Decoder frame dump dir created: %s\n", dir_name);
1854 }
1855 if(dir){
1856 closedir(dir);
1857 }
1858#endif
1859
1860END:
1861
1862 ni_aligned_free(p_buffer);
1863 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
1864
1865 return retval;
1866}
1867
1868/*!******************************************************************************
1869 * \brief send a keep alive message to firmware
1870 *
1871 * \param
1872 *
1873 * \return
1874 *******************************************************************************/
1875ni_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)
1876{
1877 ni_retcode_t retval;
1878 uint32_t ui32LBA = 0;
1879
1880 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
1881 if (NI_INVALID_SESSION_ID == session_id)
1882 {
1883 ni_log(NI_LOG_ERROR, "ERROR: %s(): Invalid session ID!, return\n",
1884 __func__);
1886 LRETURN;
1887 }
1888
1889 if (NI_INVALID_DEVICE_HANDLE == device_handle)
1890 {
1891 ni_log(NI_LOG_ERROR, "ERROR: %s(): xcoder instance id < 0, return\n",
1892 __func__);
1893 retval = NI_RETCODE_INVALID_PARAM;
1894 LRETURN;
1895 }
1896
1897 ui32LBA = CONFIG_SESSION_KeepAlive_W(session_id);
1898 if (ni_nvme_send_write_cmd(device_handle, event_handle, p_data,
1899 NI_DATA_BUFFER_LEN, ui32LBA) < 0)
1900 {
1901 ni_log(NI_LOG_ERROR, "ERROR: %s(): device_handle=%" PRIx64 " , "
1902 "session_id=%d\n", __func__, (int64_t)device_handle, session_id);
1903 retval = NI_RETCODE_FAILURE;
1904 }
1905 else
1906 {
1908 "SUCCESS %s(): device_handle=%" PRIx64 " , "
1909 "session_id=%d\n", __func__, (int64_t)device_handle, session_id);
1910 retval = NI_RETCODE_SUCCESS;
1911 }
1912
1913END:
1914
1915 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
1916
1917 return retval;
1918}
1919
1920/*!******************************************************************************
1921 * \brief Send end of stream signal to the decoder
1922 *
1923 * \param
1924 *
1925 * \return
1926 *******************************************************************************/
1928{
1929 ni_retcode_t retval;
1930 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
1931 if (!p_ctx)
1932 {
1933 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
1934 __func__);
1935 retval = NI_RETCODE_INVALID_PARAM;
1936 LRETURN;
1937 }
1938
1939 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
1940 {
1941 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
1942 __func__);
1944 LRETURN;
1945 }
1946
1949 p_ctx->device_type, p_ctx->hw_id,
1950 &(p_ctx->session_id), OPT_1);
1951 CHECK_VPU_RECOVERY(retval);
1952
1953END:
1954
1955 if (NI_RETCODE_SUCCESS != retval)
1956 {
1957 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): %d, return\n", __func__, retval);
1958 }
1959
1960 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
1961
1962 return retval;
1963}
1964
1965/*!******************************************************************************
1966 * \brief Flush decoder output
1967 *
1968 * \param
1969 *
1970 * \return
1971 *******************************************************************************/
1973{
1974 ni_retcode_t retval;
1975 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
1976
1977 if (!p_ctx)
1978 {
1979 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): passed parameters are null!, return\n",
1980 __func__);
1981 retval = NI_RETCODE_INVALID_PARAM;
1982 LRETURN;
1983 }
1984
1985 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
1986 {
1987 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): xcoder instance id < 0, return\n",
1988 __func__);
1990 LRETURN;
1991 }
1992
1995 p_ctx->device_type, p_ctx->hw_id,
1996 &(p_ctx->session_id), OPT_1);
1997
1998END:
1999
2000 if (NI_RETCODE_SUCCESS != retval)
2001 {
2002 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): %d, return\n", __func__, retval);
2003 }
2004
2005 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
2006
2007 return retval;
2008}
2009
2010/*!******************************************************************************
2011 * \brief Close a xcoder decoder instance
2012 *
2013 * \param
2014 *
2015 * \return
2016 *******************************************************************************/
2018{
2019 (void)eos_recieved;
2021 void* p_buffer = NULL;
2022 uint32_t ui32LBA = 0;
2023 int i;
2024 ni_xcoder_params_t *p_param = NULL;
2025
2026 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
2027
2028 if (!p_ctx)
2029 {
2030 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
2031 __func__);
2033 }
2034
2036
2037 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
2038 {
2039 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): Invalid session ID, return.\n", __func__);
2040 retval = NI_RETCODE_SUCCESS;
2041 LRETURN;
2042 }
2043
2044 if (NI_CODEC_HW_ENABLE == p_ctx->hw_action)
2045 {
2046 ni_session_statistic_t sessionStatistic = {0};
2048 }
2049
2051 (char *) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rg") >= 0)
2052 {
2053 ni_log2(p_ctx, NI_LOG_INFO,
2054 "Decoder_complete_info:session_id 0x%x, total frames input:%u "
2055 "buffered: %u completed: %u output: %u dropped: %u error: %u corrupted: %u\n",
2063 } else
2064 {
2065 ni_log2(p_ctx, NI_LOG_INFO,
2066 "Decoder_complete_info:session_id 0x%x, total frames input:%u "
2067 "buffered: %u completed: %u output: %u dropped: %u error: %u\n",
2074 }
2075
2076 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
2077 {
2078 ni_log2(p_ctx, NI_LOG_ERROR, "%s: Invalid session ID, return.\n", __func__);
2079 retval = NI_RETCODE_SUCCESS;
2080 LRETURN;
2081 }
2082
2083 //malloc data buffer
2084 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
2085 {
2086 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: malloc decoder close data buffer failed\n", NI_ERRNO);
2088 LRETURN;
2089 }
2090
2091 if (p_ctx->p_session_config)
2092 {
2093 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
2095 {
2097 if (NI_RETCODE_SUCCESS != retval)
2098 {
2099 char errmsg[NI_ERRNO_LEN] = {0};
2101 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ddr priority setting failure for %s\n",
2102 __func__, errmsg);
2103 LRETURN;
2104 }
2105 }
2106 }
2107
2108 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
2109
2111
2112 int retry = 0;
2113 while (retry < NI_SESSION_CLOSE_RETRY_MAX)
2114 {
2115 ni_log2(p_ctx, NI_LOG_DEBUG,
2116 "%s(): p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
2117 "p_ctx->session_id=%d, close_mode=1\n",
2118 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
2119 p_ctx->session_id);
2120
2122 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
2123 {
2124 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): command failed!\n", __func__);
2127 break;
2128 } else
2129 {
2130 //Close should always succeed
2131 retval = NI_RETCODE_SUCCESS;
2133 break;
2134 }
2135 /*
2136 else if (*((ni_retcode_t *)p_buffer) == RETCODE_SUCCESS)
2137 {
2138 retval = NI_RETCODE_SUCCESS;
2139 p_ctx->session_id = NI_INVALID_SESSION_ID;
2140 break;
2141 }
2142 else
2143 {
2144 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): wait for close\n", __func__);
2145 ni_usleep(NI_SESSION_CLOSE_RETRY_INTERVAL_US);
2146 retval = NI_RETCODE_ERROR_NVME_CMD_FAILED;
2147 }
2148 */
2149 retry++;
2150 }
2151
2152END:
2153
2154 ni_aligned_free(p_buffer);
2156 ni_memfree(p_ctx->p_leftover);
2157
2158 if (p_ctx->pts_table)
2159 {
2160 ni_queue_free(&p_ctx->pts_table->list, p_ctx->buffer_pool);
2161 ni_memfree(p_ctx->pts_table);
2162 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_timestamp_done: success\n");
2163 }
2164
2165 if (p_ctx->dts_queue)
2166 {
2167 ni_queue_free(&p_ctx->dts_queue->list, p_ctx->buffer_pool);
2168 ni_memfree(p_ctx->dts_queue);
2169 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_timestamp_done: success\n");
2170 }
2171
2174 p_ctx->buffer_pool = NULL;
2175 p_ctx->dec_fme_buf_pool = NULL;
2176
2177 for (i = 0; i < NI_FIFO_SZ; i++)
2178 {
2179 ni_memfree(p_ctx->pkt_custom_sei_set[i]);
2180 }
2181
2182 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): CTX[Card:%" PRIx64 " / HW:%d / INST:%d]\n",
2183 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
2184 p_ctx->session_id);
2185
2186 low_delay_signal(p_ctx);
2188
2189 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
2190
2191 return retval;
2192}
2193
2194/*!******************************************************************************
2195 * \brief Send a video p_packet to decoder
2196 *
2197 * \param
2198 *
2199 * \return
2200 *******************************************************************************/
2202{
2203 uint32_t sent_size = 0;
2204 uint32_t packet_size = 0;
2205 int current_pkt_size;
2206 int retval = NI_RETCODE_SUCCESS;
2207 ni_xcoder_params_t *p_param;
2208 ni_instance_buf_info_t buf_info = { 0 };
2209 ni_session_statistic_t sessionStatistic = {0};
2210 int query_retry = 0;
2211 uint32_t ui32LBA = 0;
2212
2213 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
2214
2215 if ((!p_ctx) || (!p_packet))
2216 {
2217 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
2218 __func__);
2220 }
2221
2223
2224 if ((NI_INVALID_SESSION_ID == p_ctx->session_id))
2225 {
2226 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
2227 __func__);
2229 LRETURN;
2230 }
2231
2232 low_delay_wait(p_ctx);
2233
2234#ifdef MEASURE_LATENCY
2235 if ((p_packet->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
2236 {
2237 uint64_t abs_time_ns = ni_gettime_ns();
2239 abs_time_ns, p_packet->dts);
2240 }
2241#endif
2242
2243 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
2244 packet_size = p_packet->data_len;
2245 current_pkt_size = (int)packet_size;
2246
2247#ifdef XCODER_311
2248 int max_retry = 200; // 20ms
2249 if (p_packet->video_width * p_packet->video_height >= NI_NUM_OF_PIXELS_1440P)
2250 {
2251 max_retry = NI_MAX_TX_RETRIES; // 100ms
2252 }
2253#endif
2254
2255 for (;;)
2256 {
2257 query_sleep(p_ctx);
2258
2259 query_retry++;
2260
2261
2263 "65") >= 0)
2264 {
2266 &sessionStatistic);
2267 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
2269 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
2270 CHECK_VPU_RECOVERY(retval);
2271
2272 buf_info.buf_avail_size = sessionStatistic.ui32WrBufAvailSize;
2273 } else
2274 {
2276 NI_DEVICE_TYPE_DECODER, &buf_info);
2277 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
2278 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
2279 CHECK_VPU_RECOVERY(retval);
2280 }
2281
2282 if (buf_info.buf_avail_size == DP_IPC_PASSTHRU)
2283 {
2284 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Bad available buffer size %u\n", __FUNCTION__, buf_info.buf_avail_size);
2285 retval = NI_RETCODE_FAILURE;
2286 LRETURN;
2287 }
2288
2290 {
2292 }
2293 if (p_ctx->biggest_bitstream_buffer_allocated < packet_size)
2294 {
2297 {
2298 // Reallocate decoder bitstream buffers to accomodate
2300 "66") >= 0)
2301 {
2302 retval = ni_config_instance_set_write_len(p_ctx,
2304 // packet buffer aligned to NI_MAX_PACKET_SZ(128k)
2305 (packet_size / NI_MAX_PACKET_SZ + 1) * NI_MAX_PACKET_SZ);
2307 p_ctx->device_type, p_ctx->hw_id,
2308 &(p_ctx->session_id), OPT_3);
2309 CHECK_VPU_RECOVERY(retval);
2310 }
2311 else
2312 {
2313 retval = ni_config_instance_set_decoder_params(p_ctx, packet_size);
2314 }
2315 if (NI_RETCODE_SUCCESS != retval)
2316 {
2317 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): failed to reallocate bitstream\n", __FUNCTION__);
2318 LRETURN;
2319 }
2321 query_retry--;
2322 continue;
2323 }
2324 }
2325
2326 if (NI_RETCODE_SUCCESS != retval ||
2327 buf_info.buf_avail_size < packet_size)
2328 {
2329 ni_log2(p_ctx, NI_LOG_TRACE,
2330 "Warning: dec write query fail rc %d or available buf size %u < "
2331 "pkt size %u , retry: %d max_retry_fail_count %d\n",
2332 retval, buf_info.buf_avail_size, packet_size, query_retry, p_ctx->max_retry_fail_count[0]);
2333#ifdef XCODER_311
2334 if (query_retry > max_retry ||
2335 (sessionStatistic.ui32RdBufAvailSize > 0 && !p_ctx->required_buf_size))
2336#else
2337 if (query_retry > NI_MAX_TX_RETRIES ||
2338 (sessionStatistic.ui32RdBufAvailSize > 0 && !p_ctx->required_buf_size))
2339#endif
2340 {
2342#ifdef XCODER_311
2343 if (query_retry > max_retry)
2344#else
2345 if (query_retry > NI_MAX_TX_RETRIES)
2346#endif
2347 {
2348 p_ctx->max_retry_fail_count[0]++;
2349 }
2350 p_ctx->required_buf_size = packet_size;
2352 LRETURN;
2353 }
2357 }
2358 else
2359 {
2360 p_ctx->max_retry_fail_count[0] = 0;
2361 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec write query success, available buf "
2362 "size %u >= pkt size %u !\n",
2363 buf_info.buf_avail_size, packet_size);
2364 break;
2365 }
2366 }
2367
2368 //Configure write size for the buffer
2370 packet_size);
2372 p_ctx->device_type, p_ctx->hw_id,
2373 &(p_ctx->session_id), OPT_1);
2374 CHECK_VPU_RECOVERY(retval);
2375 if (retval < 0)
2376 {
2377 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): config pkt size command failed\n",
2378 __func__);
2380 LRETURN;
2381 }
2382
2384
2385 //check for start of stream flag
2386 if (p_packet->start_of_stream)
2387 {
2390 p_ctx->device_type, p_ctx->hw_id,
2391 &(p_ctx->session_id), OPT_1);
2392 CHECK_VPU_RECOVERY(retval);
2393 if (NI_RETCODE_SUCCESS != retval)
2394 {
2395 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Failed to send SOS.\n", __func__);
2396 LRETURN;
2397 }
2398
2399 p_packet->start_of_stream = 0;
2400 }
2401
2402 if (p_packet->p_data)
2403 {
2404 ni_log2(p_ctx, NI_LOG_DEBUG,
2405 "%s() had data to send: packet_size=%u, "
2406 "p_packet->sent_size=%d, p_packet->data_len=%u, "
2407 "p_packet->start_of_stream=%u, p_packet->end_of_stream=%u, "
2408 "p_packet->video_width=%u, p_packet->video_height=%u\n",
2409 __func__, packet_size, p_packet->sent_size, p_packet->data_len,
2410 p_packet->start_of_stream, p_packet->end_of_stream,
2411 p_packet->video_width, p_packet->video_height);
2412
2413 uint8_t *p_data = (uint8_t *)p_packet->p_data;
2414 // Note: session status is NOT reset but tracked between send
2415 // and recv to catch and recover from a loop condition
2416 // p_ctx->status = 0;
2417
2418 if (packet_size % NI_MEM_PAGE_ALIGNMENT) //packet size, already aligned
2419 {
2420 packet_size = ( (packet_size / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
2421 }
2422
2423 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
2424 p_data, packet_size, ui32LBA);
2425 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write,
2426 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
2427 CHECK_VPU_RECOVERY(retval);
2428 if (retval < 0)
2429 {
2430 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
2432 LRETURN;
2433 }
2434
2435 // reset session status after successful send
2436 p_ctx->status = 0;
2437 p_ctx->required_buf_size = 0;
2438
2439 sent_size = p_packet->data_len;
2440 p_packet->data_len = 0;
2441
2442 if (p_param->dec_input_params.nb_save_pkt)
2443 {
2444 char dump_file[512] = {0};
2445 long curr_pkt_num =
2446 ((long)p_ctx->pkt_num % p_param->dec_input_params.nb_save_pkt) + 1;
2447 (void)snprintf(dump_file, sizeof(dump_file), "%s/pkt-%04ld.bin",
2448 p_ctx->stream_dir_name, curr_pkt_num);
2449
2450 FILE *f = NULL;
2451 ni_fopen(&f, dump_file, "wb");
2452 if (f)
2453 {
2454 (void)fwrite(p_packet->p_data, sent_size, 1, f);
2455 (void)fflush(f);
2456 (void)fclose(f);
2457 }
2458 }
2459
2460 p_ctx->pkt_num++;
2461 p_ctx->low_delay_sync_flag = 1;
2462 }
2463
2464 //Handle end of stream flag
2465 if (p_packet->end_of_stream)
2466 {
2469 p_ctx->device_type, p_ctx->hw_id,
2470 &(p_ctx->session_id), OPT_1);
2471 CHECK_VPU_RECOVERY(retval);
2472
2473 if (NI_RETCODE_SUCCESS != retval)
2474 {
2475 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Failed to send EOS.\n", __func__);
2476 LRETURN;
2477 }
2478
2479 p_packet->end_of_stream = 0;
2480 p_ctx->ready_to_close = 1;
2481 }
2482
2483 {
2484 p_ctx->pts_offsets[p_ctx->pkt_index % NI_FIFO_SZ] = p_packet->pts;
2485 p_ctx->flags_array[p_ctx->pkt_index % NI_FIFO_SZ] = p_packet->flags;
2486 p_ctx->pkt_pos[p_ctx->pkt_index % NI_FIFO_SZ] = p_packet->pkt_pos;
2487 if (p_ctx->pkt_index == 0)
2488 {
2489 p_ctx->pkt_offsets_index_min[p_ctx->pkt_index % NI_FIFO_SZ] = 0;
2490 /* minus 1 here. ffmpeg parses the msb 0 of long start code as the last packet's payload for hevc bitstream (hevc_parse).
2491 * move 1 byte forward on all the pkt_offset so that frame_offset coming from fw can fall into the correct range. */
2492 //p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ] = current_pkt_size - 1;
2493 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ] = current_pkt_size;
2494 ni_log2(p_ctx, NI_LOG_DEBUG,
2495 "%s: (first packet) pkt_index %d i %u "
2496 "pkt_offsets_index_min %" PRIu64 " pkt_offsets_index %" PRIu64
2497 " pts_offsets %" PRId64 "\n",
2498 __func__, p_ctx->pkt_index, p_ctx->pkt_index % NI_FIFO_SZ,
2500 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ],
2501 p_ctx->pts_offsets[p_ctx->pkt_index % NI_FIFO_SZ]);
2502 }
2503 else
2504 {
2505 // cumulate sizes to correspond to FW offsets
2506 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];
2507 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;
2508 ni_log2(p_ctx, NI_LOG_DEBUG,
2509 "%s: pkt_index %d i %u pkt_offsets_index_min "
2510 "%" PRIu64 " pkt_offsets_index %" PRIu64 " pts_offsets %" PRId64
2511 "\n",
2512 __func__, p_ctx->pkt_index, p_ctx->pkt_index % NI_FIFO_SZ,
2514 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ],
2515 p_ctx->pts_offsets[p_ctx->pkt_index % NI_FIFO_SZ]);
2516
2517 //Wrapping 32 bits since FW send u32 wrapped values
2518 if (p_ctx->pkt_offsets_index_min[p_ctx->pkt_index % NI_FIFO_SZ] > 0xFFFFFFFF)
2519 {
2520 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);
2521 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;
2522 ni_log2(p_ctx, NI_LOG_DEBUG,
2523 "%s: (wrap) pkt_index %d i %u "
2524 "pkt_offsets_index_min %" PRIu64 " pkt_offsets_index %" PRIu64
2525 " pts_offsets %" PRId64 "\n",
2526 __func__, p_ctx->pkt_index, p_ctx->pkt_index % NI_FIFO_SZ,
2528 p_ctx->pkt_offsets_index[p_ctx->pkt_index % NI_FIFO_SZ],
2529 p_ctx->pts_offsets[p_ctx->pkt_index % NI_FIFO_SZ]);
2530 }
2531 }
2532
2533 /* if this wrap-around pkt_offset_index spot is about to be overwritten, free the previous one. */
2534 free(p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ]);
2535
2536 if (p_packet->p_custom_sei_set)
2537 {
2538 p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ] = malloc(sizeof(ni_custom_sei_set_t));
2539 if (p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ])
2540 {
2541 ni_custom_sei_set_t *p_custom_sei_set = p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ];
2542 memcpy(p_custom_sei_set, p_packet->p_custom_sei_set, sizeof(ni_custom_sei_set_t));
2543 }
2544 else
2545 {
2546 /* warn and lose the sei data. */
2547 ni_log2(p_ctx, NI_LOG_ERROR,
2548 "Error %s: failed to allocate custom SEI buffer for pkt.\n",
2549 __func__);
2550 }
2551 }
2552 else
2553 {
2554 p_ctx->pkt_custom_sei_set[p_ctx->pkt_index % NI_FIFO_SZ] = NULL;
2555 }
2556
2557 p_ctx->pkt_index++;
2558 }
2559
2560 retval = ni_timestamp_register(p_ctx->buffer_pool, p_ctx->dts_queue, p_packet->dts, 0);
2561 if (NI_RETCODE_SUCCESS != retval)
2562 {
2563 ni_log2(p_ctx, NI_LOG_ERROR,
2564 "ERROR %s(): ni_timestamp_register() for dts returned %d\n",
2565 __func__, retval);
2566 }
2567END:
2568
2570
2571 if (NI_RETCODE_SUCCESS == retval)
2572 {
2573 ni_log2(p_ctx, NI_LOG_TRACE,
2574 "%s(): exit: packets: %" PRIu64 " offset %" PRIx64 ""
2575 " sent_size = %u, status=%d\n",
2576 __func__, p_ctx->pkt_num, (uint64_t)p_packet->pos, sent_size,
2577 p_ctx->status);
2578 return (int)sent_size;
2579 } else
2580 {
2581 ni_log2(p_ctx, NI_LOG_ERROR,
2582 "ERROR %s(): exit: returnErr: %d, p_ctx->status: %d\n", __func__,
2583 retval, p_ctx->status);
2584 return retval;
2585 }
2586}
2587
2588static int64_t guess_correct_pts(ni_session_context_t* p_ctx, int64_t reordered_pts, int64_t dts)
2589{
2590 int64_t pts = NI_NOPTS_VALUE;
2591 if (dts != NI_NOPTS_VALUE)
2592 {
2594 p_ctx->pts_correction_last_dts = dts;
2595 ni_log2(p_ctx, NI_LOG_DEBUG,
2596 "%s: pts_correction_last_dts %" PRId64 " "
2597 "pts_correction_num_faulty_dts %d\n",
2598 __func__, p_ctx->pts_correction_last_dts,
2600 }
2601 else if (reordered_pts != NI_NOPTS_VALUE)
2602 {
2603 p_ctx->pts_correction_last_dts = reordered_pts;
2604 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: pts_correction_last_dts %" PRId64 "\n", __func__,
2606 }
2607 if (reordered_pts != NI_NOPTS_VALUE)
2608 {
2609 p_ctx->pts_correction_num_faulty_pts += reordered_pts <= p_ctx->pts_correction_last_pts;
2610 p_ctx->pts_correction_last_pts = reordered_pts;
2611 ni_log2(p_ctx, NI_LOG_DEBUG,
2612 "%s: pts_correction_last_pts %" PRId64 " "
2613 "pts_correction_num_faulty_pts %d\n",
2614 __func__, p_ctx->pts_correction_last_pts,
2616 }
2617 else if (dts != NI_NOPTS_VALUE)
2618 {
2619 p_ctx->pts_correction_last_pts = dts;
2620 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: pts_correction_last_pts %" PRId64 "\n", __func__,
2622 }
2624 && reordered_pts != NI_NOPTS_VALUE)
2625 {
2626 pts = reordered_pts;
2627 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: (reordered_pts) pts %" PRId64 "\n", __func__,
2628 pts);
2629 }
2630 else
2631 {
2632 if ((NI_NOPTS_VALUE == reordered_pts) ||
2633 (NI_NOPTS_VALUE == p_ctx->last_pts) || (dts >= p_ctx->last_pts))
2634 {
2635 pts = dts;
2636 } else
2637 {
2638 pts = reordered_pts;
2639 }
2640
2641 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: (dts) pts %" PRId64 "\n", __func__, pts);
2642 }
2643 return pts;
2644}
2645
2646static int rotated_array_binary_search(uint64_t *lefts, uint64_t *rights,
2647 int32_t size, uint64_t target)
2648{
2649 int lo = 0;
2650 int hi = size - 1;
2651 while (lo <= hi)
2652 {
2653 int mid = lo + (hi - lo) / 2;
2654 if (lefts[mid] <= target && target < rights[mid])
2655 {
2656 return mid;
2657 }
2658
2659 if (rights[mid] == 0)
2660 {
2661 // empty in (mid, hi)
2662 hi = mid - 1;
2663 continue;
2664 }
2665
2666 if (rights[lo] <= rights[mid])
2667 {
2668 if (lefts[lo] <= target && target < lefts[mid])
2669 {
2670 // Elements are all monotonous in (lo, mid)
2671 hi = mid - 1;
2672 } else
2673 {
2674 // Rotation in (mid, hi)
2675 lo = mid + 1;
2676 }
2677 } else
2678 {
2679 if (rights[mid] <= target && target < rights[hi])
2680 {
2681 // Elements are all monotonous in (mid, hi)
2682 lo = mid + 1;
2683 } else
2684 {
2685 // Rotation in (lo, mid)
2686 hi = mid - 1;
2687 }
2688 }
2689 }
2690
2691 return -1;
2692}
2693
2694/*!******************************************************************************
2695 * \brief Retrieve a YUV p_frame from decoder
2696 *
2697 * \param
2698 *
2699 * \return
2700 *******************************************************************************/
2702{
2703 ni_instance_mgr_stream_info_t data = { 0 };
2704 int rx_size = 0;
2705 uint64_t frame_offset = 0;
2706 uint32_t frame_dropped = 0;
2707 uint8_t *p_data_buffer = NULL;
2708 uint32_t i = 0;
2709 int is_planar;
2710 int retval = NI_RETCODE_SUCCESS;
2711 int metadata_hdr_size = NI_FW_META_DATA_SZ - NI_MAX_NUM_OF_DECODER_OUTPUTS * sizeof(niFrameSurface1_t);
2712 int sei_size = 0;
2713 uint32_t total_bytes_to_read = 0;
2714 uint32_t read_size_bytes = 0;
2715 ni_instance_buf_info_t buf_info = { 0 };
2716 ni_session_statistic_t sessionStatistic = {0};
2717 ni_xcoder_params_t *p_param;
2718
2719 int query_retry = 0;
2720 uint32_t ui32LBA = 0;
2721 unsigned int bytes_read_so_far = 0;
2722 int query_type = INST_BUF_INFO_RW_READ;
2723 int low_delay_notify = 0;
2724 uint32_t frames_dropped = 0;
2725 uint8_t get_first_metadata = 0;
2726 uint8_t sequence_change = 0;
2727
2728 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
2729
2730 if ((!p_ctx) || (!p_frame))
2731 {
2732 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: passed parameters are null!, return\n");
2734 }
2735
2737
2738start:
2739 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
2740 {
2741 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): xcoder instance id < 0, return\n",
2742 __func__);
2744 LRETURN;
2745 }
2746
2747 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
2748 p_data_buffer = (uint8_t *)p_frame->p_buffer;
2749
2750 // p_frame->p_data[] can be NULL before actual resolution is returned by
2751 // decoder and buffer pool is allocated, so no checking here.
2752 total_bytes_to_read = p_frame->data_len[0] + p_frame->data_len[1] +
2753 p_frame->data_len[2] + metadata_hdr_size;
2754 ni_log2(p_ctx, NI_LOG_DEBUG, "Total bytes to read %u, low_delay %u\n",
2755 total_bytes_to_read, p_ctx->decoder_low_delay);
2756
2757 if (p_ctx->decoder_low_delay > 0 && !p_ctx->ready_to_close)
2758 {
2759 ni_log2(p_ctx, NI_LOG_DEBUG, "frame_num = %" PRIu64 ", pkt_num = %" PRIu64 "\n",
2760 p_ctx->frame_num, p_ctx->pkt_num);
2761 frames_dropped = p_ctx->session_statistic.ui32FramesDropped;
2762 if (p_ctx->force_low_delay && (p_ctx->force_low_delay_cnt < frames_dropped)) {
2763 p_ctx->force_low_delay_cnt = frames_dropped;
2764 }
2765 if (p_ctx->frame_num + p_ctx->force_low_delay_cnt >= p_ctx->pkt_num)
2766 {
2767 //nothing to query, leave
2768 retval = NI_RETCODE_SUCCESS;
2769 LRETURN;
2770 }
2771 query_type = INST_BUF_INFO_RW_READ_BUSY;
2772 }
2773 for (;;)
2774 {
2775 query_sleep(p_ctx);
2776
2777 query_retry++;
2778
2780 "65") >= 0)
2781 {
2783 &sessionStatistic);
2784 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
2786 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
2787 CHECK_VPU_RECOVERY(retval);
2788
2789 buf_info.buf_avail_size = sessionStatistic.ui32RdBufAvailSize;
2790 } else
2791 {
2792 retval = ni_query_instance_buf_info(p_ctx, query_type,
2793 NI_DEVICE_TYPE_DECODER, &buf_info);
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
2799 ni_log2(p_ctx, NI_LOG_TRACE, "Info query buf_info.size = %u\n",
2800 buf_info.buf_avail_size);
2801
2802 if (NI_RETCODE_SUCCESS != retval)
2803 {
2804 ni_log2(p_ctx, NI_LOG_TRACE, "Warning: dec read query fail rc %d retry %d max_retry_fail_count %d\n",
2805 retval, query_retry, p_ctx->max_retry_fail_count[1]);
2806
2807 if (query_retry >= 1000)
2808 {
2809 p_ctx->max_retry_fail_count[1]++;
2810 low_delay_notify = 1;
2812 LRETURN;
2813 }
2817 }
2818 else if (buf_info.buf_avail_size == DP_IPC_PASSTHRU)
2819 {
2820 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Bad available buffer size %u\n", __FUNCTION__, buf_info.buf_avail_size);
2821 retval = NI_RETCODE_FAILURE;
2822 LRETURN;
2823 }
2824 else if (buf_info.buf_avail_size == metadata_hdr_size)
2825 {
2826 ni_log2(p_ctx, NI_LOG_DEBUG, "Info only metadata hdr is available, seq change?\n");
2827 total_bytes_to_read = metadata_hdr_size;
2828 sequence_change = 1;
2829 break;
2830 }
2831 else if (0 == buf_info.buf_avail_size)
2832 {
2833 // query to see if it is eos now, if we have sent it
2834 if (p_ctx->ready_to_close)
2835 {
2836 ni_log2(p_ctx, NI_LOG_TRACE, "Info dec query, ready_to_close %u, query eos\n",
2837 p_ctx->ready_to_close);
2838 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_DECODER, &data);
2839 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
2840 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
2841 CHECK_VPU_RECOVERY(retval);
2842
2843 if (data.is_flushed ||
2844 query_retry >=
2846 {
2847 if (query_retry >=
2849 {
2850 ni_log2(p_ctx, NI_LOG_ERROR,
2851 "WARNING: Dec eos reached but also exceeded max dec read query "
2852 "retries. is_flushed=%u try=%d.\n",
2853 data.is_flushed, query_retry);
2854 } else
2855 {
2856 ni_log2(p_ctx, NI_LOG_DEBUG,
2857 "Dec eos reached. is_flushed=%u try=%d.\n",
2858 data.is_flushed, query_retry);
2859 }
2860 p_frame->end_of_stream = 1;
2861 low_delay_notify = 1;
2862 retval = NI_RETCODE_SUCCESS;
2863 LRETURN;
2864 } else
2865 {
2866 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read available buf size == 0, query try %d,"
2867 " retrying ..\n", query_retry);
2871 continue;
2872 }
2873 }
2874
2875 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read available buf size == 0. retry=%d, eos=%d"
2876 "\n", query_retry, p_frame->end_of_stream);
2878 (p_ctx->decoder_low_delay > 0 &&
2879 ((p_ctx->frame_num + p_ctx->force_low_delay_cnt)
2880 < p_ctx->pkt_num))) &&
2881 query_retry < 1000 / 2)
2882 {
2883 if (p_ctx->decoder_low_delay && p_ctx->force_low_delay) {
2884 if (p_ctx->session_statistic.ui32FramesDropped > frames_dropped) {
2885 // last pkt sent to decoder marked as dropped, no output,
2886 // so just stop query and return
2887 p_ctx->force_low_delay_cnt++;
2888 low_delay_signal(p_ctx);
2889 retval = NI_RETCODE_SUCCESS;
2890 LRETURN;
2891 }
2892 } else if (NI_RETCODE_NVME_SC_WRITE_BUFFER_FULL == p_ctx->status &&
2893 sessionStatistic.ui32WrBufAvailSize > p_ctx->required_buf_size)
2894 {
2895 ni_log2(p_ctx, NI_LOG_TRACE, "Info dec write buffer is enough, available buf "
2896 "size %u >= required size %u !\n",
2897 sessionStatistic.ui32WrBufAvailSize, p_ctx->required_buf_size);
2898 p_ctx->status = 0;
2899 p_ctx->required_buf_size = 0;
2900 retval = NI_RETCODE_SUCCESS;
2901 LRETURN;
2902 }
2904 ni_usleep(25);
2906 continue;
2907 } else
2908 {
2909 if(p_ctx->decoder_low_delay > 0)
2910 {
2911 if (p_ctx->force_low_delay) {
2912 p_ctx->force_low_delay_cnt++;
2913 low_delay_signal(p_ctx);
2914 } else {
2915 ni_log2(p_ctx, NI_LOG_ERROR,
2916 "Warning: ceased using low delay decoding mode after "
2917 "excessively long decoder read query.\n");
2918 // Here it should be the last signal to release the send thread
2919 // holding the low delay mutex.
2920 low_delay_signal(p_ctx);
2921 p_ctx->decoder_low_delay = 0;
2922 }
2923 }
2924
2925 if ((p_param->dec_input_params.min_packets_delay && p_ctx->pkt_delay_cnt))
2926 {
2927 if(p_ctx->pkt_num >= (p_ctx->frame_num + p_ctx->pkt_delay_cnt +
2929 {
2930 if(query_retry <= 2000)
2931 {
2933 ni_usleep(25);
2935 continue;
2936 } else {
2937 p_ctx->pkt_delay_cnt++;
2938 ni_log2(p_ctx, NI_LOG_ERROR,
2939 "Warning: decoder pkt_num %u frame_num %u "
2940 "timeout, increasing pkt_delay_cnt to %u\n",
2941 p_ctx->pkt_num, p_ctx->frame_num,
2942 p_ctx->pkt_delay_cnt);
2943 }
2944 }
2945 }
2946
2947 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: dec read failed %d retries. rc=%d; eos=%d\n",
2948 query_retry, p_ctx->status, p_frame->end_of_stream);
2949 }
2950 retval = NI_RETCODE_SUCCESS;
2951 LRETURN;
2952 }
2953 else
2954 {
2955 // We have to ensure there are adequate number of DTS for picture
2956 // reorder delay otherwise wait for more packets to be sent to decoder.
2957 ni_timestamp_table_t *p_dts_queue = p_ctx->dts_queue;
2958 if ((int)p_dts_queue->list.count < p_ctx->pic_reorder_delay + 1 &&
2959 !p_ctx->ready_to_close &&
2961 {
2962 retval = NI_RETCODE_SUCCESS;
2963 ni_log2(p_ctx, NI_LOG_DEBUG,
2964 "At least %d packets should be sent before reading the "
2965 "first frame!\n",
2966 p_ctx->pic_reorder_delay + 1);
2967 LRETURN;
2968 }
2969 p_ctx->max_retry_fail_count[1] = 0;
2970
2971 // get actual YUV transfer size if this is the stream's very first read
2972 if (0 == p_ctx->active_video_width || 0 == p_ctx->active_video_height)
2973 {
2974 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_DECODER, &data);
2975 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
2976 p_ctx->device_type, p_ctx->hw_id,
2977 &(p_ctx->session_id), OPT_1);
2978 CHECK_VPU_RECOVERY(retval);
2979
2980 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec YUV query, pic size %ux%u xfer frame size "
2981 "%ux%u frame-rate %u is_flushed %u\n",
2982 data.picture_width, data.picture_height,
2984 data.frame_rate, data.is_flushed);
2987 p_ctx->actual_video_width = data.picture_width;
2988 p_ctx->pixel_format = data.pix_format;
2989 is_planar = (p_ctx->pixel_format == NI_PIX_FMT_YUV420P) ||
2992 //p_ctx->bit_depth_factor = data.transfer_frame_stride / data.picture_width;
2993 p_ctx->is_first_frame = 1;
2994 p_ctx->pixel_format_changed = 0;
2995
2996 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec YUV, adjust frame size from %ux%u to "
2997 "%ux%u format = %d\n", p_frame->video_width, p_frame->video_height,
2998 p_ctx->active_video_width, p_ctx->active_video_height, p_ctx->pixel_format);
2999
3001
3002 // set up decoder YUV frame buffer pool
3005 (int)p_ctx->active_video_height,
3007 p_ctx->bit_depth_factor))
3008 {
3009 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Cannot allocate fme buf pool.\n",
3010 __func__);
3012
3014 ni_decoder_session_close(p_ctx, 0);
3015#ifdef XCODER_SELF_KILL_ERR
3016 // if need to terminate at such occasion when continuing is not
3017 // possible, trigger a codec closure
3018 ni_log2(p_ctx, NI_LOG_ERROR, "Terminating due to unable to allocate fme buf "
3019 "pool.\n");
3020 kill(getpid(), SIGTERM);
3021#endif
3023 LRETURN;
3024 }
3025
3027 p_ctx->dec_fme_buf_pool, p_frame, 1, // get mem buffer
3028 (int)p_ctx->actual_video_width, (int)p_ctx->active_video_height,
3030 p_ctx->bit_depth_factor, is_planar);
3031
3032 if (NI_RETCODE_SUCCESS != retval)
3033 {
3034 LRETURN;
3035 }
3036 total_bytes_to_read = p_frame->data_len[0] + p_frame->data_len[1] +
3037 p_frame->data_len[2] + metadata_hdr_size;
3038 p_data_buffer = (uint8_t*) p_frame->p_buffer;
3039
3040 // make sure we don't read more than available
3041 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec buf size: %u YUV frame + meta-hdr size: %u "
3042 "available: %u\n", p_frame->buffer_size,
3043 total_bytes_to_read, buf_info.buf_avail_size);
3044 }
3045 break;
3046 }
3047 }
3048
3049 ni_log2(p_ctx, NI_LOG_DEBUG, "total_bytes_to_read %u max_nvme_io_size %u ylen %u cr len "
3050 "%u cb len %u hdr %d\n",
3051 total_bytes_to_read, p_ctx->max_nvme_io_size,
3052 p_frame->data_len[0], p_frame->data_len[1],
3053 p_frame->data_len[2], metadata_hdr_size);
3054
3055 if (buf_info.buf_avail_size < total_bytes_to_read)
3056 {
3058 ni_log2(p_ctx, NI_LOG_ERROR,
3059 "ERROR %s() avaliable size(%u)"
3060 "less than needed (%u)\n",
3061 __func__, buf_info.buf_avail_size, total_bytes_to_read);
3062 abort();
3063 }
3064
3065 if (buf_info.buf_avail_size == metadata_hdr_size && (!p_ctx->frame_num || !p_data_buffer))
3066 {
3069 "6rE") >= 0)
3070 {
3071 // allocate p_data_buffer to read the first metadata
3072 void *p_metadata_buffer = NULL;
3073 int buffer_size = ((metadata_hdr_size + (NI_MEM_PAGE_ALIGNMENT - 1)) /
3075 if (ni_posix_memalign(&p_metadata_buffer, sysconf(_SC_PAGESIZE), buffer_size))
3076 {
3077 ni_log2(p_ctx, NI_LOG_ERROR,
3078 "ERROR %d: %s() Cannot allocate metadata buffer.\n",
3079 NI_ERRNO, __func__);
3081 LRETURN;
3082 }
3083 p_data_buffer = (uint8_t *)p_metadata_buffer;
3084 get_first_metadata = 1;
3085 if (!p_ctx->frame_num)
3086 sequence_change = 0;
3087 }
3088 }
3089
3090 if (!p_data_buffer)
3091 {
3092 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: data buffer is null!, return\n");
3093 retval = NI_RETCODE_INVALID_PARAM;
3094 LRETURN;
3095 }
3096
3097 read_size_bytes = buf_info.buf_avail_size;
3099 if (read_size_bytes % NI_MEM_PAGE_ALIGNMENT)
3100 {
3101 read_size_bytes = ((read_size_bytes / NI_MEM_PAGE_ALIGNMENT) *
3104 }
3105
3106 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
3107 p_data_buffer, read_size_bytes, ui32LBA);
3108 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
3109 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
3110 CHECK_VPU_RECOVERY(retval);
3111 if (retval < 0)
3112 {
3113 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
3115 LRETURN;
3116 } else if (get_first_metadata) {
3117 // got first metadata alone
3118 ni_metadata_dec_frame_t *p_meta =
3119 (ni_metadata_dec_frame_t *)((uint8_t *)p_data_buffer);
3120 ni_log2(p_ctx, NI_LOG_DEBUG, "Got first pkt_delay_cnt %u\n",
3122 if (p_ctx->pkt_delay_cnt < p_meta->metadata_common.pkt_delay_cnt)
3124 get_first_metadata = 0;
3125 ni_aligned_free(p_data_buffer);
3126 goto start;
3127 } else {
3128 // command issued successfully, now exit
3130 p_meta =
3131 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
3132 p_frame->data_len[0] +
3133 p_frame->data_len[1] +
3134 p_frame->data_len[2]);
3135
3136 if (buf_info.buf_avail_size != metadata_hdr_size)
3137 {
3138 low_delay_notify = 1;
3139 sei_size = p_meta->sei_size;
3140 } else if (ni_cmp_fw_api_ver(
3142 "6rE") >= 0)
3143 {
3144 p_meta =
3145 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer);
3146 ni_log2(p_ctx, NI_LOG_DEBUG, "Got pkt_delay_cnt %u\n",
3148 if (p_ctx->pkt_delay_cnt < p_meta->metadata_common.pkt_delay_cnt)
3150 }
3151 total_bytes_to_read = total_bytes_to_read + sei_size;
3152 ni_log2(p_ctx, NI_LOG_DEBUG, "decoder read success, size %d total_bytes_to_read "
3153 "include sei %u sei_size %d\n",
3154 retval, total_bytes_to_read, sei_size);
3155 }
3156
3157 bytes_read_so_far = total_bytes_to_read ;
3158 // Note: session status is NOT reset but tracked between send
3159 // and recv to catch and recover from a loop condition
3160
3162 "6sP") >= 0)
3163 {
3164 rx_size = ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, &frame_dropped, false);
3165 }
3166 else
3167 {
3168 rx_size = ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, 0, false);
3169 }
3170 p_ctx->frame_pkt_offset = frame_offset;
3171 if (p_ctx->decoder_low_delay > 0 && buf_info.buf_avail_size == metadata_hdr_size &&
3173 {
3174 ni_log2(p_ctx, NI_LOG_TRACE, "Low delay mode amd check header if has b frame\n");
3175
3176 ni_metadata_dec_frame_t *p_meta =
3177 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
3178 p_frame->data_len[0] +
3179 p_frame->data_len[1] +
3180 p_frame->data_len[2]);
3181 if (p_meta->metadata_common.has_b_frame == 1)
3182 {
3183 ni_log2(p_ctx, NI_LOG_ERROR,"Warning: session 0x%x decoder lowDelay mode "
3184 "is cancelled due to has_b_frames, frame_num %u\n",
3185 p_ctx->session_id, p_ctx->frame_num);
3186 p_ctx->decoder_low_delay = 0;
3187 }
3188 }
3189
3190 if (rx_size > 0)
3191 {
3192 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): s-state %d first_frame %d\n", __func__,
3193 p_ctx->session_run_state, p_ctx->is_first_frame);
3194
3195 int64_t tmp_dts, prev_dts = INT64_MIN, ts_diff = 0;
3196 int nb_diff = 0;
3197
3199 "6sP") >= 0)
3200 {
3201 if(p_ctx->last_frame_dropped + frame_dropped != p_ctx->session_statistic.ui32FramesDropped)
3202 {
3203 ni_log2(p_ctx, NI_LOG_DEBUG,
3204 "### %s(): Warning: ui32FramesDropped %u should be %u + %u\n",
3205 __func__, p_ctx->session_statistic.ui32FramesDropped,
3206 p_ctx->last_frame_dropped, frame_dropped);
3207
3208 p_ctx->session_statistic.ui32FramesDropped = p_ctx->last_frame_dropped + frame_dropped;
3209 }
3210
3212 }
3213
3214 // at stream start, if there are already frames dropped at decoding, drop
3215 // equal number of dts from dts queue to try to align with the first
3216 // returned frame, and calculate the average of dts difference to be used
3217 // for locating the first frame's dts
3218 if (p_ctx->is_first_frame)
3219 {
3220 ni_log2(p_ctx, NI_LOG_DEBUG,
3221 "%s(): First frame : session_id 0x%x, pic_reorder_delay: %d "
3222 "total frames input:%u buffered: %u completed: %u output: %u "
3223 "dropped: %u (%u %u) error: %u\n",
3224 __func__, p_ctx->session_id, p_ctx->pic_reorder_delay,
3230 p_ctx->last_frame_dropped, frame_dropped,
3232
3233 if (p_ctx->session_statistic.ui32FramesDropped > 0)
3234 {
3235 for (i = 0; i < p_ctx->session_statistic.ui32FramesDropped; i++)
3236 {
3238 p_ctx->dts_queue, 0, &tmp_dts,
3241 {
3242 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): FramesDropped pop "
3243 "decoder dts queue %d %ld failed !\n",
3244 __func__, i, tmp_dts);
3245 break;
3246 } else
3247 {
3248 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop "
3249 "decoder dts queue %d %ld success !\n",
3250 __func__, i, tmp_dts);
3251 if (prev_dts != INT64_MIN) {
3252 ts_diff += llabs(tmp_dts - prev_dts);
3253 nb_diff++;
3254 }
3255 prev_dts = tmp_dts;
3256 }
3257 }
3258 if (nb_diff > 1)
3259 {
3260 ts_diff = ts_diff / nb_diff;
3261 }
3263 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop dts "
3264 "average diff: %ld\n", __func__, ts_diff);
3265 }
3266 }
3267 else
3268 {
3270 {
3271 for(i = p_ctx->decoder_last_drop_frame_num; i < p_ctx->session_statistic.ui32FramesDropped; i++)
3272 {
3274 p_ctx->dts_queue, 0, &tmp_dts,
3277 {
3278 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): FramesDropped pop "
3279 "decoder dts queue %d %ld failed !\n",
3280 __func__, i, tmp_dts);
3281 break;
3282 }
3283 }
3285 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop dts %d\n", __func__, p_ctx->decoder_last_drop_frame_num);
3286 }
3287 }
3288
3290 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
3293 {
3294 if (p_ctx->last_dts != NI_NOPTS_VALUE && !p_ctx->ready_to_close)
3295 {
3296 p_ctx->pic_reorder_delay++;
3297 p_frame->dts = p_ctx->last_dts + p_ctx->last_dts_interval;
3298 ni_log2(p_ctx, NI_LOG_DEBUG, "Padding DTS: %" PRId64 "\n", p_frame->dts);
3299 } else
3300 {
3301 p_frame->dts = NI_NOPTS_VALUE;
3302 }
3303 }
3304
3305 if (p_ctx->is_first_frame)
3306 {
3307 for (i = 0; (int)i < p_ctx->pic_reorder_delay; i++)
3308 {
3309 if (p_ctx->last_pts == NI_NOPTS_VALUE &&
3310 p_ctx->last_dts == NI_NOPTS_VALUE)
3311 {
3312 // If the p_frame->pts is unknown in the very beginning we assume
3313 // p_frame->pts == 0 as well as DTS less than PTS by 1000 * 1/timebase
3314 if (p_frame->pts >= p_frame->dts &&
3315 p_frame->pts - p_frame->dts < 1000)
3316 {
3317 break;
3318 }
3319 }
3320
3322 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
3324 p_ctx->frame_num % 500 == 0,
3326 {
3327 p_frame->dts = NI_NOPTS_VALUE;
3328 } else
3329 {
3330 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): pic_reorder_delay pop "
3331 "decoder dts queue %d %ld success !\n",
3332 __func__, i, p_frame->dts);
3333 }
3334 }
3335 // Reset for DTS padding counting
3336 p_ctx->pic_reorder_delay = 0;
3337 }
3338 if (p_ctx->codec_format == NI_CODEC_FORMAT_JPEG)//fw won't save frameoffset when decoding jpeg.
3339 {
3340 if (p_ctx->is_first_frame)
3341 {
3342 p_ctx->is_first_frame = 0;
3343 }
3344 p_frame->pts = p_ctx->pts_offsets[p_ctx->frame_num % NI_FIFO_SZ];
3345 p_frame->flags = p_ctx->flags_array[p_ctx->frame_num % NI_FIFO_SZ];
3346 p_frame->pkt_pos = p_ctx->pkt_pos[p_ctx->frame_num % NI_FIFO_SZ];
3347 ni_log2(p_ctx, NI_LOG_DEBUG, "p_frame->pts = %u, frame_num = %d, p_frame->dts = %u\n",
3348 p_frame->pts, p_ctx->frame_num, p_frame->dts);
3349 }
3350 else
3351 {
3352 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: frame_offset %" PRIu64 "\n", __func__,
3353 frame_offset);
3354
3355 // search for the pkt_offsets of received frame according to frame_offset.
3356 // 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)
3357 // i = -1 if not found
3358 int j = 0;
3359 j = rotated_array_binary_search(p_ctx->pkt_offsets_index_min,
3361 frame_offset);
3362 if (j >= 0)
3363 {
3364 p_frame->pts = p_ctx->pts_offsets[j];
3365 p_frame->flags = p_ctx->flags_array[j];
3366 p_frame->pkt_pos = p_ctx->pkt_pos[j];
3367 ni_log2(p_ctx, NI_LOG_DEBUG,
3368 "%s: (found pts) dts %" PRId64 " pts "
3369 "%" PRId64 " frame_offset %" PRIu64 " j %d "
3370 "pkt_offsets_index_min %" PRIu64 " pkt_offsets_index "
3371 "%" PRIu64 " pkt_pos %" PRIu64 " \n",
3372 __func__, p_frame->dts, p_frame->pts, frame_offset, j,
3373 p_ctx->pkt_offsets_index_min[j],
3374 p_ctx->pkt_offsets_index[j],
3375 p_ctx->pkt_pos[j]);
3376
3377 if (p_ctx->is_first_frame)
3378 {
3379 // if the first frame is I frame and there are dropped frames,
3380 // find the dts closest to its pts using the average of dts diff
3381 if (p_frame->dts != NI_NOPTS_VALUE &&
3382 p_frame->pts != NI_NOPTS_VALUE &&
3383 PIC_TYPE_I == p_frame->ni_pict_type &&
3385 ts_diff > 0)
3386 {
3387 while (p_frame->dts < p_frame->pts &&
3388 llabs(p_frame->pts - p_frame->dts) > ts_diff)
3389 {
3390 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: First I frame pts %lld "
3391 "dts %lld diff. %lld > ts_diff %lld\n",
3392 __func__, p_frame->pts, p_frame->dts,
3393 llabs(p_frame->pts - p_frame->dts), ts_diff);
3394
3396 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
3398 {
3399 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): First I frame "
3400 "pop decoder dts queue error.\n", __func__);
3401 break;
3402 }
3403 }
3404 }
3405 }
3406
3407 p_frame->p_custom_sei_set = p_ctx->pkt_custom_sei_set[j];
3408 p_ctx->pkt_custom_sei_set[j] = NULL;
3409 } else
3410 {
3411 // backup solution pts
3412 if (p_param->dec_input_params.skip_pts_guess && p_ctx->last_pts != NI_NOPTS_VALUE)
3413 {
3414 // if skip guess_correct_pts, use pts interval to get the correct pts
3415 p_frame->pts = p_ctx->last_pts + (p_ctx->last_pts_interval > 0 ? p_ctx->last_pts_interval : 1);
3416 }
3417 else
3418 {
3419 p_frame->pts = p_ctx->last_pts + (p_frame->dts - p_ctx->last_dts);
3420 }
3421 p_frame->pkt_pos = p_ctx->last_pkt_pos + (frame_offset - p_ctx->last_frame_offset);
3422 ni_log2(p_ctx, NI_LOG_ERROR,
3423 "ERROR: Frame pts %" PRId64 " not found for offset "
3424 "%" PRIu64 "\n", p_frame->pts, frame_offset);
3425 ni_log2(p_ctx, NI_LOG_DEBUG,
3426 "%s: (not found use default) dts %" PRId64 " pts %" PRId64
3427 "\n",
3428 __func__, p_frame->dts, p_frame->pts);
3429 }
3430
3431 if (p_ctx->is_first_frame)
3432 {
3433 p_ctx->is_first_frame = 0;
3434 }
3435 }
3436 p_frame->orignal_pts = p_frame->pts;
3437 p_ctx->last_pkt_pos = p_frame->pkt_pos;
3438 p_ctx->last_frame_offset = frame_offset;
3439 if (!p_param->dec_input_params.skip_pts_guess)
3440 p_frame->pts = guess_correct_pts(p_ctx, p_frame->pts, p_frame->dts);
3441 if (p_frame->pts != NI_NOPTS_VALUE && p_ctx->last_pts != NI_NOPTS_VALUE)
3442 p_ctx->last_pts_interval = p_frame->pts - p_ctx->last_pts;
3443 p_ctx->last_pts = p_frame->pts;
3444 if (p_frame->dts != NI_NOPTS_VALUE && p_ctx->last_dts != NI_NOPTS_VALUE)
3445 p_ctx->last_dts_interval = p_frame->dts - p_ctx->last_dts;
3446 p_ctx->last_dts = p_frame->dts;
3447 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: (best_effort_timestamp) pts %" PRId64 "\n",
3448 __func__, p_frame->pts);
3449 p_ctx->frame_num++;
3450
3452 if (p_frame->error_ratio > 0)
3453 {
3454 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: frame number = %d, error_ratio = %u\n",
3455 __func__, p_ctx->frame_num, p_frame->error_ratio);
3456 }
3457
3458#ifdef MEASURE_LATENCY
3459#ifndef XCODER_311
3460 ni_log2(p_ctx, NI_LOG_INFO, "DEC pkt_num %d, fme_num %d, latecy is %d\n",
3461 p_ctx->pkt_num, p_ctx->frame_num, p_ctx->pkt_num - p_ctx->frame_num);
3462#endif
3463#endif
3464
3465#ifdef XCODER_DUMP_DATA
3466 char dump_file[256];
3467 (void)snprintf(dump_file, sizeof(dump_file), "%ld-%u-dec-fme/fme-%04ld.yuv",
3468 (long)getpid(), p_ctx->session_id, (long)p_ctx->frame_num);
3469 FILE *f = NULL;
3470 ni_fopen(&f, dump_file, "wb");
3471 (void)fwrite(p_frame->p_buffer,
3472 p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2],
3473 1, f);
3474 (void)fflush(f);
3475 (void)fclose(f);
3476#endif
3477 }
3478
3479 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): received data: [0x%08x]\n", __func__, rx_size);
3480 ni_log2(p_ctx, NI_LOG_DEBUG,
3481 "%s(): p_frame->start_of_stream=%u, "
3482 "p_frame->end_of_stream=%u, p_frame->video_width=%u, "
3483 "p_frame->video_height=%u\n",
3484 __func__, p_frame->start_of_stream, p_frame->end_of_stream,
3485 p_frame->video_width, p_frame->video_height);
3486 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): p_frame->data_len[0/1/2]=%u/%u/%u\n", __func__,
3487 p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2]);
3488
3489 if (p_ctx->frame_num % 500 == 0)
3490 {
3491 ni_log2(p_ctx, NI_LOG_DEBUG,
3492 "Decoder pts queue size = %u dts queue size = %u\n\n",
3493 p_ctx->pts_table->list.count, p_ctx->dts_queue->list.count);
3494 // scan and clean up
3496 p_ctx->buffer_pool);
3497 }
3498
3499#ifdef MEASURE_LATENCY
3500 if ((p_frame->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
3501 {
3502 uint64_t abs_time_ns = ni_gettime_ns();
3504 ni_log2(p_ctx, NI_LOG_INFO, "DTS:%" PRId64 ",DELTA:%" PRId64 ",dLAT:%" PRIu64 ";\n",
3505 p_frame->dts, abs_time_ns - q->last_benchmark_time,
3506 ni_lat_meas_q_check_latency(q, abs_time_ns, p_frame->dts));
3507 q->last_benchmark_time = abs_time_ns;
3508 }
3509#endif
3510
3511END:
3512
3514
3515 if (get_first_metadata && p_data_buffer)
3516 ni_aligned_free(p_data_buffer);
3517 if (sequence_change && p_ctx->frame_num)
3518 {
3519 if (p_ctx->actual_video_width == p_frame->video_width &&
3520 p_ctx->active_video_height == p_frame->video_height)
3521 {
3522 p_ctx->pixel_format_changed = 1;
3523 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): format changed\n", __func__);
3524 }
3525 }
3526
3527 if (NI_RETCODE_SUCCESS != retval)
3528 {
3529 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): bad exit, retval = %d\n", __func__, retval);
3530 if (retval == NI_RETCODE_ERROR_VPU_RECOVERY)
3531 {
3532 low_delay_signal(p_ctx);
3533 }
3534 return retval;
3535 } else
3536 {
3537 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit, rx_size = %d\n", __func__, rx_size);
3538 if (low_delay_notify)
3539 {
3540 low_delay_signal(p_ctx);
3541 }
3542 return rx_size;
3543 }
3544}
3545
3546/*!******************************************************************************
3547 * \brief Query current xcoder status
3548 *
3549 * \param
3550 *
3551 * \return
3552 *******************************************************************************/
3554 ni_device_type_t device_type)
3555{
3557 int retval = NI_RETCODE_SUCCESS;
3558
3559 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): device_type %d:%s; enter\n", __func__,
3560 device_type, g_device_type_str[device_type]);
3561
3562 if (!p_ctx)
3563 {
3564 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
3565 __func__);
3566 retval = NI_RETCODE_INVALID_PARAM;
3567 LRETURN;
3568 }
3569
3570 retval = ni_query_general_status(p_ctx, device_type, &data);
3571 if (NI_RETCODE_SUCCESS == retval)
3572 {
3576 p_ctx->overall_load_query.admin_queried = (uint32_t)data.admin_nsid;
3577 p_ctx->load_query.current_load =
3578 (uint32_t)data.process_load_percent | (uint32_t)(data.process_load_percent_upper << 8);
3579 p_ctx->load_query.fw_model_load = (uint32_t)data.fw_model_load;
3580 p_ctx->load_query.fw_load = (uint32_t)data.fw_load;
3582
3583 switch (device_type)
3584 {
3588 if (p_ctx->load_query.fw_load == 1 &&
3590 {
3591 // ignore negligible non-video traffic
3592 p_ctx->load_query.fw_load -= 1;
3593 }
3594 break;
3595 default:
3596 break;
3597 }
3598 p_ctx->load_query.total_contexts = (uint32_t)data.active_sub_instances_cnt;
3599 p_ctx->load_query.fw_video_mem_usage = (uint32_t)data.fw_video_mem_usage;
3601 p_ctx->load_query.fw_share_mem_usage = (uint32_t)data.fw_share_mem_usage;
3602 p_ctx->load_query.fw_p2p_mem_usage = (uint32_t)data.fw_p2p_mem_usage;
3604 (uint32_t)data.active_hwupload_sub_inst_cnt;
3605 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 "
3606 "total_contexts:%u fw_video_mem_usage:%u "
3607 "fw_video_shared_mem_usage:%u fw_share_mem_usage:%u "
3608 "fw_p2p_mem_usage:%u active_hwuploaders:%u\n", __func__,
3609 p_ctx->blk_dev_name,
3610 p_ctx->blk_xcoder_name,
3611 p_ctx->dev_xcoder_name,
3612 p_ctx->load_query.current_load,
3614 p_ctx->load_query.fw_load,
3622 {
3623 ni_log2(p_ctx, NI_LOG_DEBUG,
3624 "Overall load %u, model load %u, instance count %u\n",
3628 }
3629 }
3630
3631END:
3632
3633 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
3634
3635 return retval;
3636}
3637
3638/*!******************************************************************************
3639 * \brief Query current xcoder status
3640 *
3641 * \param
3642 *
3643 * \return
3644 *******************************************************************************/
3646 ni_device_type_t device_type, void *detail_data, int ver)
3647{
3648 int retval = NI_RETCODE_SUCCESS;
3649
3650 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): device_type %d:%s; enter\n", __func__,
3651 device_type, g_device_type_str[device_type]);
3652
3653 if (!p_ctx)
3654 {
3655 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
3656 __func__);
3657 retval = NI_RETCODE_INVALID_PARAM;
3658 LRETURN;
3659 }
3660
3661 retval = ni_query_detail_status(p_ctx, device_type, detail_data, ver);
3662
3663END:
3664
3665 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
3666
3667 return retval;
3668}
3669
3670/*!******************************************************************************
3671 * \brief Open a xcoder encoder instance
3672 *
3673 * \param
3674 *
3675 * \return
3676 *******************************************************************************/
3677
3679{
3681 ni_xcoder_params_t *p_param;
3682 void *p_buffer = NULL;
3683 ni_instance_buf_info_t buf_info = {0};
3684 uint32_t ui32LBA = 0;
3685 uint32_t max_cu_size;
3686 uint32_t block_size;
3687 int32_t width, height;
3688 int m_threshold = 0;
3689 char fmt_fw_api_ver1[5], fmt_fw_api_ver2[5];
3690
3691 if (!p_ctx || !p_ctx->p_session_config)
3692 {
3693 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
3694 __func__);
3695 retval = NI_RETCODE_INVALID_PARAM;
3696 LRETURN;
3697 }
3698
3699 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
3700 bool isrgba = (p_ctx->pixel_format == NI_PIX_FMT_ABGR || p_ctx->pixel_format == NI_PIX_FMT_ARGB
3701 || p_ctx->pixel_format == NI_PIX_FMT_RGBA || p_ctx->pixel_format == NI_PIX_FMT_BGRA);
3702 if (isrgba)
3703 {
3705 || p_param->source_width < NI_MIN_WIDTH || p_param->source_height < NI_MIN_HEIGHT)
3706 {
3707 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() RGBA / BGRA / ARGB / AGBR resolution invalid, return\n",
3708 __func__);
3709 retval = NI_RETCODE_INVALID_PARAM;
3710 LRETURN;
3711 }
3712 }
3713
3714 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter hwframes = %d\n", __func__,
3715 p_param->hwframes);
3716
3717#ifdef NI_HAVE_MCTF
3718 if (p_param->hwframes && p_param->useMCTF)
3719 {
3720 ni_log2(p_ctx, NI_LOG_ERROR,
3721 "ERROR: %s() MCTF does not support hwframe input, return\n",
3722 __func__);
3724 LRETURN;
3725 }
3726 if (p_param->useMCTF &&
3729 {
3730 ni_log2(p_ctx, NI_LOG_ERROR,
3731 "ERROR: %s() MCTF only supports 8-bit input, return\n",
3732 __func__);
3734 LRETURN;
3735 }
3736#endif
3737
3738 // Select the CPU based on the NUMA node.
3739 if (p_param->enableCpuAffinity)
3740 {
3741#if defined(__linux__) && defined(XCODER_ENABLE_CPU_AFFINITY)
3742 retval = ni_set_cpu_affinity(p_ctx);
3743 if (NI_RETCODE_SUCCESS != retval)
3744 {
3745 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ni_set_cpu_affinity failed, ret=%d\n",
3746 __func__, retval);
3747 LRETURN;
3748 }
3749#else
3750 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): not support enableCpuAffinity parameter, "
3751 "enable with [./build.sh -c] on linux\n", __func__);
3752#endif
3753 }
3754
3755 // calculate encoder ROI map size: each QP info takes 8-bit, represent 8 x 8
3756 // pixel block
3757 max_cu_size = (NI_CODEC_FORMAT_H264 == p_ctx->codec_format) ? 16 : 64;
3758
3759 width = p_param->source_width;
3760 height = p_param->source_height;
3761 // AV1 non-8x8-aligned resolution is implicitly cropped due to Quadra HW limitation
3762 if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
3763 {
3764 width = (width / 8) * 8;
3765 height = (height / 8) * 8;
3766 }
3767
3768 block_size =
3769 ((width + max_cu_size - 1) & (~(max_cu_size - 1))) *
3770 ((height + max_cu_size - 1) & (~(max_cu_size - 1))) /
3771 (8 * 8);
3772 p_ctx->roi_len = ((block_size + 63) & (~63)); // align to 64 bytes
3773
3774 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): finish init\n", __func__);
3775
3776 //Check if there is an instance or we need a new one
3777 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
3778 {
3780 p_ctx->pts_table = NULL;
3781 p_ctx->dts_queue = NULL;
3782 p_ctx->buffer_pool = NULL;
3783 p_ctx->status = 0;
3784 p_ctx->key_frame_type = 0;
3785 p_ctx->keyframe_factor = 1;
3786 p_ctx->frame_num = 0;
3787 p_ctx->pkt_num = 0;
3788 p_ctx->av1_pkt_num = 0;
3789 p_ctx->rc_error_count = 0;
3790 p_ctx->force_frame_type = 0;
3791 p_ctx->ready_to_close = 0;
3792 p_ctx->auto_dl_handle = 0;
3793 //Sequence change tracking related stuff
3794 p_ctx->active_video_width = 0;
3795 p_ctx->active_video_height = 0;
3796 p_ctx->p_all_zero_buf = NULL;
3797 p_ctx->actual_video_width = 0;
3798 p_ctx->enc_pts_w_idx = 0;
3799 p_ctx->enc_pts_r_idx = 0;
3800 p_ctx->session_timestamp = 0;
3801 memset((void *)p_ctx->pkt_custom_sei_set, 0, NI_FIFO_SZ * sizeof(ni_custom_sei_set_t *));
3802 memset(&(p_ctx->param_err_msg[0]), 0, sizeof(p_ctx->param_err_msg));
3804 {
3806 }
3807
3808 //malloc zero data buffer
3809 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
3811 {
3812 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc all zero buffer failed\n",
3813 NI_ERRNO, __func__);
3815 LRETURN;
3816 }
3817 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
3818
3819 //malloc data buffer
3820 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
3821 {
3822 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
3823 NI_ERRNO, __func__);
3826 LRETURN;
3827 }
3828 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
3829
3830 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
3831 //In case we can open sesison, the session id would become valid.
3832 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
3833 (uint16_t)NI_INVALID_SESSION_ID;
3834
3835 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
3837 ni_htonl(p_ctx->codec_format), 0);
3838 ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer,
3839 NI_DATA_BUFFER_LEN, ui32LBA);
3840 //Open will return a session status structure with a valid session id if it worked.
3841 //Otherwise the invalid session id set before the open command will stay
3842 p_ctx->session_id =
3843 ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
3844 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
3845 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
3846 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
3847 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
3848 {
3849 ni_log2(p_ctx, NI_LOG_ERROR,
3850 "ERROR %s(): p_ctx->device_handle=%" PRIx64 ", "
3851 "p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
3852 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
3853 p_ctx->session_id);
3854 ni_encoder_session_close(p_ctx, 0);
3856 LRETURN;
3857 }
3858 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder open session ID:0x%x timestamp:%" PRIu64 "\n",
3859 p_ctx->session_id, p_ctx->session_timestamp);
3860
3861 //Send keep alive timeout Info
3862 uint64_t keep_alive_timeout =
3863 (uint64_t)p_ctx->keep_alive_timeout * 1000000; //send us to FW
3864 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
3865 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
3866 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
3867 keep_alive_timeout);
3869 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
3870 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
3871 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
3872 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
3873 CHECK_VPU_RECOVERY(retval);
3874
3875 if (NI_RETCODE_SUCCESS != retval)
3876 {
3877 ni_log2(p_ctx, NI_LOG_ERROR,
3878 "ERROR %s(): nvme write keep_alive_timeout command "
3879 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
3880 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
3882 LRETURN;
3883 }
3884
3885 // Send SW version to FW if FW API version is >= 6.2
3887 "62") >= 0)
3888 {
3889 // Send SW version to session manager
3890 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
3891 memcpy(p_buffer, NI_XCODER_REVISION, sizeof(uint64_t));
3893 ni_fmt_fw_api_ver_str((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], &fmt_fw_api_ver2[0]);
3894 ni_log2(p_ctx, NI_LOG_DEBUG, "%s libxcoder FW API ver %s, FW FW API ver %s\n",
3895 __func__, fmt_fw_api_ver1, fmt_fw_api_ver2);
3896 ui32LBA = CONFIG_SESSION_SWVersion_W(p_ctx->session_id);
3897 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
3898 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
3899 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
3900 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
3901 CHECK_VPU_RECOVERY(retval);
3902
3903 if (NI_RETCODE_SUCCESS != retval)
3904 {
3905 ni_log2(p_ctx, NI_LOG_ERROR,
3906 "ERROR %s(): nvme write sw_version command "
3907 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
3908 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
3910 LRETURN;
3911 }
3912
3913 if (ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6sM") >= 0)
3914 {
3915 // For FW API ver 6sM or newer, initialize with the most current size
3916 p_ctx->meta_size = sizeof(ni_metadata_enc_bstream_t);
3917 }
3918 else if (ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rc") >= 0)
3919 {
3920 // For FW API ver 6rc or newer, initialize with the most current size
3922 }
3924 "6p") >= 0)
3925 // For FW API ver 6.p or newer, initialize with the most current size
3927 else
3928 // For FW API ver 6.2 or newer, initialize with the most current size
3930 }
3931 else
3932 {
3933 // For FW API ver 6.1 or older, initialize with metadata size 32
3935 }
3936
3937 // Open AI session for AI Enhance
3938 if(p_param->enable_ai_enhance)
3939 {
3940 // Check if the bit depth & resoultion
3941 if ((p_ctx->bit_depth_factor != 1) ||
3942 !((p_param->source_width == 1280 && p_param->source_height == 720) ||
3943 (p_param->source_width == 1920 && p_param->source_height == 1080) ||
3944 (p_param->source_width == 3840 && p_param->source_height == 2160) ||
3945 (p_param->source_width == 720 && p_param->source_height == 1280) ||
3946 (p_param->source_width == 768 && p_param->source_height == 1280) ||
3947 (p_param->source_width == 1080 && p_param->source_height == 1920) ||
3948 (p_param->source_width == 2496 && p_param->source_height == 1080)))
3949 {
3950 p_param->enable_ai_enhance = 0;
3951 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);
3952 ni_log2(p_ctx, NI_LOG_ERROR, "The bit depth or resoultion is not supported on ai enhance mode\n");
3953 }else{
3954 ni_log2(p_ctx, NI_LOG_DEBUG, "Adding ai enhance session to encoder\n");
3955 ui32LBA = OPEN_ADD_CODEC(NI_DEVICE_TYPE_AI, 0, ni_htons(p_ctx->session_id));
3956 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
3957 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
3958
3959 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_open,
3960 p_ctx->device_type, p_ctx->hw_id,
3961 &(p_ctx->session_id), OPT_1);
3962 if (NI_RETCODE_SUCCESS != retval)
3963 {
3964 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR couldn't add ai to encoder session\n");
3965 ni_log2(p_ctx, NI_LOG_ERROR,
3966 "ERROR %s(): p_ctx->device_handle=%" PRIx64 ", "
3967 "p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
3968 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
3969 p_ctx->session_id);
3970 ni_encoder_session_close(p_ctx, 0);
3971 LRETURN;
3972 }
3973 }
3974 }
3975
3977 {
3978 retval = ni_device_set_ddr_configuration(p_ctx, p_param->ddr_priority_mode);
3979 if (NI_RETCODE_SUCCESS != retval)
3980 {
3981 char errmsg[NI_ERRNO_LEN] = {0};
3983 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ddr priority setting failure for %s\n",
3984 __func__, errmsg);
3985 LRETURN;
3986 }
3987 }
3988
3989 ni_log2(p_ctx, NI_LOG_DEBUG, "Open session completed\n");
3990 }
3991
3992 /* Modify mmap_threshold and trim_threshold of malloc */
3993 // calculate the default threshold which equals to the resolution + padding size.
3994 // 64 is AV_INPUT_BUFFER_PADDING_SIZE
3995 m_threshold = p_param->source_width * p_param->source_height * 3 / 2 *
3996 p_ctx->bit_depth_factor + 64;
3997 m_threshold = ((m_threshold + (NI_MEM_PAGE_ALIGNMENT - 1)) /
3999
4000 // The upper limit is DEFAULT_MMAP_THRESHOLD_MAX: 512*1024 on 32-bit systems,
4001 // or 4*1024*1024*sizeof(long) on 64-bit systems.
4002 // This macro is not defined in header file.
4003 // So, assume that is running on 64-bit systems
4004 if (m_threshold > (size_t)4 * 1024 * 1024 * sizeof(long))
4005 {
4006 ni_log2(p_ctx, NI_LOG_INFO, "Warning: m_threshold (%d) is bigger than "
4007 "DEFAULT_MMAP_THRESHOLD_MAX, use default value (%d)\n",
4008 m_threshold, (size_t)4 * 1024 * 1024 * sizeof(long));
4009 m_threshold = (size_t)4 * 1024 * 1024 * sizeof(long);
4010 }
4011
4012 if (p_param->staticMmapThreshold) // Set Static Mmap Threshold
4013 {
4014#if defined(__linux__) && !defined(_ANDROID) && !defined(__OPENHARMONY__)
4015 // If the malloc buffer is larger than the threshold,
4016 // glibc will use mmap to malloc the memory, which is a low speed method.
4017 // So, set the M_MMAP_THRESHOLD >= 1 yuv buffer size here.
4018 if (mallopt(M_MMAP_THRESHOLD, m_threshold) == 0) // NOLINT(concurrency-mt-unsafe) - process-wide tuning at init
4019 {
4020 ni_log2(p_ctx, NI_LOG_ERROR, "Error: could not set M_MMAP_THRESHOLD to %d\n",
4021 m_threshold);
4023 LRETURN;
4024 }
4025
4026 // When the amount of contiguous free memory at the top of the heap
4027 // grows larger than M_TRIM_THRESHOLD,
4028 // free(3) employs sbrk(2) to release this memory back to the system.
4029 // So, set the M_TRIM_THRESHOLD to 3*m_threshold,
4030 // to avoid an inefficient case, frequently releasing and requesting physical memory.
4031 if (mallopt(M_TRIM_THRESHOLD, 3 * m_threshold) == 0) // NOLINT(concurrency-mt-unsafe) - process-wide tuning at init
4032 {
4033 ni_log2(p_ctx, NI_LOG_ERROR, "Error: could not set M_TRIM_THRESHOLD to %ds\n",
4034 3 * m_threshold);
4036 LRETURN;
4037 }
4038#else
4039 ni_log2(p_ctx, NI_LOG_INFO,
4040 "Warning: this platform does not support staticMmapThreshold\n");
4041#endif
4042 }
4043 else // default
4044 {
4045 // a way to dynamically trigger a pre-mature increase in mmap&trim threshold
4046 // make the mmap_threshold larger than frame size to avoid frequent page faults
4047 m_threshold = (int) (m_threshold * 1.25); // An experience value
4048 void *temp_buf = malloc((size_t) m_threshold);
4049 ni_log2(p_ctx, NI_LOG_TRACE, "trigger a pre-mature increase in mmap&trim threshold: 0x%p = malloc(%d)\n",
4050 temp_buf, m_threshold);
4051 free(temp_buf);
4052 }
4053
4054 if (p_ctx->hw_action == NI_CODEC_HW_ENABLE)
4055 {
4056 ni_device_capability_t sender_cap, receiver_cap;
4057 bool device_in_ctxt = true;
4058 retval = ni_device_capability_query2(p_ctx->sender_handle, &sender_cap, device_in_ctxt);
4059 if (retval != NI_RETCODE_SUCCESS)
4060 {
4061 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_device_capability_query2 returned %d\n",
4062 retval);
4063 LRETURN;
4064 }
4065 retval = ni_device_capability_query2(p_ctx->blk_io_handle, &receiver_cap, device_in_ctxt);
4066 if (retval != NI_RETCODE_SUCCESS)
4067 {
4068 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_device_capability_query2 returned %d\n",
4069 retval);
4070 LRETURN;
4071 }
4072
4073 for (uint8_t ui8Index = 0; ui8Index < 20; ui8Index++)
4074 {
4075 if (sender_cap.serial_number[ui8Index] !=
4076 receiver_cap.serial_number[ui8Index])
4077 {
4078 // QDFW-315 Autodownload
4079 p_ctx->auto_dl_handle = p_ctx->sender_handle;
4080 ni_log2(p_ctx, NI_LOG_DEBUG, "Autodownload device handle set %p!\n",
4081 p_ctx->auto_dl_handle);
4082 p_ctx->hw_action = NI_CODEC_HW_NONE;
4083 break;
4084 }
4085 else
4086 {
4088 "6m") >= 0)
4089 {
4090 ni_device_vf_ns_id_t sender_vf_ns_id = {0};
4091 ni_device_vf_ns_id_t curr_vf_ns_id = {0};
4092 retval = ni_query_vf_ns_id(p_ctx->sender_handle, &sender_vf_ns_id, p_ctx->fw_rev);
4093 if (retval != NI_RETCODE_SUCCESS)
4094 {
4095 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: calling ni_query_vf_ns_id(): "
4096 "p_ctx->sender_handle=%" PRIx64 ", p_ctx->hw_id=%d, p_ctx->session_id=%u\n",
4097 (int64_t)p_ctx->sender_handle, p_ctx->hw_id, p_ctx->session_id);
4098 ni_encoder_session_close(p_ctx, 0);
4099 LRETURN;
4100 }
4101 retval = ni_query_vf_ns_id(p_ctx->blk_io_handle, &curr_vf_ns_id, p_ctx->fw_rev);
4102 if (retval != NI_RETCODE_SUCCESS)
4103 {
4104 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: calling ni_query_vf_ns_id(): "
4105 "p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, p_ctx->session_id=%u\n",
4106 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
4107 ni_encoder_session_close(p_ctx, 0);
4108 LRETURN;
4109 }
4110
4111 if ((sender_vf_ns_id.ns_id != curr_vf_ns_id.ns_id) ||
4112 (sender_vf_ns_id.vf_id != curr_vf_ns_id.vf_id))
4113 {
4114 p_ctx->auto_dl_handle = p_ctx->sender_handle;
4115 ni_log2(p_ctx, NI_LOG_DEBUG, "Autodownload device handle set %p!\n",
4116 p_ctx->auto_dl_handle);
4117 p_ctx->hw_action = NI_CODEC_HW_NONE;
4118 break;
4119 }
4120 }
4121 }
4122 }
4123 }
4124
4126 if (NI_RETCODE_SUCCESS != retval)
4127 {
4128 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: calling ni_config_instance_set_encoder_params(): "
4129 "p_ctx->device_handle=%" PRIx64 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
4130 (int64_t)p_ctx->device_handle, p_ctx->hw_id, p_ctx->session_id);
4131 ni_encoder_session_close(p_ctx, 0);
4132 LRETURN;
4133 }
4134 if(p_param->enable_ai_enhance)
4135 {
4136 retval = ni_ai_query_network_ready(p_ctx);
4137 if(retval != NI_RETCODE_SUCCESS)
4138 {
4139 ni_log2(p_ctx, NI_LOG_ERROR,
4140 "ERROR: ni_ai_query_network_ready returned %d\n", retval);
4141 LRETURN;
4142 }
4143 }
4144
4145 ni_timestamp_init(p_ctx, &p_ctx->pts_table, "enc_pts");
4146 ni_timestamp_init(p_ctx, &p_ctx->dts_queue, "enc_dts");
4147
4148 // init close caption SEI header and trailer
4149 memcpy(p_ctx->itu_t_t35_cc_sei_hdr_hevc, g_itu_t_t35_cc_sei_hdr_hevc,
4151 memcpy(p_ctx->itu_t_t35_cc_sei_hdr_h264, g_itu_t_t35_cc_sei_hdr_h264,
4153 memcpy(p_ctx->itu_t_t35_cc_sei_hdr_av1, g_itu_t_t35_cc_sei_hdr_av1,
4155 memcpy(p_ctx->sei_trailer, g_sei_trailer, NI_CC_SEI_TRAILER_LEN);
4156 // init hdr10+ SEI header
4157 memcpy(p_ctx->itu_t_t35_hdr10p_sei_hdr_hevc, g_itu_t_t35_hdr10p_sei_hdr_hevc,
4159 memcpy(p_ctx->itu_t_t35_hdr10p_sei_hdr_h264, g_itu_t_t35_hdr10p_sei_hdr_h264,
4161 memcpy(p_ctx->itu_t_t35_hdr10p_sei_hdr_av1, g_itu_t_t35_hdr10p_sei_hdr_av1,
4163
4164 // query to check the final encoder config status
4165 for (;;)
4166 {
4168 NI_DEVICE_TYPE_ENCODER, &buf_info);
4169
4171 p_ctx->device_type, p_ctx->hw_id,
4172 &(p_ctx->session_id), OPT_1);
4173
4175 || NI_RETCODE_FAILURE == retval)
4176 {
4177 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() line-%d return %d\n", __func__, __LINE__, retval);
4178 LRETURN;
4179 }
4180 else if (buf_info.buf_avail_size > 0)
4181 {
4182 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): buf_avail_size %u\n", __func__,
4183 buf_info.buf_avail_size);
4184 break;
4185 }
4186 else
4187 {
4188 ni_usleep(1000);
4189 }
4190 }
4191
4192 ni_log2(p_ctx, NI_LOG_DEBUG,
4193 "%s(): p_ctx->device_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
4194 "p_ctx->session_id=%d\n",
4195 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
4196 p_ctx->session_id);
4197
4198#ifdef XCODER_DUMP_DATA
4199 char dir_name[256] = {0};
4200 (void)snprintf(dir_name, sizeof(dir_name), "%ld-%u-enc-pkt", (long)getpid(),
4201 p_ctx->session_id);
4202 DIR *dir = opendir(dir_name);
4203 if (!dir && ENOENT == NI_ERRNO)
4204 {
4205 mkdir(dir_name, S_IRWXU | S_IRWXG | S_IRWXO);
4206 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder pkt dump dir created: %s\n", dir_name);
4207 }
4208
4209 if(dir){
4210 closedir(dir);
4211 }
4212
4213 (void)snprintf(dir_name, sizeof(dir_name), "%ld-%u-enc-fme", (long)getpid(),
4214 p_ctx->session_id);
4215 dir = opendir(dir_name);
4216 if (!dir && ENOENT == NI_ERRNO)
4217 {
4218 mkdir(dir_name, S_IRWXU | S_IRWXG | S_IRWXO);
4219 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder frame dump dir created: %s\n", dir_name);
4220 }
4221 if(dir){
4222 closedir(dir);
4223 }
4224#endif
4225
4226END:
4227
4228 ni_aligned_free(p_buffer);
4229 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
4230
4231 return retval;
4232}
4233
4234/*!******************************************************************************
4235 * \brief Flush encoder output
4236 *
4237 * \param
4238 *
4239 * \return
4240 *******************************************************************************/
4242{
4243 ni_retcode_t retval;
4244 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
4245 if (!p_ctx)
4246 {
4247 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
4248 __func__);
4249 retval = NI_RETCODE_INVALID_PARAM;
4250 LRETURN;
4251 }
4252
4253 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
4254 {
4255 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
4256 __func__);
4258 LRETURN;
4259 }
4260
4263 p_ctx->device_type, p_ctx->hw_id,
4264 &(p_ctx->session_id), OPT_1);
4265 CHECK_VPU_RECOVERY(retval);
4266
4267END:
4268
4269 if (NI_RETCODE_SUCCESS != retval)
4270 {
4271 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): %d, return\n", __func__, retval);
4272 }
4273
4274 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
4275
4276 return retval;
4277}
4278
4279/*!******************************************************************************
4280 * \brief Close a xcoder encoder instance
4281 *
4282 * \param
4283 *
4284 * \return
4285 *******************************************************************************/
4287{
4288 (void)eos_recieved;
4290 void* p_buffer = NULL;
4291 uint32_t ui32LBA = 0;
4292 int i = 0;
4293 ni_xcoder_params_t *p_param = NULL;
4294
4295 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
4296
4297 if (!p_ctx)
4298 {
4299 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
4300 __func__);
4302 }
4303
4305
4306 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
4307 {
4308 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): Invalid session ID, return.\n", __func__);
4309 retval = NI_RETCODE_SUCCESS;
4310 LRETURN;
4311 }
4312
4313 if (p_ctx->device_type == NI_DEVICE_TYPE_ENCODER)
4314 {
4315 ni_log2(p_ctx, NI_LOG_INFO,
4316 "Encoder_complete_info:session_id 0x%x, total frames input:%u "
4317 "buffered: %u completed: %u output: %u dropped: %u error: %u\n",
4324 }
4325
4326 //malloc data buffer
4327 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
4328 {
4329 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
4330 NI_ERRNO, __func__);
4332 LRETURN;
4333 }
4334 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
4335
4336 if (p_ctx->p_session_config)
4337 {
4338 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
4340 {
4342 if (NI_RETCODE_SUCCESS != retval)
4343 {
4344 char errmsg[NI_ERRNO_LEN] = {0};
4346 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): ddr priority setting failure for %s\n",
4347 __func__, errmsg);
4348 LRETURN;
4349 }
4350 }
4351 }
4352
4354
4355 int retry = 0;
4356 while (retry < NI_SESSION_CLOSE_RETRY_MAX)
4357 {
4358 ni_log2(p_ctx, NI_LOG_DEBUG,
4359 "%s(): p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
4360 "p_ctx->session_id=%d, close_mode=1\n",
4361 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
4362 p_ctx->session_id);
4363
4365 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
4366 {
4367 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): command failed\n", __func__);
4370 break;
4371 } else
4372 {
4373 //Close should always succeed
4374 retval = NI_RETCODE_SUCCESS;
4376 break;
4377 }
4378 /*
4379 else if(((ni_session_closed_status_t *)p_buffer)->session_closed)
4380 {
4381 retval = NI_RETCODE_SUCCESS;
4382 p_ctx->session_id = NI_INVALID_SESSION_ID;
4383 break;
4384 }
4385 else
4386 {
4387 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): wait for close\n");
4388 ni_usleep(NI_SESSION_CLOSE_RETRY_INTERVAL_US);
4389 retval = NI_RETCODE_ERROR_NVME_CMD_FAILED;
4390 }
4391 */
4392 retry++;
4393 }
4394
4395END:
4396
4397 ni_aligned_free(p_buffer);
4399#ifdef NI_HAVE_MCTF
4400 clearMCTF(p_ctx);
4401#endif
4402
4403 //Sequence change related stuff cleanup here
4404 p_ctx->active_video_width = 0;
4405 p_ctx->active_video_height = 0;
4406 p_ctx->actual_video_width = 0;
4407 //End of sequence change related stuff cleanup
4408
4409 if (p_ctx->pts_table)
4410 {
4411 ni_queue_free(&p_ctx->pts_table->list, p_ctx->buffer_pool);
4412 ni_memfree(p_ctx->pts_table);
4413 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_timestamp_done: success\n");
4414 }
4415
4416 if (p_ctx->dts_queue)
4417 {
4418 ni_queue_free(&p_ctx->dts_queue->list, p_ctx->buffer_pool);
4419 ni_memfree(p_ctx->dts_queue);
4420 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_timestamp_done: success\n");
4421 }
4422
4424 p_ctx->buffer_pool = NULL;
4425
4426 for (i = 0; i < NI_FIFO_SZ; i++)
4427 {
4428 ni_memfree(p_ctx->pkt_custom_sei_set[i]);
4429 }
4430
4431 for (i = 0; i < 120 ; i++)
4432 {
4433 if (p_ctx->input_frame_fifo[i].p_input_buffer != NULL)
4434 {
4435 free(p_ctx->input_frame_fifo[i].p_input_buffer);
4436 p_ctx->input_frame_fifo[i].p_input_buffer = NULL;
4437 }
4438 }
4439
4440 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): CTX[Card:%" PRIx64 " / HW:%d / INST:%d]\n",
4441 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
4442 p_ctx->session_id);
4443 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
4444
4445 low_delay_signal(p_ctx);
4447
4448 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
4449
4450 return retval;
4451}
4452
4453
4454void enqueue_ni_frame(ni_session_context_t *p_ctx, ni_frame_t *ni_frame, int32_t source_width, int32_t source_height)
4455{
4456 int32_t width_stride[4] = {0};
4457 int32_t height_stride[4] = {0};
4458
4459 if (((ni_xcoder_params_t *)(p_ctx->p_session_config))->zerocopy_mode &&
4460 ((ni_xcoder_params_t *)(p_ctx->p_session_config))->luma_linesize != 0 &&
4461 ((ni_xcoder_params_t *)(p_ctx->p_session_config))->chroma_linesize != 0)
4462 {
4463 //zero copy happend
4464 width_stride[0] = ((ni_xcoder_params_t *)(p_ctx->p_session_config))->luma_linesize;
4465 width_stride[1] = width_stride[2] = ((ni_xcoder_params_t *)(p_ctx->p_session_config))->chroma_linesize;
4466 }
4467 else
4468 {
4469 int is_semiplanar = !ni_get_planar_from_pixfmt(p_ctx->pixel_format);
4470 ni_get_hw_yuv420p_dim((int)ni_frame->video_width, (int)ni_frame->video_height,
4471 p_ctx->bit_depth_factor, is_semiplanar,
4472 width_stride, height_stride);
4473 }
4474
4475 for (int i = 0; i < 120; i++)
4476 {
4477 // 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",
4478 // __FUNCTION__, __LINE__, i, p_ctx->frame_num, p_ctx->input_frame_fifo[i].p_input_buffer,
4479 // ni_frame->data_len[0], ni_frame->data_len[1], ni_frame->data_len[2],
4480 // ni_frame->p_data[0], ni_frame->p_data[1], ni_frame->p_data[2],
4481 // ni_frame->video_width, ni_frame->video_height);
4482 if ((source_width != p_ctx->input_frame_fifo[i].video_width ||
4483 source_height != p_ctx->input_frame_fifo[i].video_height) &&
4484 p_ctx->input_frame_fifo[i].p_input_buffer != NULL &&
4485 p_ctx->input_frame_fifo[i].usable == 1)
4486 {
4487 free(p_ctx->input_frame_fifo[i].p_input_buffer);
4488 p_ctx->input_frame_fifo[i].p_input_buffer = NULL;
4489 p_ctx->input_frame_fifo[i].usable = -1;
4490 }
4491
4492 if (p_ctx->input_frame_fifo[i].p_input_buffer == NULL)
4493 {
4494 p_ctx->input_frame_fifo[i].p_input_buffer = (uint8_t *)malloc(source_width * p_ctx->bit_depth_factor * source_height * 3 / 2);
4495
4496 for (int j = 0; j < source_height; j++)
4497 {
4498 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + (ptrdiff_t)source_width * p_ctx->bit_depth_factor * j,
4499 ni_frame->p_data[0] + (ptrdiff_t)j * width_stride[0],
4500 (size_t)source_width * p_ctx->bit_depth_factor);
4501 }
4502 for (int j = 0; j < (source_height + 1) / 2; j++)
4503 {
4504 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + (ptrdiff_t)source_width * p_ctx->bit_depth_factor * source_height + ((ptrdiff_t)source_width * p_ctx->bit_depth_factor / 2) * j,
4505 ni_frame->p_data[1] + (ptrdiff_t)j * width_stride[1],
4506 (size_t)source_width / 2 * p_ctx->bit_depth_factor);
4507 }
4508 for (int j = 0; j < (source_height + 1) / 2; j++)
4509 {
4510 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + (ptrdiff_t)source_width * p_ctx->bit_depth_factor * source_height * 5 / 4 + ((ptrdiff_t)source_width * p_ctx->bit_depth_factor / 2) * j,
4511 ni_frame->p_data[2] + (ptrdiff_t)j * width_stride[2],
4512 (size_t)source_width / 2 * p_ctx->bit_depth_factor);
4513 }
4514
4515 p_ctx->input_frame_fifo[i].video_width = source_width;
4516 p_ctx->input_frame_fifo[i].video_height = source_height;
4517
4518 p_ctx->input_frame_fifo[i].usable = -1;
4519 p_ctx->input_frame_fifo[i].pts = ni_frame->pts;
4520 // 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",
4521 // __FUNCTION__, __LINE__, i, p_ctx->frame_num, ni_frame->buffer_size, ni_frame->video_width, ni_frame->video_height,
4522 // p_ctx->input_frame_fifo[i].pts);
4523 break;
4524 }
4525 else if (p_ctx->input_frame_fifo[i].usable == 1)
4526 {
4527 for (int j = 0; j < source_height; j++)
4528 {
4529 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + (ptrdiff_t)source_width * p_ctx->bit_depth_factor * j,
4530 ni_frame->p_data[0] + (ptrdiff_t)j * width_stride[0],
4531 (size_t)source_width * p_ctx->bit_depth_factor);
4532 }
4533 for (int j = 0; j < (source_height + 1) / 2; j++)
4534 {
4535 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + (ptrdiff_t)source_width * p_ctx->bit_depth_factor * source_height + ((ptrdiff_t)source_width * p_ctx->bit_depth_factor / 2) * j,
4536 ni_frame->p_data[1] + (ptrdiff_t)j * width_stride[1],
4537 (size_t)source_width / 2 * p_ctx->bit_depth_factor);
4538 }
4539 for (int j = 0; j < (source_height + 1) / 2; j++)
4540 {
4541 memcpy(p_ctx->input_frame_fifo[i].p_input_buffer + (ptrdiff_t)source_width * p_ctx->bit_depth_factor * source_height * 5 / 4 + ((ptrdiff_t)source_width * p_ctx->bit_depth_factor / 2) * j,
4542 ni_frame->p_data[2] + (ptrdiff_t)j * width_stride[2],
4543 (size_t)source_width / 2 * p_ctx->bit_depth_factor);
4544 }
4545
4546 p_ctx->input_frame_fifo[i].video_width = source_width;
4547 p_ctx->input_frame_fifo[i].video_height = source_height;
4548
4549 p_ctx->input_frame_fifo[i].usable = -1;
4550 p_ctx->input_frame_fifo[i].pts = ni_frame->pts;
4551 break;
4552 }
4553 }
4554}
4555
4556/*!******************************************************************************
4557 * \brief Send a YUV p_frame to encoder
4558 *
4559 * \param
4560 *
4561 * \return
4562 *******************************************************************************/
4564{
4565 bool ishwframe = false;
4566 uint32_t size = 0;
4567 uint32_t send_count = 0;
4568 uint32_t i = 0;
4569 uint32_t sent_size = 0;
4570 uint32_t frame_size_bytes = 0;
4571 int retval = 0;
4572 ni_instance_buf_info_t buf_info = { 0 };
4573 ni_session_statistic_t sessionStatistic = {0};
4574#ifdef NI_HAVE_MCTF
4575 ni_frame_t* p_orig_frame = NULL;
4576 bool checkMCTF = false;
4577 int waitCnt = MCTF_LOOKAHEAD;
4578#endif
4579
4580 if (!p_ctx || !p_frame)
4581 {
4582 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
4583 __func__);
4585 }
4586
4587#ifdef NI_HAVE_MCTF
4588 checkMCTF = ((ni_xcoder_params_t *)p_ctx->p_session_config)->useMCTF;
4589#endif
4590 ishwframe = p_ctx->hw_action & NI_CODEC_HW_ENABLE;
4591 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter hw=%d\n", __func__, ishwframe);
4592
4593 if (ishwframe && !p_frame->end_of_stream)
4594 {
4595 // check if the hw input frame is valid
4596 if (!p_frame->p_data[3])
4597 {
4598 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() hw input frame is null!, return\n",
4599 __func__);
4601 }
4602 uint16_t input_frame_idx = ((niFrameSurface1_t*)(p_frame->p_data[3]))->ui16FrameIdx;
4603 if (!((input_frame_idx > 0 &&
4604 input_frame_idx < NI_GET_MAX_HWDESC_FRAME_INDEX(p_ctx->ddr_config)) ||
4605 (input_frame_idx > NI_GET_MIN_HWDESC_P2P_BUF_ID(p_ctx->ddr_config) &&
4606 input_frame_idx <= NI_GET_MAX_HWDESC_P2P_BUF_ID(p_ctx->ddr_config))))
4607 {
4608 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): got invalid frameIdx [%u]\n",
4609 __func__, input_frame_idx);
4611 }
4612 }
4613
4615
4616 uint8_t separate_metadata = 0;
4617 uint8_t separate_start = 0;
4618
4619 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
4620 {
4621 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
4622 __func__);
4624 LRETURN;
4625 }
4626
4627#ifdef NI_HAVE_MCTF
4628 bool is_eos = p_frame->end_of_stream ? true : false;
4629 p_orig_frame = p_frame;
4630#endif
4631
4632 low_delay_wait(p_ctx);
4633
4634#ifdef MEASURE_LATENCY
4635 if ((p_frame->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
4636 {
4637 uint64_t abs_time_ns = ni_gettime_ns();
4638 ni_lat_meas_q_t *frame_time_q = (ni_lat_meas_q_t *)p_ctx->frame_time_q;
4639 ni_lat_meas_q_add_entry(frame_time_q, abs_time_ns, p_frame->dts);
4640 }
4641#endif
4642
4643 /*!********************************************************************/
4644 /*!************ Sequence Change related stuff *************************/
4645 //First check squence changed related stuff.
4646 //We need to record the current hight/width params if we didn't do it before:
4647
4648#ifdef NI_HAVE_MCTF
4649start_write:
4650 send_count = 0;
4651 if (waitCnt > 0 && waitCnt < MCTF_LOOKAHEAD && p_frame != p_orig_frame) {
4652 // send mctf buffered frame
4653 p_frame = get_mctf_result(p_ctx, waitCnt);
4654 waitCnt -= 1;
4655 }
4656
4657 if (is_eos && p_frame == p_orig_frame && p_ctx->frame_num > 0 &&
4658 p_ctx->mctf != NULL) {
4659 checkMCTF = false;
4660 // check if there's pending frame
4661 int ret = performMCTF(p_ctx, p_frame, p_frame->video_width, p_frame->video_height);
4662 if (ret == MCTF_RET_EOS_PENDING && waitCnt > 0) {
4663 p_frame = get_mctf_result(p_ctx, waitCnt);
4664 waitCnt -= 1;
4665 } else if (ret == MCTF_RET_EOS_DONE) {
4666 clearMCTF(p_ctx);
4667 }
4668 }
4669#endif
4670
4671 if( p_frame->video_height)
4672 {
4673 p_ctx->active_video_width = p_frame->data_len[0] / p_frame->video_height;
4674 p_ctx->active_video_height = p_frame->video_height;
4675 }
4676 else if (p_frame->video_width)
4677 {
4678 ni_log2(p_ctx, NI_LOG_DEBUG, "WARNING: passed video_height is not valid!, return\n");
4679 p_ctx->active_video_height = p_frame->data_len[0] / p_frame->video_width;
4680 p_ctx->active_video_width = p_frame->video_width;
4681 }
4682 else
4683 {
4684 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: passed video_height and video_width are not valid!, return\n");
4686 LRETURN;
4687 }
4688 // record actual width (in pixels / without padding) for sequnce change detection
4689 p_ctx->actual_video_width = p_frame->video_width;
4690
4691 /*!************ Sequence Change related stuff end*************************/
4692 /*!********************************************************************/
4693
4694 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;
4695 ni_log2(p_ctx, NI_LOG_DEBUG,
4696 "%s: data_len[0] %u data_len[1] %u "
4697 "data_len[2] %u extra_data_len %u frame_size_bytes %u\n",
4698 __func__, p_frame->data_len[0], p_frame->data_len[1],
4699 p_frame->data_len[2], p_frame->extra_data_len, frame_size_bytes);
4700
4701 // skip query write buffer because we just send EOS
4702 if (!p_frame->end_of_stream)
4703 {
4704 for (;;)
4705 {
4706 query_sleep(p_ctx);
4707
4709 "65") >= 0)
4710 {
4712 p_ctx, NI_DEVICE_TYPE_ENCODER, &sessionStatistic);
4713 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
4715 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
4716 CHECK_VPU_RECOVERY(retval);
4717 buf_info.buf_avail_size = sessionStatistic.ui32WrBufAvailSize;
4718 } else
4719 {
4720 retval =
4722 NI_DEVICE_TYPE_ENCODER, &buf_info);
4723 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
4724 p_ctx->device_type, p_ctx->hw_id,
4725 &(p_ctx->session_id), OPT_1);
4726 CHECK_VPU_RECOVERY(retval);
4727 }
4728
4729 if (NI_RETCODE_FAILURE == retval)
4730 {
4731 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() line-%d retrun %d\n", __func__, __LINE__, retval);
4732 LRETURN;
4733 }
4734 else if (NI_RETCODE_SUCCESS != retval ||
4735 buf_info.buf_avail_size < frame_size_bytes)
4736 {
4737 ni_log2(p_ctx, NI_LOG_TRACE,
4738 "Enc write query retry %d. rc=%d. Available buf size %u < "
4739 "frame size %u\n", retval, send_count,
4740 buf_info.buf_avail_size, frame_size_bytes);
4741 if (send_count >= NI_MAX_ENCODER_QUERY_RETRIES)
4742 {
4743 int retval_backup = retval;
4747 {
4748 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
4749 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
4750 CHECK_VPU_RECOVERY(retval);
4751 }
4752 else
4753 retval = NI_RETCODE_SUCCESS;
4754
4755 ni_log2(p_ctx, NI_LOG_DEBUG,
4756 "Enc write query buf info exceeded max retries: "
4757 "%d, rc=%d. Available buf size %u < frame size %u\n",
4758 NI_MAX_ENCODER_QUERY_RETRIES, retval_backup,
4759 buf_info.buf_avail_size, frame_size_bytes);
4761
4762 LRETURN;
4763 }
4764 send_count++;
4768 } else
4769 {
4770 ni_log2(p_ctx, NI_LOG_DEBUG,
4771 "Info enc write query success, available buf "
4772 "size %u >= frame size %u !\n",
4773 buf_info.buf_avail_size, frame_size_bytes);
4774 break;
4775 }
4776 }
4777 }
4778
4779#ifdef NI_HAVE_MCTF
4780 if (checkMCTF && p_ctx->mctf == NULL && !is_eos)
4781 {
4782 int ret = initMCTF(p_ctx);
4783 if (ret < 0)
4784 {
4785 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() initMCTF failed with %d, return\n",
4786 __func__, ret);
4788 LRETURN;
4789 }
4790 }
4791 if (checkMCTF && !p_frame->end_of_stream) {
4792 int ret = performMCTF(p_ctx, p_frame, p_frame->video_width, p_frame->video_height);
4793 if (ret == MCTF_RET_NOT_REF || ret == MCTF_RET_LOOKBACK_REF) {
4794 // not used by MCTF or lookback reference frame, send current frame as is
4795 } else if (ret == MCTF_RET_BUFFERED) {
4796 // need to wait for next frame, current frame is buffered internally
4797 // return fake write complete
4798 p_ctx->status = 0;
4799 p_ctx->low_delay_sync_flag = 1;
4800 retval = frame_size_bytes;
4801 LRETURN;
4802 } else if (ret == MCTF_RET_FILTERED) {
4803 // MCTF is performed, need to write the filtered frame first, then write current frame
4804 if (waitCnt > 0) {
4805 p_frame = get_mctf_result(p_ctx, waitCnt);
4806 waitCnt -= 1;
4807 }
4808 } else {
4809 retval = NI_RETCODE_FAILURE;
4810 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() performMCTF failed with %d, return\n",
4811 __func__, ret);
4812 LRETURN;
4813 }
4814 }
4815#endif
4816
4817 // Re-evaluate metadata/start-buffer mode after MCTF may have swapped p_frame.
4818 separate_metadata = p_frame->separate_metadata;
4819 separate_start =
4820 (p_frame->separate_start && p_frame->total_start_len) ? 1 : 0;
4821
4822 // fill in metadata such as timestamp
4824 if (separate_metadata)
4825 {
4826 p_meta = (ni_metadata_enc_frame_t *)p_frame->p_metadata_buffer;
4827 } else
4828 {
4829 p_meta = (ni_metadata_enc_frame_t *)((uint8_t *)
4830 p_frame->p_data[2 + ishwframe] +
4831 p_frame->data_len[2 + ishwframe]);
4832 }
4833
4834 if (p_meta) //When hwframe xcoding reaches eos, frame looks like swframe but no allocation for p_meta
4835 {
4836 p_meta->metadata_common.ui64_data.frame_tstamp = (uint64_t)p_frame->pts;
4837
4838 p_meta->force_headers = 0; // p_frame->force_headers not implemented/used
4841 p_meta->use_long_term_ref = p_frame->use_long_term_ref;
4842
4843 ni_log2(p_ctx, NI_LOG_DEBUG,
4844 "%s: p_meta "
4845 "use_cur_src_as_long_term_pic %d use_long_term_ref %d\n",
4846 __func__, p_meta->use_cur_src_as_long_term_pic,
4847 p_meta->use_long_term_ref);
4848
4849 p_meta->frame_force_type_enable = p_meta->frame_force_type = 0;
4850 // frame type to be forced to is supposed to be set correctly
4851 // in p_frame->ni_pict_type
4852 if (1 == p_ctx->force_frame_type || p_frame->force_key_frame)
4853 {
4854 if (p_frame->ni_pict_type)
4855 {
4856 p_meta->frame_force_type_enable = 1;
4857 p_meta->frame_force_type = p_frame->ni_pict_type;
4858 }
4859 ni_log2(p_ctx, NI_LOG_DEBUG,
4860 "%s(): ctx->force_frame_type"
4861 " %d frame->force_key_frame %d force frame_num %" PRIu64 ""
4862 " type to %d\n",
4863 __func__, p_ctx->force_frame_type, p_frame->force_key_frame,
4864 p_ctx->frame_num, p_frame->ni_pict_type);
4865 }
4866
4867 // force pic qp if specified
4868 p_meta->force_pic_qp_enable = p_meta->force_pic_qp_i =
4869 p_meta->force_pic_qp_p = p_meta->force_pic_qp_b = 0;
4870 if (p_frame->force_pic_qp)
4871 {
4872 p_meta->force_pic_qp_enable = 1;
4873 p_meta->force_pic_qp_i = p_meta->force_pic_qp_p =
4874 p_meta->force_pic_qp_b = p_frame->force_pic_qp;
4875 }
4876 p_meta->frame_sei_data_size = p_frame->sei_total_len;
4877 p_meta->frame_roi_map_size = p_frame->roi_len;
4878 p_meta->frame_roi_avg_qp = p_ctx->roi_avg_qp;
4879 p_meta->enc_reconfig_data_size = p_frame->reconf_len;
4880 p_meta->hor_adjust_offset = p_frame->hor_adjust_offset / ((p_ctx->src_bit_depth == 10) ? 2 : 1);
4881 // Reset it for the next frame
4882 p_frame->hor_adjust_offset = 0;
4883 ni_log2(p_ctx, NI_LOG_DEBUG,
4884 "### %s(): p_meta->hor_adjust_offset %d src_bit_depth %d\n", __func__, p_meta->hor_adjust_offset, p_ctx->src_bit_depth);
4885 p_meta->timecode_present = p_frame->timecode_present;
4886 p_frame->timecode_present = 0;
4887
4889 "6Q") >= 0)
4890 {
4891 if (separate_start)
4892 {
4893 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
4894 p_meta->start_len[i] = p_frame->start_len[i];
4895 }
4896 else
4897 {
4898 memset(p_meta->start_len, 0, sizeof(p_meta->start_len));
4899 }
4901 }
4902
4903 if (p_ctx->frame_num % ((ni_xcoder_params_t *)(p_ctx->p_session_config))->interval_of_psnr == 0)
4904 p_meta->get_recon_frame_mode = ((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode;
4905 else
4906 p_meta->get_recon_frame_mode = 3;
4907
4908 ni_log2(p_ctx,
4910 "%s(): %d.%u p_ctx->frame_num=%" PRIu64 ", "
4911 "p_frame->start_of_stream=%u, p_frame->end_of_stream=%u, "
4912 "p_frame->video_width=%u, p_frame->video_height=%u, pts=0x%08x 0x%08x, "
4913 "dts=0x%08x 0x%08x, sei_len=%u, roi size=%u avg_qp=%u reconf_len=%u "
4914 "force_pic_qp=%u use_cur_src_as_long_term_pic %u use_long_term_ref "
4915 "%u start_len [%u,%u,%u] inconsecutive_transfer %u "
4916 "get_recon_frame_mode %u\n",
4917 __func__, p_ctx->hw_id, p_ctx->session_id, p_ctx->frame_num,
4918 p_frame->start_of_stream, p_frame->end_of_stream, p_frame->video_width,
4919 p_frame->video_height, (uint32_t)((p_frame->pts >> 32) & 0xFFFFFFFF),
4920 (uint32_t)(p_frame->pts & 0xFFFFFFFF),
4921 (uint32_t)((p_frame->dts >> 32) & 0xFFFFFFFF),
4922 (uint32_t)(p_frame->dts & 0xFFFFFFFF), p_meta->frame_sei_data_size,
4923 p_meta->frame_roi_map_size, p_meta->frame_roi_avg_qp,
4924 p_meta->enc_reconfig_data_size, p_meta->force_pic_qp_i,
4926 p_meta->start_len[0], p_meta->start_len[1], p_meta->start_len[2],
4927 p_meta->inconsecutive_transfer,
4928 p_meta->get_recon_frame_mode);
4929 }
4930 if (p_frame->start_of_stream)
4931 {
4932 //Send Start of stream p_config command here
4935 p_ctx->device_type, p_ctx->hw_id,
4936 &(p_ctx->session_id), OPT_1);
4937 CHECK_VPU_RECOVERY(retval);
4938 if (NI_RETCODE_SUCCESS != retval)
4939 {
4940 LRETURN;
4941 }
4942
4943 p_frame->start_of_stream = 0;
4944 }
4945
4946 // skip direct to send eos without sending the passed in p_frame as it's been sent already
4947 if (p_frame->end_of_stream)
4948 {
4951 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
4952 CHECK_VPU_RECOVERY(retval);
4953 if (NI_RETCODE_SUCCESS != retval)
4954 {
4955 LRETURN;
4956 }
4957
4958 p_frame->end_of_stream = 0;
4959 p_ctx->ready_to_close = 1;
4960 } else //handle regular frame sending
4961 {
4962 retval = ni_timestamp_register(p_ctx->buffer_pool, p_ctx->dts_queue,
4963 p_frame->dts, 0);
4964 if (NI_RETCODE_SUCCESS != retval)
4965 {
4966 ni_log2(p_ctx, NI_LOG_ERROR,
4967 "ERROR %s(): "
4968 "ni_timestamp_register() for dts returned: %d\n",
4969 __func__, retval);
4970 }
4971
4972 if (separate_metadata)
4973 {
4974 uint32_t ui32LBA_metadata =
4976 ni_log2(p_ctx, NI_LOG_DEBUG,
4977 "%s: p_metadata_buffer = %p, metadata_buffer_size "
4978 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
4979 __func__, p_frame->p_metadata_buffer,
4980 p_frame->metadata_buffer_size, p_ctx->frame_num,
4981 ui32LBA_metadata);
4982
4983 sent_size =
4985
4986 retval = ni_nvme_send_write_cmd(
4987 p_ctx->blk_io_handle, p_ctx->event_handle,
4988 p_frame->p_metadata_buffer, sent_size,
4989 ui32LBA_metadata);
4990 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
4991 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
4992 CHECK_VPU_RECOVERY(retval);
4993 if (retval < 0)
4994 {
4995 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n",
4996 __func__);
4998 LRETURN;
4999 }
5000 }
5001
5002 if (separate_start)
5003 {
5004 uint32_t ui32LBA =
5006 ni_log2(p_ctx, NI_LOG_DEBUG,
5007 "%s: p_start_buffer = %p, p_frame->start_buffer_size "
5008 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
5009 __func__, p_frame->p_start_buffer, p_frame->start_buffer_size, p_ctx->frame_num,
5010 ui32LBA);
5011
5012 sent_size =
5014
5015 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5016 p_frame->p_start_buffer, sent_size, ui32LBA);
5017 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
5018 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5019 CHECK_VPU_RECOVERY(retval);
5020 if (retval < 0)
5021 {
5022 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
5024 LRETURN;
5025 }
5026 }
5027
5028 if (p_frame->inconsecutive_transfer)
5029 {
5030 uint32_t ui32LBA =
5032
5033 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
5034 {
5035 ni_log2(p_ctx, NI_LOG_DEBUG,
5036 "%s: p_data = %p, p_frame->buffer_size "
5037 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
5038 __func__, p_frame->p_data, p_frame->buffer_size, p_ctx->frame_num,
5039 ui32LBA);
5040
5041 if (p_frame->data_len[i])
5042 {
5043 sent_size = p_frame->data_len[i];
5044 if (separate_start)
5045 sent_size -= p_frame->start_len[i];
5046
5047 sent_size =
5049
5050 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5051 p_frame->p_data[i]+p_frame->start_len[i], sent_size, ui32LBA);
5052 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
5053 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5054 CHECK_VPU_RECOVERY(retval);
5055 if (retval < 0)
5056 {
5057 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
5059 LRETURN;
5060 }
5061 }
5062 }
5063 }
5064 else
5065 {
5066 uint32_t ui32LBA =
5068 ni_log2(p_ctx, NI_LOG_DEBUG,
5069 "%s: p_data = %p, p_frame->buffer_size "
5070 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
5071 __func__, p_frame->p_data, p_frame->buffer_size, p_ctx->frame_num,
5072 ui32LBA);
5073
5074 sent_size = frame_size_bytes;
5075 if (separate_metadata)
5076 sent_size -= p_frame->extra_data_len;
5077 if (separate_start)
5078 sent_size -= p_frame->total_start_len;
5079
5080 sent_size =
5082
5083 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5084 p_frame->p_buffer+p_frame->total_start_len, sent_size, ui32LBA);
5085 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
5086 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5087 CHECK_VPU_RECOVERY(retval);
5088 if (retval < 0)
5089 {
5090 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
5092 LRETURN;
5093 }
5094 }
5095
5096 //Save input frame data used for calculate PSNR
5097 if ((ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rc") >= 0) &&
5098 (p_ctx->frame_num == 0 || ((p_ctx->frame_num % ((ni_xcoder_params_t *)(p_ctx->p_session_config))->interval_of_psnr) == 0)) &&
5099 (((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode < 3) &&
5100 (!(((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.get_psnr_mode == 2 && p_ctx->codec_format == NI_CODEC_FORMAT_H265)))
5101 {
5102 if (ishwframe && !p_frame->end_of_stream)
5103 {
5104 // uint16_t input_frame_idx = ((niFrameSurface1_t*)(p_frame->p_data[3]))->ui16FrameIdx;
5105 // use hwdownload to download hw frame, but donot recycle hwframe buffer
5106 ni_session_data_io_t hwdl_session_data = {0};
5107 // ni_log2(p_ctx, NI_LOG_ERROR, "pixel_format %d\n", p_ctx->pixel_format);
5108 int ret = hwdl_frame(p_ctx, &hwdl_session_data, p_frame,
5109 p_frame->pixel_format);
5110 if (ret <= 0)
5111 {
5112 ni_frame_buffer_free(&(hwdl_session_data.data.frame));
5113 return ret;
5114 }
5115
5116 hwdl_session_data.data.frame.pts = p_frame->pts;
5117 enqueue_ni_frame(p_ctx, &hwdl_session_data.data.frame, (int32_t)p_frame->video_width, (int32_t)p_frame->video_height);
5118 ni_frame_buffer_free(&hwdl_session_data.data.frame);
5119 }
5120 else
5121 {
5122 enqueue_ni_frame(p_ctx, p_frame, (int32_t)p_frame->video_width, (int32_t)p_frame->video_height);
5123 }
5124 }
5125
5126 if (ishwframe)
5127 {
5128 ni_log2(p_ctx, NI_LOG_DEBUG,
5129 "%s(): session=0x%x ui16FrameIdx=%u\n",
5130 __func__,
5131 p_ctx->session_id,
5132 ((niFrameSurface1_t*)(p_frame->p_data[3]))->ui16FrameIdx);
5133 }
5134
5135 p_ctx->status = 0;
5136 p_ctx->frame_num++;
5137 size = frame_size_bytes;
5138 p_ctx->low_delay_sync_flag = 1;
5139
5140#ifdef NI_HAVE_MCTF
5141 if (p_orig_frame != p_frame)
5142 {
5143 if (waitCnt > 0) {
5144 // go back to send next buffered frame
5145 }
5146 else {
5147 // go back to send the original frame
5148 p_frame = p_orig_frame;
5149 }
5150 checkMCTF = false;
5151 goto start_write;
5152 }
5153#endif
5154
5155#ifdef XCODER_DUMP_DATA
5156 char dump_file[256];
5157 (void)snprintf(dump_file, sizeof(dump_file), "%ld-%u-enc-fme/fme-%04ld.yuv",
5158 (long)getpid(), p_ctx->session_id, (long)p_ctx->frame_num);
5159
5160 FILE *f = NULL;
5161 ni_fopen(&f, dump_file, "wb");
5162 (void)fwrite(p_frame->p_buffer,
5163 p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2],
5164 1, f);
5165 (void)fflush(f);
5166 (void)fclose(f);
5167#endif
5168 }
5169
5170 retval = (int)size;
5171
5172END:
5173
5175
5176 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
5177 return retval;
5178}
5179
5180// DEBUG
5181#if 0
5182// write bitstream features to log file
5183static void ni_write_bitstream_features_internal(ni_session_context_t *p_enc_ctx, ni_packet_t *p_out_pkt)
5184{
5186 int video_codec_id = VODEO_CODEC_ID_H264;
5187 int profile = H264_CODEC_PROFILE_MAIN;
5188
5189 if (!p_enc_ctx || !p_out_pkt || !p_enc_ctx->p_session_config ||
5190 !(((ni_xcoder_params_t *)(p_enc_ctx->p_session_config))->cfg_enc_params.getBitstreamFeatures))
5191 {
5192 return;
5193 }
5194
5196 (p_out_pkt->frame_type == NI_QUADRA_PREDICTED_FRAME) ? ITU_FRAME_TYPE_P :
5198
5199 video_codec_id = (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H264) ? VODEO_CODEC_ID_H264 :
5200 (p_enc_ctx->codec_format == NI_CODEC_FORMAT_H265) ? VODEO_CODEC_ID_HEVC :
5201 (p_enc_ctx->codec_format == NI_CODEC_FORMAT_AV1) ? VODEO_CODEC_ID_AV1 : 0;
5202
5203 profile = ((ni_xcoder_params_t *)(p_enc_ctx->p_session_config))->cfg_enc_params.profile;
5204
5205 switch (video_codec_id)
5206 {
5212 break;
5214 profile = (profile == NI_QUADRA_HEVC_PROFILE_MAIN) ? HEVC_CODEC_PROFILE_MAIN :
5216 break;
5217 case VODEO_CODEC_ID_AV1:
5218 profile = (profile == NI_QUADRA_AV1_PROFILE_MAIN) ? AV1_CODEC_PROFILE_MAIN : 0;
5219 break;
5220 default:
5221 profile = 0;
5222 break;
5223 }
5224
5225
5226 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;
5227 int quality_pixel_count = p_enc_ctx->actual_video_width * p_enc_ctx->active_video_height;
5228 ni_bitstream_features_t *bitstream_features = &p_out_pkt->bitstream_features;
5229
5230 ni_log2(p_enc_ctx, NI_LOG_ERROR, "%s: pkt #%" PRId64 " Bitstream Features - "
5231 "Av_QP: f=%.6f FrameSize: i32=%d InitialQP: i32=%d max_QP: i32=%d MbQPs_1_: f=%.6f "
5232 "FrameType: i32=%d Sec_Codec: i32=%d Seq_Profile: i32=%d "
5233 "MbQPs_5_: f=%.6f MbQPs_6_: f=%.6f AnalyzedMBs: i32=%d "
5234 "MbTypes_5_: i32=%d MbTypes_6_: i32=%d MbTypes_0_: i32=%d MbTypes_1_: i32=%d "
5235 "quality_pixel_count: i32=%d\n",
5236 __func__, p_enc_ctx->pkt_num,
5237 bitstream_features->average_qp, frame_size,
5238 bitstream_features->initial_qp, bitstream_features->max_qp, bitstream_features->avg_forward_pred_block_qp,
5239 itu_frame_type, video_codec_id, profile,
5240 bitstream_features->avg_intra_block_qp, bitstream_features->avg_intra_plane_qp, bitstream_features->analyzed_mbs,
5241 bitstream_features->num_intra_block_blocks, bitstream_features->num_intra_plane_blocks, bitstream_features->num_skip_blocks, bitstream_features->num_forward_pred_blocks,
5242 quality_pixel_count);
5243}
5244#endif
5245
5247{
5248 ni_instance_mgr_stream_info_t data = { 0 };
5249 uint32_t actual_read_size = 0;
5250 uint32_t to_read_size = 0;
5251 int size = 0;
5252 static long long encq_count = 0LL;
5253 int retval = NI_RETCODE_SUCCESS;
5254 int query_retry = 0;
5255 int query_type = INST_BUF_INFO_RW_READ;
5256 uint32_t ui32LBA = 0;
5257 ni_metadata_enc_bstream_t *p_meta = NULL;
5258 ni_metadata_enc_bstream_rev61_t *p_meta_rev61 = NULL;
5259 ni_instance_buf_info_t buf_info = { 0 };
5260 ni_session_statistic_t sessionStatistic = {0};
5261 int low_delay_notify = 0;
5262 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
5263
5264 if (!p_ctx || !p_packet || !p_packet->p_data)
5265 {
5266 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
5267 __func__);
5268 retval = NI_RETCODE_INVALID_PARAM;
5269 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
5270
5271 return retval;
5272 }
5273
5275
5276 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
5277 {
5278 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
5279 __func__);
5281 LRETURN;
5282 }
5283
5284 ni_log2(p_ctx, NI_LOG_DEBUG, "frame_num=%" PRIu64 ", pkt_num=%" PRIu64 ", av1_pkt_num=%" PRIu64 "\n",
5285 p_ctx->frame_num, p_ctx->pkt_num, p_ctx->av1_pkt_num);
5286 if (((ni_xcoder_params_t *)p_ctx->p_session_config)->low_delay_mode)
5287 {
5288 query_type = INST_BUF_INFO_RW_READ_BUSY;
5289 if (!p_packet->end_of_stream && p_ctx->frame_num < p_ctx->pkt_num)
5290 {
5291 if (p_ctx->ready_to_close)
5292 {
5293 query_type = INST_BUF_INFO_RW_READ;
5294 } else
5295 { //nothing to query, leave
5296 retval = NI_RETCODE_SUCCESS;
5297 low_delay_notify = 1;
5298 LRETURN;
5299 }
5300 }
5301 }
5302 for (;;)
5303 {
5304 query_sleep(p_ctx);
5305
5306 query_retry++;
5307
5309 "65") >= 0)
5310 {
5312 p_ctx, NI_DEVICE_TYPE_ENCODER, &sessionStatistic);
5313 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
5315 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
5316 CHECK_VPU_RECOVERY(retval);
5317
5318 buf_info.buf_avail_size = sessionStatistic.ui32RdBufAvailSize;
5319
5320 if (((ni_xcoder_params_t *)p_ctx->p_session_config)->cfg_enc_params.lookAheadDepth)
5321 {
5323 "6rX") >= 0)
5324 {
5325 if (p_ctx->current_frame_delay < (int)sessionStatistic.ui8AdditionalFramesDelay + p_ctx->initial_frame_delay)
5326 {
5327 p_ctx->current_frame_delay = (int)sessionStatistic.ui8AdditionalFramesDelay + p_ctx->initial_frame_delay; // extend frames delay by FW estimated additional number of frames
5328 }
5329 if(query_retry == 0)
5330 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: initial_frame_delay %d max_frame_delay %d ui8AdditionalFramesDelay %u current_frame_delay %d\n",
5331 __FUNCTION__, p_ctx->initial_frame_delay, p_ctx->max_frame_delay, sessionStatistic.ui8AdditionalFramesDelay, p_ctx->current_frame_delay);
5332 }
5333 }
5334 } else
5335 {
5337 p_ctx, query_type, NI_DEVICE_TYPE_ENCODER, &buf_info);
5338 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
5339 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5340 CHECK_VPU_RECOVERY(retval);
5341 }
5342
5343 ni_log2(p_ctx, NI_LOG_TRACE,
5344 "Info enc read query rc %d, available buf size %u, "
5345 "frame_num=%" PRIu64 ", pkt_num=%" PRIu64 "\n",
5346 retval, buf_info.buf_avail_size, p_ctx->frame_num, p_ctx->pkt_num);
5347
5348 if (NI_RETCODE_SUCCESS != retval)
5349 {
5350 ni_log2(p_ctx, NI_LOG_ERROR, "Buffer info query failed in encoder read!!!!\n");
5351 LRETURN;
5352 } else if (0 == buf_info.buf_avail_size)
5353 {
5354 // query to see if it is eos now, if we have sent it
5355 if (p_ctx->ready_to_close)
5356 {
5357 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_ENCODER, &data);
5358 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
5359 p_ctx->device_type, p_ctx->hw_id,
5360 &(p_ctx->session_id), OPT_1);
5361 CHECK_VPU_RECOVERY(retval);
5362
5363 if (NI_RETCODE_SUCCESS != retval)
5364 {
5365 ni_log2(p_ctx, NI_LOG_ERROR, "Stream info query failed in encoder read!!!!\n");
5366 LRETURN;
5367 }
5368
5369 if (data.is_flushed)
5370 {
5371 p_packet->end_of_stream = 1;
5372 }
5373 }
5374 ni_log2(p_ctx, NI_LOG_DEBUG, "Info enc read available buf size %u, eos %u !\n",
5375 buf_info.buf_avail_size, p_packet->end_of_stream);
5376
5377 if ((((ni_xcoder_params_t *)p_ctx->p_session_config)->low_delay_mode ||
5379 !p_packet->end_of_stream && p_ctx->frame_num >= p_ctx->pkt_num)
5380 {
5381 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder low latency mode, eos not sent, frame_num "
5382 "%" PRIu64 " >= %" PRIu64 " pkt_num, keep querying p_ctx->status %d\n",
5383 p_ctx->frame_num, p_ctx->pkt_num, p_ctx->status);
5387 if (query_retry >= NI_MAX_ENCODER_QUERY_RETRIES &&
5389 {
5390 low_delay_notify = 1;
5392 LRETURN;
5393 }
5394 else
5395 {
5396 continue;
5397 }
5398 }
5399 else if (((ni_xcoder_params_t *)p_ctx->p_session_config)->minFramesDelay)
5400 {
5401 if (p_ctx->pkt_num) // do not busy read until header is received
5402 {
5403 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
5404 if (p_ctx->frame_num - pkt_num >= p_ctx->current_frame_delay &&
5405 !p_packet->end_of_stream)
5406 {
5407 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",
5408 __FUNCTION__, p_ctx->frame_num, pkt_num,
5409 p_ctx->last_gop_size, p_ctx->current_frame_delay);
5410 continue;
5411 }
5412 }
5413 }
5414 retval = NI_RETCODE_SUCCESS;
5415 LRETURN;
5416 } else
5417 {
5418 if (((ni_xcoder_params_t *)p_ctx->p_session_config)->minFramesDelay & 0x2)
5419 {
5420 if (p_ctx->pkt_num) // do not read until header is received
5421 {
5422 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
5423 if (p_ctx->frame_num - pkt_num < (p_ctx->current_frame_delay - 1) &&
5424 !p_ctx->ready_to_close)
5425 {
5426 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",
5427 __FUNCTION__, p_ctx->frame_num, pkt_num,
5428 p_ctx->last_gop_size, p_ctx->current_frame_delay);
5429 retval = NI_RETCODE_SUCCESS;
5430 LRETURN;
5431 }
5432 }
5433 }
5434 break;
5435 }
5436 }
5437 ni_log2(p_ctx, NI_LOG_DEBUG, "Encoder read buf_avail_size %u\n", buf_info.buf_avail_size);
5438
5439 to_read_size = buf_info.buf_avail_size;
5440
5441 p_packet->data_len = 0;
5442 p_packet->pts = NI_NOPTS_VALUE;
5443 p_packet->dts = 0;
5444
5445 p_packet->psnr_y = 0;
5446 p_packet->psnr_u = 0;
5447 p_packet->psnr_v = 0;
5448 p_packet->average_psnr = 0;
5449 p_packet->ssim_y = 0;
5450 p_packet->ssim_u = 0;
5451 p_packet->ssim_v = 0;
5452
5454 actual_read_size = to_read_size;
5455 if (actual_read_size % NI_MEM_PAGE_ALIGNMENT)
5456 {
5457 actual_read_size =
5458 ((actual_read_size / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) +
5460 }
5461
5462 if (p_packet->buffer_size < actual_read_size)
5463 {
5464 if (ni_packet_buffer_alloc(p_packet, (int)actual_read_size))
5465 {
5466 ni_log2(p_ctx, NI_LOG_ERROR,
5467 "ERROR %s(): packet buffer size %u allocation "
5468 "failed\n",
5469 __func__, actual_read_size);
5471 LRETURN;
5472 }
5473 }
5474
5475 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5476 p_packet->p_data, actual_read_size, ui32LBA);
5477 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
5478 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5479 CHECK_VPU_RECOVERY(retval);
5480 if (retval < 0)
5481 {
5482 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
5484 LRETURN;
5485 }
5486
5487 // SSIM is supported if fw_rev is >= 6.2
5489 "62") >= 0)
5490 {
5491 p_meta = (ni_metadata_enc_bstream_t *)p_packet->p_data;
5492 p_packet->pts = (int64_t)(p_meta->frame_tstamp);
5493
5494 // Frame types that encoder can return are I=0, P=1, B=2, Not coded=3.
5495 // Since all I-frames encoded by Quadra are IDR frames, interpret an I frame as IDR frame.
5496 p_packet->frame_type = (p_meta->frame_type == 0) ?
5497 PIC_TYPE_IDR : ((p_meta->frame_type == 3) ? PIC_NOT_CODED : p_meta->frame_type);
5498 p_packet->avg_frame_qp = p_meta->avg_frame_qp;
5499 p_packet->recycle_index = (int)p_meta->recycle_index;
5500 p_packet->av1_show_frame = (int)p_meta->av1_show_frame;
5501 ni_log2(p_ctx, NI_LOG_DEBUG, "%s RECYCLE INDEX = %u!!!\n", __FUNCTION__, p_meta->recycle_index);
5502 ni_log2(p_ctx, NI_LOG_DEBUG, "%s MetaDataSize %d FrameType %d AvgFrameQp %d ssim %d %d %d\n",
5503 __FUNCTION__, p_meta->metadata_size, p_packet->frame_type, p_meta->avg_frame_qp, p_meta->ssimY, p_meta->ssimU, p_meta->ssimV);
5504
5506 "6r2") >= 0)
5507 {
5508 if (((ni_xcoder_params_t *)p_ctx->p_session_config)->cfg_enc_params.lookAheadDepth)
5509 {
5511 "6rX") < 0)
5512 {
5513 if (p_meta->gop_size) // ignore frame 0 gop size 0 (other I-frame gop size 1)
5514 {
5515 if ((int)p_meta->gop_size < p_ctx->last_gop_size)
5516 {
5517 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
5518 }
5519 }
5520 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",
5521 __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);
5522 }
5523 p_ctx->last_gop_size = p_meta->gop_size;
5524 }
5525 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: current gop_size %u\n",
5526 __FUNCTION__, p_meta->gop_size);
5527 }
5528
5530 "6p") >= 0)
5531 {
5532 if (ni_cmp_fw_api_ver((char*)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rm") >= 0)
5533 {
5534 p_packet->still_image_detected = p_meta->ui8StillImage;
5535 p_packet->scene_change_detected = p_meta->ui8SceneChange;
5536 }
5537 else
5538 {
5539 p_packet->still_image_detected = 0;
5540 p_packet->scene_change_detected = 0;
5541 }
5542
5543 if(p_meta->frame_size > 0)
5544 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",
5545 p_ctx->pkt_num,
5546 p_meta->max_mv_x[0], p_meta->max_mv_x[1], p_meta->max_mv_y[0], p_meta->max_mv_y[1],
5547 p_meta->min_mv_x[0], p_meta->min_mv_x[1], p_meta->min_mv_y[0], p_meta->min_mv_y[1],
5548 p_meta->frame_size, p_meta->inter_total_count, p_meta->intra_total_count,
5549 p_meta->ui8StillImage, p_meta->ui8SceneChange);
5550 }
5551
5553 "6sC") >= 0)
5554 {
5555 if (p_meta->pass1Cost)
5556 ni_log2(p_ctx, NI_LOG_DEBUG, "pkt_num %d pass1Cost %f\n", p_ctx->pkt_num, p_meta->pass1Cost);
5557 }
5558
5559 p_ctx->meta_size = p_meta->metadata_size;
5560
5561 if (p_meta->ssimY != 0)
5562 {
5563 p_packet->ssim_y = (float)p_meta->ssimY/10000;
5564 p_packet->ssim_u = (float)p_meta->ssimU/10000;
5565 p_packet->ssim_v = (float)p_meta->ssimV/10000;
5566 // The SSIM Y, U, V values returned by FW are 4 decimal places multiplied by 10000.
5567 //Divide by 10000 to get the original value.
5568 ni_log2(p_ctx,
5569#ifdef NI_LOG_SSIM_AT_INFO
5571#else
5573#endif
5574 "%s: pkt #%" PRId64 " pts %" PRId64 " ssim "
5575 "Y %.4f U %.4f V %.4f\n", __FUNCTION__, p_ctx->pkt_num,
5576 p_packet->pts, (float)p_meta->ssimY/10000,
5577 (float)p_meta->ssimU/10000, (float)p_meta->ssimV/10000);
5578 }
5579 }
5580 else
5581 {
5582 // Up to fw_rev major 6 and minor 1, use the old meta data structure
5583 p_meta_rev61 = (ni_metadata_enc_bstream_rev61_t *)p_packet->p_data;
5584 p_packet->pts = (int64_t)(p_meta_rev61->frame_tstamp);
5585 p_packet->frame_type = p_meta_rev61->frame_type;
5586 p_packet->avg_frame_qp = p_meta_rev61->avg_frame_qp;
5587 p_packet->recycle_index = (int)p_meta_rev61->recycle_index;
5588 p_packet->av1_show_frame = (int)p_meta_rev61->av1_show_frame;
5589 ni_log2(p_ctx, NI_LOG_DEBUG, "%s RECYCLE INDEX = %u!!!\n", __FUNCTION__, p_meta_rev61->recycle_index);
5590
5591 }
5592
5593 p_packet->data_len = to_read_size;
5594
5595 size = (int)p_packet->data_len;
5596
5597 if (size > 0)
5598 {
5599 if (p_ctx->pkt_num >= 1 &&
5601 "6sM") >= 0)
5602 {
5603 p_meta = (ni_metadata_enc_bstream_t *)p_packet->p_data;
5604
5605 // CU info parsing
5606 if (((ni_xcoder_params_t *)(p_ctx->p_session_config))->cfg_enc_params.getBitstreamFeatures)
5607 {
5608 memset(&p_packet->bitstream_features, 0, sizeof(p_packet->bitstream_features));
5609 get_bitstream_features_from_cu_info(p_ctx, p_packet);
5610 }
5611
5612 if (p_meta && p_meta->cuInfoSize != 0)
5613 {
5614 p_packet->data_len -= p_meta->cuInfoSize;
5615 // DEBUG
5616 #if 0
5617 ni_write_bitstream_features_internal(p_ctx, p_packet);
5618 #endif
5619 }
5620 }
5621
5622 if (p_ctx->pkt_num >= 1 &&
5624 "6rc") >= 0)
5625 {
5626 calculate_psnr(p_ctx, p_packet);
5627 }
5628
5629 if (p_ctx->pkt_num < 1)
5630 {
5631 p_ctx->headers_length += (p_packet->data_len - p_ctx->meta_size);
5632 }
5633
5634
5635 if (p_ctx->pkt_num >= 1)
5636 {
5637 if (NI_CODEC_FORMAT_AV1 != p_ctx->codec_format
5638 || p_packet->av1_show_frame)
5639 {
5640 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)
5641 {
5642 p_packet->dts = NI_NOPTS_VALUE;
5643 }
5644 }
5645
5646 p_ctx->pkt_num++;
5647 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
5648 {
5649 p_ctx->av1_pkt_num++;
5650 }
5651 low_delay_notify = 1;
5652 }
5653
5654 encq_count++;
5655
5656#ifdef MEASURE_LATENCY
5657#ifndef XCODER_311
5658 ni_log2(p_ctx, NI_LOG_INFO, "ENC fme_num %d, pkt_num %d, latency is %d\n",
5659 p_ctx->frame_num, p_ctx->pkt_num, p_ctx->frame_num - p_ctx->pkt_num);
5660#endif
5661#endif
5662
5663#ifdef XCODER_DUMP_DATA
5664 char dump_file[256];
5665 (void)snprintf(dump_file, sizeof(dump_file), "%ld-%u-enc-pkt/pkt-%04ld.bin",
5666 (long)getpid(), p_ctx->session_id, (long)p_ctx->pkt_num);
5667
5668 FILE *f = NULL;
5669 ni_fopen(&f, dump_file, "wb");
5670 (void)fwrite((uint8_t *)p_packet->p_data + sizeof(ni_metadata_enc_bstream_t),
5671 p_packet->data_len - sizeof(ni_metadata_enc_bstream_t), 1, f);
5672 (void)fflush(f);
5673 (void)fclose(f);
5674#endif
5675 }
5676
5677 ni_log2(p_ctx,
5679 "%s(): %d.%u p_packet->start_of_stream=%u, "
5680 "p_packet->end_of_stream=%u, p_packet->video_width=%u, "
5681 "p_packet->video_height=%u, p_packet->dts=0x%08x 0x%08x, "
5682 "p_packet->pts=0x%08x 0x%08x, type=%u, avg_frame_qp=%u, show_frame=%d\n",
5683 __func__, p_ctx->hw_id, p_ctx->session_id, p_packet->start_of_stream,
5684 p_packet->end_of_stream, p_packet->video_width, p_packet->video_height,
5685 (uint32_t)((p_packet->dts >> 32) & 0xFFFFFFFF),
5686 (uint32_t)(p_packet->dts & 0xFFFFFFFF),
5687 (uint32_t)((p_packet->pts >> 32) & 0xFFFFFFFF),
5688 (uint32_t)(p_packet->pts & 0xFFFFFFFF), p_packet->frame_type,
5689 p_packet->avg_frame_qp, p_packet->av1_show_frame);
5690
5691 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): p_packet->data_len=%u, size=%d\n", __func__,
5692 p_packet->data_len, size);
5693
5694 if (encq_count % 500 == 0)
5695 {
5696 ni_log2(p_ctx, NI_LOG_DEBUG,
5697 "Encoder pts queue size = %u dts queue size = %u\n\n",
5698 p_ctx->pts_table->list.count, p_ctx->dts_queue->list.count);
5699 }
5700
5701 retval = size;
5702
5703#ifdef MEASURE_LATENCY
5704 if ((p_packet->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL) && (p_ctx->pkt_num > 0))
5705 {
5706 if (NI_CODEC_FORMAT_AV1 != p_ctx->codec_format
5707 || p_packet->av1_show_frame)
5708 {
5709 uint64_t abs_time_ns = ni_gettime_ns();
5711 ni_log2(p_ctx, NI_LOG_INFO, "DTS:%" PRId64 ",DELTA:%" PRId64 ",eLAT:%" PRIu64 ";\n",
5712 p_packet->dts, abs_time_ns - q->last_benchmark_time,
5713 ni_lat_meas_q_check_latency(q, abs_time_ns, p_packet->dts));
5714 q->last_benchmark_time = abs_time_ns;
5715 }
5716 }
5717#endif
5718
5719END:
5720
5722
5723 if (low_delay_notify)
5724 {
5725 low_delay_signal(p_ctx);
5726 }
5727
5728 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
5729
5730 return retval;
5731}
5732
5733/*!******************************************************************************
5734 * \brief Send sequnce change to a xcoder encoder instance
5735 *
5736 * \param
5737 *
5738 * \return
5739 *******************************************************************************/
5741{
5743
5744 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
5745
5746 // re-init last_gop_size and av1_pkt_num for minFramesDelay frame delay estimiation
5747 int lookAheadEnable = !!(((ni_xcoder_params_t *)p_ctx->p_session_config)->cfg_enc_params.lookAheadDepth);
5748 int gop_preset_index = ((ni_xcoder_params_t *)p_ctx->p_session_config)->cfg_enc_params.gop_preset_index;
5749 p_ctx->last_gop_size = g_map_preset_to_gopsize[lookAheadEnable][gop_preset_index + 1];
5750 p_ctx->av1_pkt_num = 0;
5751
5752 //Configure encoder sequence change
5754 p_resolution);
5756 p_ctx->device_type, p_ctx->hw_id,
5757 &(p_ctx->session_id), OPT_1);
5758 CHECK_VPU_RECOVERY(retval);
5759 if (retval < 0)
5760 {
5761 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): config encoder sequence change command failed\n",
5762 __func__);
5764 }
5765#ifdef NI_HAVE_MCTF
5766 else if (p_ctx->mctf)
5767 {
5768 // Rebuild MCTF state for the new resolution on the next submitted frame.
5769 clearMCTF(p_ctx);
5770 }
5771#endif
5772
5773END:
5774
5775 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
5776
5777 return retval;
5778}
5779
5780/*!******************************************************************************
5781 * \brief Open a xcoder scaler instance
5782 *
5783 * \param[in] p_ctx pointer to session context
5784 *
5785 * \return NI_RETCODE_INVALID_PARAM
5786 * NI_RETCODE_ERROR_NVME_CMD_FAILED
5787 * NI_RETCODE_ERROR_INVALID_SESSION
5788 * NI_RETCODE_ERROR_MEM_ALOC
5789 *******************************************************************************/
5791{
5793 void* p_buffer = NULL;
5794 uint32_t ui32LBA = 0;
5795 char fmt_fw_api_ver1[5], fmt_fw_api_ver2[5];
5796
5797 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
5798
5799 if (!p_ctx)
5800 {
5801 retval = NI_RETCODE_INVALID_PARAM;
5802 LRETURN;
5803 }
5804
5806 {
5808 "64") < 0)
5809 {
5810 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot use stack filter on device with FW API version < 6.4\n");
5812 }
5813 }
5814
5816 {
5818 "67") < 0)
5819 {
5820 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot use rotate filter on device with FW API version < 6.7\n");
5822 }
5823 }
5824
5826 {
5828 "6L") < 0)
5829 {
5830 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot use in-place overlay filter on device with FW API version < 6.L\n");
5832 }
5833 }
5834
5836 {
5838 "6sI") < 0)
5839 {
5840 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot use ai align filter on device with FW API version < 6.sI\n");
5842 }
5843 }
5844
5845 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
5846 {
5848 p_ctx->pts_table = NULL;
5849 p_ctx->dts_queue = NULL;
5850 p_ctx->p_leftover = NULL;
5851 p_ctx->buffer_pool = NULL;
5852 p_ctx->dec_fme_buf_pool = NULL;
5853 p_ctx->prev_size = 0;
5854 p_ctx->sent_size = 0;
5855 p_ctx->status = 0;
5856 p_ctx->key_frame_type = 0;
5857 p_ctx->ready_to_close = 0;
5858 p_ctx->rc_error_count = 0;
5859 p_ctx->frame_num = 0;
5860 p_ctx->pkt_num = 0;
5861 p_ctx->pkt_index = 0;
5862 if (!p_ctx->max_retry_count)
5864
5865
5866 //malloc zero data buffer
5867 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
5869 {
5870 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc all zero buffer failed\n",
5871 NI_ERRNO, __func__);
5873 LRETURN;
5874 }
5875 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
5876
5877 //malloc data buffer
5878 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
5879 {
5880 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
5881 NI_ERRNO, __func__);
5883 LRETURN;
5884 }
5885 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
5886
5887 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
5888 //In case we can open sesison, the session id would become valid.
5889 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
5890 (uint16_t)NI_INVALID_SESSION_ID;
5891
5892 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
5893 ui32LBA = OPEN_SESSION_CODEC(NI_DEVICE_TYPE_SCALER, ni_htonl(p_ctx->scaler_operation), 0);
5894 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5895 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
5896 if (retval != NI_RETCODE_SUCCESS)
5897 {
5898 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR ni_nvme_send_read_cmd\n");
5899 LRETURN;
5900 }
5901 //Open will return a session status structure with a valid session id if it worked.
5902 //Otherwise the invalid session id set before the open command will stay
5903 p_ctx->session_id = ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
5904 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
5905 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
5906 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
5907 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
5908 {
5909 ni_log2(p_ctx, NI_LOG_ERROR,
5910 "ERROR %s(): p_ctx->device_handle=%" PRIx64
5911 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
5912 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
5913 p_ctx->session_id);
5915 LRETURN;
5916 }
5917 ni_log2(p_ctx, NI_LOG_DEBUG, "Scaler open session ID:0x%x\n",p_ctx->session_id);
5918 ni_log2(p_ctx, NI_LOG_DEBUG,
5919 "%s(): p_ctx->device_handle=%" PRIx64
5920 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
5921 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
5922 p_ctx->session_id);
5923
5924 //Send keep alive timeout Info
5925 uint64_t keep_alive_timeout =
5926 (uint64_t)p_ctx->keep_alive_timeout * 1000000; //send us to FW
5927 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
5928 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
5929 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
5930 keep_alive_timeout);
5932 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5933 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
5934 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
5935 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5936 CHECK_VPU_RECOVERY(retval);
5937
5938 if (NI_RETCODE_SUCCESS != retval)
5939 {
5940 ni_log2(p_ctx, NI_LOG_ERROR,
5941 "ERROR %s(): nvme write keep_alive_timeout command "
5942 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
5943 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
5945 LRETURN;
5946 }
5947
5948 // Send SW version to FW if FW API version is >= 6.2
5950 "62") >= 0)
5951 {
5952 // Send SW version to session manager
5953 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
5954 memcpy(p_buffer, NI_XCODER_REVISION, sizeof(uint64_t));
5956 ni_fmt_fw_api_ver_str((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], &fmt_fw_api_ver2[0]);
5957 ni_log2(p_ctx, NI_LOG_DEBUG, "%s libxcoder FW API ver %s, FW FW API ver %s\n",
5958 __func__, fmt_fw_api_ver1, fmt_fw_api_ver2);
5959 ui32LBA = CONFIG_SESSION_SWVersion_W(p_ctx->session_id);
5960 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
5961 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
5962 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
5963 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
5964 CHECK_VPU_RECOVERY(retval);
5965
5966 if (NI_RETCODE_SUCCESS != retval)
5967 {
5968 ni_log2(p_ctx, NI_LOG_ERROR,
5969 "ERROR %s(): nvme write sw_version command "
5970 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
5971 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
5973 LRETURN;
5974 }
5975 }
5976 }
5977
5978 // init for frame pts calculation
5979 p_ctx->is_first_frame = 1;
5980 p_ctx->last_pts = 0;
5981 p_ctx->last_dts = 0;
5982 p_ctx->active_video_width = 0;
5983 p_ctx->active_video_height = 0;
5984 p_ctx->actual_video_width = 0;
5985
5986#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OPEN_HARMONY__) && !defined(_ANDROID)
5987 if (p_ctx->isP2P)
5988 {
5989 retval = p2p_fill_pcie_address(p_ctx);
5990 if(retval != NI_RETCODE_SUCCESS)
5991 {
5992 LRETURN;
5993 }
5994 }
5995#endif
5996
5997END:
5998
5999 ni_aligned_free(p_buffer);
6000 return retval;
6001}
6002
6003/*!******************************************************************************
6004 * \brief close a scaler session
6005 *
6006 * \param[in] p_ctx pointer to session context
6007 * \param[in] eos_received (not used)
6008 *
6009 * \return NI_RETCODE_INVALID_PARAM
6010 * NI_RETCODE_ERROR_INVALID_SESSION
6011 * NI_RETCODE_ERROR_NVME_CMD_FAILED
6012 *******************************************************************************/
6014{
6015 (void)eos_received;
6017 void * p_buffer = NULL;
6018 uint32_t ui32LBA = 0;
6019
6020 if (!p_ctx)
6021 {
6022 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
6023 __func__);
6025 }
6026
6028
6029 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
6030 {
6031 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): Invalid session ID, return.\n", __func__);
6032 retval = NI_RETCODE_SUCCESS;
6033 LRETURN;
6034 }
6035
6036 //malloc data buffer
6037 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
6038 {
6039 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc data buffer failed\n",
6040 NI_ERRNO, __func__);
6042 LRETURN;
6043 }
6044 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
6045
6047
6048 int retry = 0;
6049 while (retry < NI_SESSION_CLOSE_RETRY_MAX)
6050 {
6051 ni_log2(p_ctx, NI_LOG_DEBUG,
6052 "%s(): p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
6053 "p_ctx->session_id=%d, close_mode=1\n",
6054 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
6055 p_ctx->session_id);
6056
6058 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
6059 {
6060 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): command failed!\n", __func__);
6063 break;
6064 } else
6065 {
6066 //Close should always succeed
6067 retval = NI_RETCODE_SUCCESS;
6069 break;
6070 }
6071 retry++;
6072 }
6073
6074#ifndef _WIN32
6075 if (p_ctx->isP2P)
6076 {
6077 if (p_ctx->netint_fd)
6078 {
6079 close(p_ctx->netint_fd);
6080 }
6081 }
6082#endif
6083
6084END:
6085
6086 ni_aligned_free(p_buffer);
6088
6090
6091 return retval;
6092}
6093
6094/*!******************************************************************************
6095 * \brief Send a p_config command to configure scaling parameters.
6096 *
6097 * \param ni_session_context_t p_ctx - xcoder Context
6098 * \param ni_scaler_params_t * params - pointer to the scaler ni_scaler_params_t struct
6099 *
6100 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
6101 *******************************************************************************/
6103 ni_scaler_params_t *p_params)
6104{
6105 void *p_scaler_config = NULL;
6106 ni_scaler_config_t *p_cfg = NULL;
6107 uint32_t buffer_size = sizeof(ni_scaler_config_t); /* wire struct, not param struct */
6109 uint32_t ui32LBA = 0;
6110
6111 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
6112
6113 if (!p_ctx || !p_params)
6114 {
6115 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
6116 __func__);
6117 retval = NI_RETCODE_INVALID_PARAM;
6118 LRETURN;
6119 }
6120
6121 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
6122 {
6123 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
6124 __func__);
6126 LRETURN;
6127 }
6128
6129 buffer_size =
6130 ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) *
6132 if (ni_posix_memalign(&p_scaler_config, sysconf(_SC_PAGESIZE), buffer_size))
6133 {
6134 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() malloc p_scaler_config buffer failed\n",
6135 NI_ERRNO, __func__);
6137 LRETURN;
6138 }
6139 memset(p_scaler_config, 0, buffer_size);
6140
6141 //configure the session here
6144
6145 //Flip the bytes!!
6146 p_cfg = (ni_scaler_config_t *)p_scaler_config;
6147 p_cfg->filterblit = p_params->filterblit;
6148 p_cfg->numInputs = p_params->nb_inputs;
6149 if (p_cfg->filterblit == 5)
6150 {
6151 // check fw revision
6154 "6sL") < 0)
6155 {
6156 ni_log2(p_ctx, NI_LOG_ERROR, "%s: not supported config filterblit 5 "
6157 "on device with FW API version < 6rL\n", __func__);
6158 // Close the session since we can't configure it as per fw
6159 retval = ni_scaler_session_close(p_ctx, 0);
6160 if (NI_RETCODE_SUCCESS != retval)
6161 {
6162 ni_log2(p_ctx, NI_LOG_ERROR,
6163 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
6164 "hw_id, %d, xcoder_inst_id: %d\n",
6165 __func__,
6166 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
6167 p_ctx->session_id);
6168 }
6170 LRETURN;
6171 }
6172
6173 // set filterblit 5 default parameter
6174 p_cfg->scaler_param_b = (uint16_t)(3.5 * 10000);
6175 p_cfg->scaler_param_c = (uint16_t)(1.25 * 10000);
6176 }
6177 else
6178 {
6179 p_cfg->scaler_param_b = (uint16_t)(0);
6180 p_cfg->scaler_param_c = (uint16_t)(0.75 * 10000);
6181 }
6182
6183 if (p_params->enable_scaler_params)
6184 {
6185 // check fw revision
6188 "6s2") < 0)
6189 {
6190 ni_log2(p_ctx, NI_LOG_ERROR, "%s: not supported config scaler params B and C "
6191 "on device with FW API version < 6s1\n", __func__);
6192 // Close the session since we can't configure it as per fw
6193 retval = ni_scaler_session_close(p_ctx, 0);
6194 if (NI_RETCODE_SUCCESS != retval)
6195 {
6196 ni_log2(p_ctx, NI_LOG_ERROR,
6197 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
6198 "hw_id, %d, xcoder_inst_id: %d\n",
6199 __func__,
6200 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
6201 p_ctx->session_id);
6202 }
6203
6205 LRETURN;
6206 }
6207 if (p_params->scaler_param_b < 0 || p_params->scaler_param_c < 0 ||
6208 p_params->scaler_param_b > 5 || p_params->scaler_param_c > 5)
6209 {
6210 ni_log2(p_ctx, NI_LOG_ERROR, "%s: scaler_params_b and scaler_params_c must "
6211 "be in [0 , 5]. scaler_params_b is %lf, scaler_params_c is %lf\n",
6212 __func__, p_params->scaler_param_b, p_params->scaler_param_c);
6213 // Close the session since we can't configure it as per fw
6214 retval = ni_scaler_session_close(p_ctx, 0);
6215 if (NI_RETCODE_SUCCESS != retval)
6216 {
6217 ni_log2(p_ctx, NI_LOG_ERROR,
6218 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
6219 "hw_id, %d, xcoder_inst_id: %d\n",
6220 __func__,
6221 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
6222 p_ctx->session_id);
6223 }
6224
6226 LRETURN;
6227 }
6228 p_cfg->scaler_param_b = (uint16_t)(p_params->scaler_param_b * 10000);
6229 p_cfg->scaler_param_c = (uint16_t)(p_params->scaler_param_c * 10000);
6230 }
6231
6232 /*
6233 * User-defined Q14 polyphase kernel (NI_SCALER_ALGORITHM_USER_KERNEL = 6).
6234 *
6235 * Activated when kernel_taps > 0. Takes priority over all other filterblit
6236 * modes: overrides p_cfg->filterblit unconditionally.
6237 *
6238 * Firmware requirements validated here (fail fast before DMA):
6239 * 1. kernel_taps in [1, NI_SCALER_MAX_KERNEL_TAPS]
6240 * 2. Every one of the 17 subpixel-position rows must sum to exactly
6241 * NI_SCALER_Q14_ONE (0x4000) when the active taps are accumulated
6242 * as signed 16-bit integers. This guarantees DC gain = 1 and prevents
6243 * luminance shift or overflow in the 2D scaler hardware.
6244 */
6246 {
6247 int pos, tap;
6248 int padding;
6249
6250 // check fw revision
6253 "6t6") < 0)
6254 {
6255 ni_log2(p_ctx, NI_LOG_ERROR, "%s: not supported config filterblit 6 "
6256 "on device with FW API version < 6t6\n", __func__);
6257 // Close the session since we can't configure it as per fw
6258 retval = ni_scaler_session_close(p_ctx, 0);
6259 if (NI_RETCODE_SUCCESS != retval)
6260 {
6261 ni_log2(p_ctx, NI_LOG_ERROR,
6262 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
6263 "hw_id, %d, xcoder_inst_id: %d\n",
6264 __func__,
6265 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
6266 p_ctx->session_id);
6267 }
6269 LRETURN;
6270 }
6271 /* ---- 1. tap-count range check ------------------------------------ */
6272 if (p_params->kernel_taps == 0 || p_params->kernel_taps > NI_SCALER_MAX_KERNEL_TAPS)
6273 {
6274 ni_log2(p_ctx, NI_LOG_ERROR,
6275 "%s: kernel_taps=%u exceeds hardware maximum %d\n",
6276 __func__, (unsigned)p_params->kernel_taps,
6279 LRETURN;
6280 }
6281
6282 /* ---- 2. per-row Q14 sum check ------------------------------------ */
6283 padding = (NI_SCALER_KERNEL_SLOTS - (int)p_params->kernel_taps) / 2;
6284
6285 for (int idx = 0; idx < 2; idx++)
6286 {
6287 for (pos = 0; pos < NI_SCALER_KERNEL_POSITIONS; pos++)
6288 {
6289 int32_t row_sum = 0;
6290 const uint16_t *row =
6291 &p_params->kernel_array[idx][(size_t)pos * NI_SCALER_KERNEL_SLOTS];
6292
6293 for (tap = 0; tap < (int)p_params->kernel_taps; tap++)
6294 row_sum += (int16_t)row[padding + tap];
6295
6296 if (row_sum != NI_SCALER_Q14_ONE)
6297 {
6298 ni_log2(p_ctx, NI_LOG_ERROR,
6299 "%s: Warning: USER_KERNEL idx %d row[%d] Q14 sum=0x%04x, "
6300 "expected 0x%04x (taps=%u, padding=%d)\n",
6301 __func__, idx, pos, (uint32_t)(uint16_t)row_sum,
6303 (unsigned)p_params->kernel_taps, padding);
6304 }
6305 }
6306 }
6307
6308 /* ---- 3. populate config ----------------------------------------- */
6310 p_cfg->kernel_taps = p_params->kernel_taps;
6311 memcpy(p_cfg->kernel_array, p_params->kernel_array, sizeof(p_params->kernel_array));
6312 ni_log2(p_ctx, NI_LOG_DEBUG,
6313 "%s: USER_KERNEL configured, taps=%u\n",
6314 __func__, (unsigned)p_params->kernel_taps);
6315 }
6316 else
6317 {
6318 // check fw revision
6321 "6t6") >= 0)
6322 {
6323 /* ---- 1. tap-count range check ------------------------------------ */
6324 if (p_params->kernel_taps > NI_SCALER_MAX_KERNEL_TAPS)
6325 {
6326 ni_log2(p_ctx, NI_LOG_ERROR,
6327 "%s: kernel_taps=%u exceeds hardware maximum %d\n",
6328 __func__, (unsigned)p_params->kernel_taps,
6331 LRETURN;
6332 }
6333 else if (p_params->kernel_taps == 0) //Set taps to default 5
6334 {
6335 p_cfg->kernel_taps = 5;
6336 }
6337 else
6338 {
6339 p_cfg->kernel_taps = p_params->kernel_taps;
6340 }
6341 }
6342 }
6343
6344 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
6345 p_scaler_config, buffer_size, ui32LBA);
6346 if ((int32_t)retval < 0)
6347 {
6348 ni_log2(p_ctx, NI_LOG_ERROR,
6349 "ERROR: ni_nvme_send_write_cmd failed: blk_io_handle: %" PRIx64
6350 ", hw_id, %d, xcoder_inst_id: %d\n",
6351 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
6352 // Close the session since we can't configure it as per fw
6353 retval = ni_scaler_session_close(p_ctx, 0);
6354 if (NI_RETCODE_SUCCESS != retval)
6355 {
6356 ni_log2(p_ctx, NI_LOG_ERROR,
6357 "ERROR: %s failed: blk_io_handle: %" PRIx64 ","
6358 "hw_id, %d, xcoder_inst_id: %d\n",
6359 __func__,
6360 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
6361 p_ctx->session_id);
6362 }
6363
6365 LRETURN;
6366 }
6368 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
6369
6370END:
6371
6372 ni_aligned_free(p_scaler_config);
6373 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
6374
6375 return retval;
6376}
6377
6378/*!******************************************************************************
6379 * \brief allocate a frame in the scaler
6380 *
6381 * \param[in] p_ctx pointer to session context
6382 * \param[in] width width in pixels
6383 * \param[in] height height in pixels
6384 * \param[in] format pixel format
6385 * \param[in] options option flags
6386 * \param[in] rectangle_width clipping rectangle width in pixels
6387 * \param[in] rectangle_height clipping rectangle height in pixels
6388 * \param[in] rectangle_x clipping rectangle x position
6389 * \param[in] rectangle_y clipping rectangle y position
6390 * \param[in] rgba_color background colour (only used by pad filter)
6391 * \param[in] frame_index frame index (only for hardware frames)
6392 *
6393 * \return NI_RETCODE_INVALID_PARAM
6394 * NI_RETCODE_ERROR_INVALID_SESSION
6395 * NI_RETCODE_ERROR_NVME_CMD_FAILED
6396 * NI_RETCODE_ERROR_MEM_ALOC
6397 *******************************************************************************/
6399 int width,
6400 int height,
6401 int format,
6402 int options,
6403 int rectangle_width,
6404 int rectangle_height,
6405 int rectangle_x,
6406 int rectangle_y,
6407 int rgba_color,
6408 int frame_index)
6409{
6412 uint32_t dataLen;
6413 uint32_t ui32LBA = 0;
6414 uint32_t query_retry = 0;
6415
6416 /* Round up to nearest 4096 bytes */
6417 dataLen =
6419 dataLen = dataLen & 0xFFFFF000;
6420
6421 if (!p_ctx)
6422 {
6424 }
6425
6426 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
6427 {
6428 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
6429 __func__);
6431 }
6432
6433 if (((options & NI_SCALER_FLAG_IO) && (options & NI_SCALER_FLAG_PC)))
6434 {
6435 // this operation is to free/allocate scaler frame pool
6436 if (rgba_color == 0)
6437 {
6440 "6r3") < 0)
6441 {
6442 ni_log2(p_ctx, NI_LOG_INFO,
6443 "WARNING: Allocate framepool size 0 for session 0x%x\n", p_ctx->session_id);
6444 return NI_RETCODE_SUCCESS;
6445 }
6446 else if (p_ctx->pool_type == NI_POOL_TYPE_NONE)
6447 {
6448 ni_log2(p_ctx, NI_LOG_ERROR,
6449 "ERROR: %s() try to free session 0x%x framepool while it's not allocated\n",
6450 __func__, p_ctx->session_id);
6452 }
6453 else if ((options & NI_SCALER_FLAG_P2) == p_ctx->pool_type)
6454 {
6455 ni_log2(p_ctx, NI_LOG_INFO, "Free framepool of scaler 0x%x\n", p_ctx->session_id);
6456 }
6457 else
6458 {
6459 ni_log2(p_ctx, NI_LOG_ERROR,
6460 "ERROR: %s() try to free session 0x%x framepool of type %u while "
6461 "passing type %u\n",
6462 __func__, p_ctx->session_id, p_ctx->pool_type,
6463 (options & NI_SCALER_FLAG_P2));
6464 }
6465 }
6466 else
6467 {
6468 if (p_ctx->pool_type != NI_POOL_TYPE_NONE)
6469 {
6470 // try to expand the framepool
6473 "6r3") < 0)
6474 {
6475 ni_log2(p_ctx, NI_LOG_ERROR,
6476 "ERROR: allocate framepool multiple times for session 0x%x "
6477 "not supported in FW API version < 6r3\n",
6478 p_ctx->session_id);
6480 }
6481 if ((options & NI_SCALER_FLAG_P2) == p_ctx->pool_type)
6482 {
6483 ni_log2(p_ctx, NI_LOG_INFO,
6484 "Expand frame pool of scaler 0x%x with %u more frames\n",
6485 p_ctx->session_id, rgba_color);
6486 }
6487 else
6488 {
6489 ni_log2(p_ctx, NI_LOG_ERROR,
6490 "ERROR: try to expand session 0x%x framepool with type %u "
6491 "while pool type is %u\n",
6492 p_ctx->session_id, options & NI_SCALER_FLAG_P2, p_ctx->pool_type);
6494 }
6495 }
6496 }
6497 }
6498
6499 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
6500 {
6501 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6502 NI_ERRNO, __func__);
6504 }
6505
6506 memset(p_data, 0x00, dataLen);
6507
6508 p_data->picture_width = width;
6509 p_data->picture_height = height;
6510 p_data->picture_format = format;
6511 p_data->options = options;
6512 p_data->rectangle_width = rectangle_width;
6513 p_data->rectangle_height = rectangle_height;
6514 p_data->rectangle_x = (int16_t)rectangle_x;
6515 p_data->rectangle_y = (int16_t)rectangle_y;
6516 p_data->rgba_color = (uint32_t)rgba_color;
6517 p_data->frame_index = (uint16_t)frame_index;
6518
6519 ni_log2(p_ctx, NI_LOG_DEBUG, "%s() options %d frame_index %u buffered_frame_index %d\n",
6520 __func__, options, p_data->frame_index, p_ctx->buffered_frame_index);
6521
6522 switch (p_ctx->scaler_operation)
6523 {
6526 if ((options & NI_SCALER_FLAG_IO) && !(options & NI_SCALER_FLAG_PC))
6527 {
6528 p_data->frame_index = frame_index; // background
6529 if (p_ctx->buffered_frame_index)
6530 {
6531 p_data->rgba_color = p_ctx->buffered_frame_index; // output frame
6532 }
6533 else
6534 {
6535 p_data->rgba_color = 0; // no output frame, fw must acquire
6536 }
6537 }
6538 break;
6539
6540 default:
6541 // Send acquired buffer index in AdminWr SET_ALLOC_FRAME command to prevent FP
6542 // ConfigOutput from acquire buffer again
6543 if ((options & NI_SCALER_FLAG_IO) && p_ctx->buffered_frame_index)
6544 {
6545 p_data->frame_index = p_ctx->buffered_frame_index;
6546 }
6547 break;
6548 }
6549
6550 bool isrgb = ((GC620_RGBA8888 == format) || (GC620_BGRX8888 == format) ||
6551 (GC620_ARGB8888 == format) || (GC620_ABGR8888 == format));
6552 if(width > NI_MAX_RESOLUTION_WIDTH || height > NI_MAX_RESOLUTION_HEIGHT ||
6554 ((width > NI_MAX_RESOLUTION_RGBA_WIDTH || height > NI_MAX_RESOLUTION_RGBA_HEIGHT) && isrgb))
6555 {
6557 ni_log2(p_ctx, NI_LOG_ERROR, "Invalid Picture Width: too small for scaler\n");
6559 ni_log2(p_ctx, NI_LOG_ERROR, "Invalid Picture Height: too small for scaler\n");
6560 if(width > NI_MAX_RESOLUTION_WIDTH || ((width > NI_MAX_RESOLUTION_RGBA_WIDTH) && isrgb))
6561 ni_log2(p_ctx, NI_LOG_ERROR, "Invalid Picture Width: too big for scaler\n");
6562 if(height > NI_MAX_RESOLUTION_HEIGHT || ((height > NI_MAX_RESOLUTION_RGBA_HEIGHT) && isrgb))
6563 ni_log2(p_ctx, NI_LOG_ERROR, "Invalid Picture Height: too big for scaler\n");
6564
6565 ni_log2(p_ctx, NI_LOG_ERROR, "Resolution %d x %d not supported for %d format!\n", width, height, format);
6566 ni_aligned_free(p_data);
6568 }
6569 ni_log2(p_ctx, NI_LOG_DEBUG,
6570 "Session=0x%x: Dev alloc frame: FrameIndex=%d; W=%d; H=%d; C=%d; RW=%d; RH=%d; RX=%d; RY=%d\n",
6571 p_ctx->session_id, p_data->frame_index,
6572 p_data->picture_width, p_data->picture_height,
6573 p_data->picture_format, p_data->rectangle_width,
6574 p_data->rectangle_height, p_data->rectangle_x, p_data->rectangle_y);
6575
6578
6579 for (;;)
6580 {
6581 query_retry++;
6582
6583 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
6584 p_data, dataLen, ui32LBA);
6585
6587 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_3);
6588
6590 {
6591 if (query_retry >= 1000 || (options & NI_SCALER_FLAG_PC))
6592 {
6593 ni_log2(p_ctx, NI_LOG_ERROR, "Error: 2D could not acquire frame\n");
6594 retval = NI_RETCODE_FAILURE;
6595 LRETURN;
6596 }
6598 continue;
6599 }
6600 else
6601 {
6602 p_ctx->pool_type = ((options & NI_SCALER_FLAG_IO) && (options & NI_SCALER_FLAG_PC)) ?
6603 (options & NI_SCALER_FLAG_P2) : (p_ctx->pool_type);
6604 break;
6605 }
6606 }
6607
6608 if (NI_RETCODE_SUCCESS != retval)
6609 {
6610 ni_log2(p_ctx, NI_LOG_ERROR,
6611 "ERROR: ni_nvme_send_admin_cmd failed: "
6612 "blk_io_handle: %" PRIx64 ", hw_id, %u, xcoder_inst_id: %d\n",
6613 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
6614 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n", __func__);
6616 }
6617
6618END:
6619
6620 ni_aligned_free(p_data);
6621 return retval;
6622}
6623
6624/*!******************************************************************************
6625 * \brief config a frame in the scaler
6626 *
6627 * \param[in] p_ctx pointer to session context
6628 * \param[in] p_cfg pointer to frame config
6629 *
6630 * \return NI_RETCODE_INVALID_PARAM
6631 * NI_RETCODE_ERROR_INVALID_SESSION
6632 * NI_RETCODE_ERROR_NVME_CMD_FAILED
6633 * NI_RETCODE_ERROR_MEM_ALOC
6634 *******************************************************************************/
6636 ni_frame_config_t *p_cfg)
6637{
6640 uint32_t dataLen;
6641 uint32_t ui32LBA = 0;
6642
6643 /* Round up to nearest 4096 bytes */
6644 dataLen =
6646 dataLen = dataLen & 0xFFFFF000;
6647
6648 if (!p_ctx || !p_cfg)
6649 {
6651 }
6652
6653 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
6654 {
6655 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
6656 __func__);
6658 }
6659
6660 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
6661 {
6662 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6663 NI_ERRNO, __func__);
6665 }
6666
6667 memset(p_data, 0x00, dataLen);
6668
6669 p_data->picture_width = p_cfg->picture_width;
6670 p_data->picture_height = p_cfg->picture_height;
6671 p_data->picture_format = p_cfg->picture_format;
6672 p_data->options = p_cfg->options;
6673
6674 p_data->rectangle_width = p_cfg->rectangle_width;
6675 p_data->rectangle_height = p_cfg->rectangle_height;
6676 p_data->rectangle_x = p_cfg->rectangle_x;
6677 p_data->rectangle_y = p_cfg->rectangle_y;
6678 p_data->rgba_color = p_cfg->rgba_color;
6679 p_data->frame_index = p_cfg->frame_index;
6680 p_data->session_id = p_cfg->session_id;
6681 p_data->output_index = p_cfg->output_index;
6682 switch (p_cfg->orientation)
6683 {
6684 case 0:
6685 case 2:
6686 case 4:
6687 case 5:
6688 p_data->orientation = p_cfg->orientation;
6689 break;
6690 case 1:
6691 p_data->orientation = 3;
6692 break;
6693 case 3:
6694 p_data->orientation = 1;
6695 break;
6696 default:
6697 ni_log2(p_ctx, NI_LOG_ERROR, "Bad orientation: %u\n", p_cfg->orientation);
6699 }
6700 bool isrgb = ((GC620_RGBA8888 == p_data->picture_format) || (GC620_BGRX8888 == p_data->picture_format) ||
6701 (GC620_ARGB8888 == p_data->picture_format) || (GC620_ABGR8888 == p_data->picture_format));
6705 {
6706 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);
6707 ni_aligned_free(p_data);
6709 }
6710
6711 ni_log2(p_ctx, NI_LOG_DEBUG,
6712 "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",
6713 p_ctx->session_id, p_cfg->frame_index,
6714 p_data->picture_width, p_data->picture_height,
6715 p_data->picture_format, p_data->rectangle_width,
6716 p_data->rectangle_height, p_data->rectangle_x,
6717 p_data->rectangle_y, p_data->orientation);
6718
6721
6722 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
6723 p_data, dataLen, ui32LBA);
6725 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
6726 if (NI_RETCODE_SUCCESS != retval)
6727 {
6728 ni_log2(p_ctx, NI_LOG_ERROR,
6729 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
6730 ", hw_id, %u, xcoder_inst_id: %d\n",
6731 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
6732
6733 ni_log2(p_ctx, NI_LOG_ERROR,
6734 "ERROR ni_scaler_config(): nvme command failed!\n");
6736 }
6737
6738END:
6739
6740 ni_aligned_free(p_data);
6741 return retval;
6742}
6743
6744/*!******************************************************************************
6745 * \brief config multiple frames in the scaler
6746 *
6747 * \param[in] p_ctx pointer to session context
6748 * \param[in] p_cfg_in pointer to input frame config array
6749 * \param[in] numInCfgs number of input frame configs in the p_cfg array
6750 * \param[in] p_cfg_out pointer to output frame config
6751 *
6752 * \return NI_RETCODE_INVALID_PARAM
6753 * NI_RETCODE_ERROR_INVALID_SESSION
6754 * NI_RETCODE_ERROR_NVME_CMD_FAILED
6755 * NI_RETCODE_ERROR_MEM_ALOC
6756 *******************************************************************************/
6758 ni_frame_config_t p_cfg_in[],
6759 int numInCfgs,
6760 ni_frame_config_t *p_cfg_out)
6761{
6763 ni_instance_mgr_allocation_info_t *p_data, *p_data_orig;
6764 uint32_t dataLen;
6765 uint32_t ui32LBA = 0;
6766 int i;
6767
6768 /* Round up to nearest 4096 bytes */
6769 dataLen =
6770 sizeof(ni_instance_mgr_allocation_info_t) * (numInCfgs + 1) + NI_MEM_PAGE_ALIGNMENT - 1;
6771 dataLen = dataLen & 0xFFFFF000;
6772
6773 if (!p_ctx || (!p_cfg_in && numInCfgs))
6774 {
6776 }
6777
6778 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
6779 {
6780 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
6781 __func__);
6783 }
6784
6785 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
6786 {
6787 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6788 NI_ERRNO, __func__);
6790 }
6791
6792 memset(p_data, 0x00, dataLen);
6793
6794 p_data_orig = p_data;
6795
6796 for (i = 0; i < numInCfgs; i++)
6797 {
6798 p_data->picture_width = p_cfg_in[i].picture_width;
6799 p_data->picture_height = p_cfg_in[i].picture_height;
6800 p_data->picture_format = p_cfg_in[i].picture_format;
6801 p_data->options = p_cfg_in[i].options & ~NI_SCALER_FLAG_IO;
6802
6803 p_data->rectangle_width = p_cfg_in[i].rectangle_width;
6804 p_data->rectangle_height = p_cfg_in[i].rectangle_height;
6805 p_data->rectangle_x = p_cfg_in[i].rectangle_x;
6806 p_data->rectangle_y = p_cfg_in[i].rectangle_y;
6807 p_data->rgba_color = p_cfg_in[i].rgba_color;
6808 p_data->frame_index = p_cfg_in[i].frame_index;
6809 p_data->session_id = p_cfg_in[i].session_id;
6810 p_data->output_index = p_cfg_in[i].output_index;
6811
6812 ni_log2(p_ctx, NI_LOG_DEBUG,
6813 "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",
6814 p_ctx->session_id, i,
6815 p_data->frame_index, p_data->session_id,
6816 p_data->picture_width, p_data->picture_height,
6817 p_data->picture_format, p_data->rectangle_width,
6818 p_data->rectangle_height, p_data->rectangle_x, p_data->rectangle_y);
6819
6820 p_data++;
6821 }
6822
6823 if (p_cfg_out)
6824 {
6825 p_data->picture_width = p_cfg_out->picture_width;
6826 p_data->picture_height = p_cfg_out->picture_height;
6827 p_data->picture_format = p_cfg_out->picture_format;
6828 p_data->options = p_cfg_out->options | NI_SCALER_FLAG_IO;
6829
6830 p_data->rectangle_width = p_cfg_out->rectangle_width;
6831 p_data->rectangle_height = p_cfg_out->rectangle_height;
6832 p_data->rectangle_x = p_cfg_out->rectangle_x;
6833 p_data->rectangle_y = p_cfg_out->rectangle_y;
6834 p_data->rgba_color = p_cfg_out->rgba_color;
6835 p_data->frame_index = p_cfg_out->frame_index;
6836
6837 ni_log2(p_ctx, NI_LOG_DEBUG,
6838 "Session=0x%x: Dev out config frame: FrameIndex=%u; W=%d; H=%d; C=%d; RW=%d; RH=%d; RX=%d; RY=%d\n",
6839 p_ctx->session_id, p_data->frame_index,
6840 p_data->picture_width, p_data->picture_height,
6841 p_data->picture_format, p_data->rectangle_width,
6842 p_data->rectangle_height, p_data->rectangle_x,
6843 p_data->rectangle_y);
6844 }
6846 {
6847 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);
6848 ni_aligned_free(p_data);
6850 }
6851
6854
6855 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
6856 p_data_orig, dataLen, ui32LBA);
6858 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
6859 if (NI_RETCODE_SUCCESS != retval)
6860 {
6861 ni_log2(p_ctx, NI_LOG_ERROR,
6862 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
6863 ", hw_id, %u, xcoder_inst_id: %d\n",
6864 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
6865
6866 ni_log2(p_ctx, NI_LOG_ERROR,
6867 "ERROR ni_scaler_config(): nvme command failed!\n");
6869 }
6870
6871END:
6872
6873 ni_aligned_free(p_data_orig);
6874 return retval;
6875}
6876
6877/*!******************************************************************************
6878 * \brief Query a particular xcoder instance to get GeneralStatus data
6879 *
6880 * \param ni_session_context_t p_ctx - xcoder Context
6881 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
6882 * \param ni_instance_mgr_general_status_t *out - Struct preallocated from the caller where the
6883 * resulting data will be placed
6884 *
6885 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
6886 *******************************************************************************/
6888{
6889 void* p_buffer = NULL;
6890 int retval = NI_RETCODE_SUCCESS;
6891 uint32_t ui32LBA = 0;
6893
6894 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
6895
6896 if ((!p_ctx) || (!p_gen_status))
6897 {
6898 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
6899 __func__);
6900 retval = NI_RETCODE_INVALID_PARAM;
6901 LRETURN;
6902 }
6903
6904 if (!IS_XCODER_DEVICE_TYPE(device_type))
6905 {
6906 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
6907 __func__, device_type);
6908 retval = NI_RETCODE_INVALID_PARAM;
6909 LRETURN;
6910 }
6911
6912 ui32LBA = QUERY_GENERAL_GET_STATUS_R(device_type);
6913
6914 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
6915 {
6916 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
6917 NI_ERRNO, __func__);
6919 LRETURN;
6920 }
6921
6922 memset(p_buffer, 0, dataLen);
6923
6924 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
6925 {
6926 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
6928 LRETURN;
6929 }
6930
6931 //No need to flip the bytes since the datastruct has only uint8_t datatypes
6932 memcpy((void*)p_gen_status, p_buffer, sizeof(ni_instance_mgr_general_status_t));
6933
6934 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): model_load:%u qc:%d percent:%d\n", __func__,
6935 p_gen_status->fw_model_load, p_gen_status->cmd_queue_count,
6936 p_gen_status->process_load_percent);
6937END:
6938
6939 ni_aligned_free(p_buffer);
6940 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
6941
6942 return retval;
6943}
6944
6945/*!******************************************************************************
6946 * \brief Query a particular xcoder instance to get DetailStatus data
6947 *
6948 * \param ni_session_context_t p_ctx - xcoder Context
6949 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
6950 * \param ni_instance_mgr_detail_status_t *out - Struct preallocated from the caller where the
6951 * resulting data will be placed
6952 *
6953 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
6954 *******************************************************************************/
6955int ni_query_detail_status(ni_session_context_t* p_ctx, ni_device_type_t device_type, void* p_detail_status, int ver)
6956{
6957 void* p_buffer = NULL;
6958 int retval = NI_RETCODE_SUCCESS;
6959 uint32_t ui32LBA = 0;
6960 uint32_t dataLen = 0;
6961 uint32_t copyLen = 0;
6962 if(ver == 0)
6963 {
6964 ui32LBA = QUERY_DETAIL_GET_STATUS_R(device_type);
6966 dataLen = ((copyLen + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
6967 }
6968 else if(ver == 1)
6969 {
6970 ui32LBA = QUERY_DETAIL_GET_STATUS_V1_R(device_type);
6971 copyLen = sizeof(ni_instance_mgr_detail_status_v1_t);
6973 }
6974 else
6975 {
6976 retval = NI_RETCODE_INVALID_PARAM;
6977 LRETURN;
6978 }
6979
6980 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
6981
6982 if ((!p_ctx) || (!p_detail_status))
6983 {
6984 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
6985 __func__);
6986 retval = NI_RETCODE_INVALID_PARAM;
6987 LRETURN;
6988 }
6989
6990 if (!IS_XCODER_DEVICE_TYPE(device_type))
6991 {
6992 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
6993 __func__, device_type);
6994 retval = NI_RETCODE_INVALID_PARAM;
6995 LRETURN;
6996 }
6997
6998 if (ni_posix_memalign((void **)&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
6999 {
7000 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7001 NI_ERRNO, __func__);
7003 LRETURN;
7004 }
7005
7006 memset(p_buffer, 0, dataLen);
7007
7008 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
7009 {
7010 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7012 LRETURN;
7013 }
7014
7015 //No need to flip the bytes since the datastruct has only uint8_t datatypes
7016 memcpy(p_detail_status, p_buffer, copyLen);
7017
7018END:
7019
7020 ni_aligned_free(p_buffer);
7021 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7022
7023 return retval;
7024}
7025
7026/*!******************************************************************************
7027 * \brief Query a particular xcoder instance to get Stream Info data
7028 *
7029 * \param ni_session_context_t p_ctx - xcoder Context
7030 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7031 * \param ni_instance_mgr_stream_info_t *out - Struct preallocated from the caller where the
7032 * resulting data will be placed
7033 *
7034 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_MEM_ALOC
7035 * or NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7036 *******************************************************************************/
7038{
7039 void* p_buffer = NULL;
7041 uint32_t ui32LBA = 0;
7043
7044 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7045
7046 if ((!p_ctx) || (!p_stream_info))
7047 {
7048 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7049 __func__);
7050 retval = NI_RETCODE_INVALID_PARAM;
7051 LRETURN;
7052 }
7053
7054 if (! (NI_DEVICE_TYPE_DECODER == device_type ||
7055 NI_DEVICE_TYPE_ENCODER == device_type))
7056 {
7057 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7058 __func__, device_type);
7059 retval = NI_RETCODE_INVALID_PARAM;
7060 LRETURN;
7061 }
7062
7063 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7064 {
7065 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7066 __func__);
7068 LRETURN;
7069 }
7070
7071 ui32LBA = QUERY_INSTANCE_STREAM_INFO_R(p_ctx->session_id, device_type);
7072
7073 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
7074 {
7075 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7076 NI_ERRNO, __func__);
7078 LRETURN;
7079 }
7080 memset(p_buffer, 0, dataLen);
7081
7082 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
7083 {
7084 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7086 LRETURN;
7087 }
7088
7089 memcpy((void*)p_stream_info, p_buffer, sizeof(ni_instance_mgr_stream_info_t));
7090
7091 //flip the bytes to host order
7092 p_stream_info->picture_width = ni_htons(p_stream_info->picture_width);
7093 p_stream_info->picture_height = ni_htons(p_stream_info->picture_height);
7094 p_stream_info->frame_rate = ni_htons(p_stream_info->frame_rate);
7095 p_stream_info->is_flushed = ni_htons(p_stream_info->is_flushed);
7096 p_stream_info->transfer_frame_stride = ni_htons(p_stream_info->transfer_frame_stride);
7097 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): pix_format = %d\n", __func__,
7098 p_stream_info->pix_format); //temp
7099
7100END:
7101
7102 ni_aligned_free(p_buffer);
7103 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7104
7105 return retval;
7106}
7107
7108/*!*****************************************************************************
7109 * \brief Query a particular session to get the stats info
7110 *
7111 * \param ni_session_context_t p_ctx - xcoder Context
7112 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7113 * \param ni_session_stats_t *out - Struct preallocated from the
7114 * caller where the resulting data will be placed
7115 *
7116 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
7117 * NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED
7118 * on failure
7119 ******************************************************************************/
7121 ni_device_type_t device_type,
7122 ni_session_stats_t *p_session_stats, int rc,
7123 int opcode)
7124{
7125 (void)opcode;
7127 void* p_buffer = NULL;
7128 uint64_t session_timestamp;
7129 uint32_t ui32LBA = 0;
7131
7132 ni_device_type_t xc_device_type =
7133 (device_type != NI_DEVICE_TYPE_UPLOAD ? device_type :
7135
7136 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7137
7138 if ((!p_ctx) || (!p_session_stats))
7139 {
7140 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7141 __func__);
7142 retval = NI_RETCODE_INVALID_PARAM;
7143 LRETURN;
7144 }
7145
7146 if (!IS_XCODER_DEVICE_TYPE(xc_device_type))
7147 {
7148 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7149 __func__, device_type);
7150 retval = NI_RETCODE_INVALID_PARAM;
7151 LRETURN;
7152 }
7153
7154 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7155 {
7156 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7157 __func__);
7159 LRETURN;
7160 }
7161
7162 ui32LBA = QUERY_SESSION_STATS_R(p_ctx->session_id, xc_device_type);
7163
7164 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
7165 {
7166 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7167 NI_ERRNO, __func__);
7169 LRETURN;
7170 }
7171 memset(p_buffer, 0, dataLen);
7172
7173 // Set session ID to be invalid. In case, the last command fails because the invalid session ID was submitted
7174 // with the command, the session id would remain invalid.
7175 // If the last command is processed successfully in session manager, the session id would become valid.
7176 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
7177 (uint16_t)NI_INVALID_SESSION_ID;
7178
7179 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA)
7180 < 0)
7181 {
7182 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): read command Failed\n", __func__);
7184 LRETURN;
7185 }
7186
7187 memcpy((void*)p_session_stats, p_buffer, sizeof(ni_session_stats_t));
7188
7189 // flip the bytes to host order
7190 // all query commands are guaranteed success once a session is opened
7191 p_session_stats->ui16SessionId = ni_htons(p_session_stats->ui16SessionId);
7192 p_session_stats->ui16ErrorCount = ni_htons(p_session_stats->ui16ErrorCount);
7193 p_session_stats->ui32LastTransactionId =
7194 ni_htonl(p_session_stats->ui32LastTransactionId);
7195 p_session_stats->ui32LastTransactionCompletionStatus =
7196 ni_htonl(p_session_stats->ui32LastTransactionCompletionStatus);
7197 p_session_stats->ui32LastErrorTransactionId = ni_htonl(p_session_stats->ui32LastErrorTransactionId);
7198 p_session_stats->ui32LastErrorStatus = ni_htonl(p_session_stats->ui32LastErrorStatus);
7199 p_session_stats->ui32Session_timestamp_high = ni_htonl(p_session_stats->ui32Session_timestamp_high);
7200 p_session_stats->ui32Session_timestamp_low = ni_htonl(p_session_stats->ui32Session_timestamp_low);
7201
7202 session_timestamp = p_session_stats->ui32Session_timestamp_high;
7203 session_timestamp <<= 32;
7204 session_timestamp |= p_session_stats->ui32Session_timestamp_low;
7205
7206 // get the session timestamp when open session
7207 // check the timestamp during transcoding
7208 if ((p_ctx->session_timestamp != session_timestamp) &&
7210 // if VPU recovery, the session timestamp will be reset.
7211 {
7212 p_session_stats->ui32LastErrorStatus =
7214 ni_log2(p_ctx, NI_LOG_DEBUG, "instance id invalid:%u, timestamp:%" PRIu64 ", "
7215 "query timestamp:%" PRIu64 "\n", p_ctx->session_id,
7216 p_ctx->session_timestamp, session_timestamp);
7217 }
7218
7219 // check rc here, if rc != NI_RETCODE_SUCCESS, it means that last read/write command failed
7220 // failures may be link layer errors, such as physical link errors or ERROR_WRITE_PROTECT in windows.
7221 if (NI_RETCODE_SUCCESS != rc)
7222 {
7223 ni_log2(p_ctx, NI_LOG_ERROR, "%s():last command Failed: rc %d\n", __func__, rc);
7224 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 "
7225 "ready_to_close %u session_run_state %d active_video_width %u active_video_height %u\n",
7226 __func__,
7227 p_ctx->session_id,
7228 p_ctx->session_timestamp,
7229 p_ctx->hw_id,
7230 p_ctx->device_type,
7231 p_ctx->codec_format,
7232 p_ctx->frame_num,
7233 p_ctx->pkt_num,
7234 p_ctx->ready_to_close,
7235 p_ctx->session_run_state,
7236 p_ctx->active_video_width,
7237 p_ctx->active_video_height);
7238
7239#if __linux__ || __APPLE__
7240#if !defined(_ANDROID) && !defined(__OPENHARMONY__)
7241#ifndef DISABLE_BACKTRACE_PRINT
7242 ni_print_backtrace(); // log backtrace
7243#endif
7244#endif
7245#endif
7246
7247 p_session_stats->ui32LastTransactionCompletionStatus =
7251 } else if (p_ctx->session_id != p_session_stats->ui16SessionId)
7252 {
7253 uint64_t ct = ni_gettime_ns();
7254 uint64_t dt = ct - p_ctx->last_access_time;
7255 ni_log2(p_ctx, NI_LOG_ERROR,
7256 "%s(): device 0x%" PRIx64 " last command Failed due to wrong "
7257 "session ID. Expected 0x%x, got 0x%x keep alive last access "
7258 "time %" PRIu64 ", current %" PRIu64 "\n", __func__,
7259 (int64_t)p_ctx->blk_io_handle, p_ctx->session_id,
7260 p_session_stats->ui16SessionId, p_ctx->last_access_time, ct);
7261 if (dt > 1000000000)
7262 {
7263 ni_log2(p_ctx, NI_LOG_ERROR,
7264 "%s():long delay between last command dt = %" PRId64 " ns, "
7265 "process was possibly blocked.\n", __func__, dt);
7266 }
7268
7269 // Mark session id to INVALID so that all commands afterward are blocked
7271 }
7272
7273 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): error count %u last rc 0x%x inst_err_no 0x%x\n",
7274 __func__, p_session_stats->ui16ErrorCount,
7275 p_session_stats->ui32LastTransactionCompletionStatus,
7276 p_session_stats->ui32LastErrorStatus);
7277
7278END:
7279
7280 ni_aligned_free(p_buffer);
7281 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7282
7283 return retval;
7284}
7285
7286/*!******************************************************************************
7287 * \brief Query a particular xcoder instance to get End of Output data
7288 *
7289 * \param ni_session_context_t p_ctx - xcoder Context
7290 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7291 * \param InstMgrStreamComp *out - Struct preallocated from the caller where the
7292 * resulting data will be placed
7293 *
7294 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_MEM_ALOC
7295 * or NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7296 *******************************************************************************/
7298{
7299 void* p_buffer = NULL;
7301 uint32_t ui32LBA = 0;
7303
7304 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7305
7306 if (!p_ctx || !p_stream_complete)
7307 {
7308 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7309 __func__);
7310 retval = NI_RETCODE_INVALID_PARAM;
7311 LRETURN;
7312 }
7313
7314 if (! (NI_DEVICE_TYPE_DECODER == device_type ||
7315 NI_DEVICE_TYPE_ENCODER == device_type))
7316 {
7317 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7318 __func__, device_type);
7319 retval = NI_RETCODE_INVALID_PARAM;
7320 LRETURN;
7321 }
7322
7323 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7324 {
7325 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7326 __func__);
7328 LRETURN;
7329 }
7330
7331 ui32LBA = QUERY_INSTANCE_EOS_R(p_ctx->session_id, device_type);
7332
7333 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
7334 {
7335 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate buffer.\n");
7337 LRETURN;
7338 }
7339
7340 memset(p_buffer, 0, dataLen);
7341
7342 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
7343 {
7344 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7346 LRETURN;
7347 }
7348
7349 memcpy((void*)p_stream_complete, p_buffer, sizeof(ni_instance_mgr_stream_complete_t));
7350
7351 //flip the bytes to host order
7352 p_stream_complete->is_flushed = ni_htons(p_stream_complete->is_flushed);
7353
7354END:
7355
7356 ni_aligned_free(p_buffer);
7357 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7358
7359 return retval;
7360}
7361
7362static const char* ni_get_device_type_str(int type)
7363{
7364 if (type < NI_DEVICE_TYPE_DECODER || type > NI_DEVICE_TYPE_AI)
7365 {
7366 return "Invalid device type";
7367 }
7368 return g_device_type_str[type];
7369}
7370
7371static void
7372ni_parse_session_statistic_info(ni_session_context_t *p_ctx,
7373 ni_session_statistic_t *p_session_statistic,
7374 void *p_buffer)
7375{
7376 memcpy((void *)p_session_statistic, p_buffer,
7377 sizeof(ni_session_statistic_t));
7378
7379 //flip the bytes to host order
7380 p_session_statistic->ui32RdBufAvailSize =
7381 ni_htonl(p_session_statistic->ui32RdBufAvailSize);
7382 p_session_statistic->ui32WrBufAvailSize =
7383 ni_htonl(p_session_statistic->ui32WrBufAvailSize);
7384
7385 p_session_statistic->ui32FramesInput =
7386 ni_htonl(p_session_statistic->ui32FramesInput);
7387 p_session_statistic->ui32FramesBuffered =
7388 ni_htonl(p_session_statistic->ui32FramesBuffered);
7389 p_session_statistic->ui32FramesCompleted =
7390 ni_htonl(p_session_statistic->ui32FramesCompleted);
7391 p_session_statistic->ui32FramesOutput =
7392 ni_htonl(p_session_statistic->ui32FramesOutput);
7393 p_session_statistic->ui32FramesDropped =
7394 ni_htonl(p_session_statistic->ui32FramesDropped);
7395 p_session_statistic->ui32InstErrors =
7396 ni_htonl(p_session_statistic->ui32InstErrors);
7397
7398 p_session_statistic->ui16SessionId =
7399 ni_htons(p_session_statistic->ui16SessionId);
7400 p_session_statistic->ui16ErrorCount =
7401 ni_htons(p_session_statistic->ui16ErrorCount);
7402 p_session_statistic->ui32LastTransactionId =
7403 ni_htonl(p_session_statistic->ui32LastTransactionId);
7404 p_session_statistic->ui32LastTransactionCompletionStatus =
7405 ni_htonl(p_session_statistic->ui32LastTransactionCompletionStatus);
7406 p_session_statistic->ui32LastErrorTransactionId =
7407 ni_htonl(p_session_statistic->ui32LastErrorTransactionId);
7408 p_session_statistic->ui32LastErrorStatus =
7409 ni_htonl(p_session_statistic->ui32LastErrorStatus);
7410 p_session_statistic->ui32Session_timestamp_high =
7411 ni_htonl(p_session_statistic->ui32Session_timestamp_high);
7412 p_session_statistic->ui32Session_timestamp_low =
7413 ni_htonl(p_session_statistic->ui32Session_timestamp_low);
7414
7415 // p_session_statistic->ui8AdditionalFramesDelay does not require endian conversion
7416
7417 if (p_ctx->session_id != p_session_statistic->ui16SessionId)
7418 {
7419 uint64_t ct = ni_gettime_ns();
7420 uint64_t dt = ct - p_ctx->last_access_time;
7421 ni_log2(p_ctx, NI_LOG_ERROR,
7422 "%s(): %s device 0x%" PRIx64 " last command Failed due to wrong "
7423 "session ID. Expected 0x%x, got 0x%x w_r <%u %u> keep alive "
7424 "last access time %" PRIu64 ", current %" PRIu64 "\n", __func__,
7425 ni_get_device_type_str((int)p_ctx->device_type),
7426 (int64_t)p_ctx->device_handle, p_ctx->session_id,
7427 p_session_statistic->ui16SessionId,
7428 p_session_statistic->ui32WrBufAvailSize,
7429 p_session_statistic->ui32RdBufAvailSize, p_ctx->last_access_time,
7430 ct);
7431 if (dt > 1000000000)
7432 {
7433 ni_log2(p_ctx, NI_LOG_ERROR,
7434 "%s():long delay between last command dt = %" PRId64 " ns, "
7435 "process was possibly blocked.\n", __func__, dt);
7436 }
7437 p_session_statistic->ui32LastErrorStatus =
7439 //Mark session id to INVALID so that all commands afterward are blocked
7441 } else
7442 {
7443 //Acknowledge that total error count here
7444 }
7445
7446 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): error count %u last rc 0x%x inst_err_no 0x%x\n",
7447 __func__, p_session_statistic->ui16ErrorCount,
7448 p_session_statistic->ui32LastTransactionCompletionStatus,
7449 p_session_statistic->ui32LastErrorStatus);
7450}
7451
7452/*!*****************************************************************************
7453 * \brief Query a particular xcoder session to get session statistics
7454 *
7455 * \param ni_session_context_t p_ctx - xcoder Context
7456 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7457 * \param ni_session_statistic_t*out - Struct preallocated from the caller
7458 * where the resulting data will be placed
7459 *
7460 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
7461 * NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on
7462 * failure
7463 ******************************************************************************/
7466 ni_device_type_t device_type,
7467 ni_session_statistic_t *p_session_statistic)
7468{
7469 void *p_buffer = NULL;
7471 uint32_t ui32LBA = 0;
7472 uint32_t dataLen =
7476
7477 if (!p_ctx || !p_session_statistic)
7478 {
7479 ni_log2(p_ctx, NI_LOG_ERROR,
7480 "ERROR: %s() passed parameters are null!, return\n", __func__);
7481 retval = NI_RETCODE_INVALID_PARAM;
7482 LRETURN;
7483 }
7484
7486 "65") < 0)
7487 {
7488 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() not supported on device with FW api version < 6.5\n", __func__);
7490 }
7491
7492 if (!(NI_DEVICE_TYPE_DECODER == device_type ||
7493 NI_DEVICE_TYPE_ENCODER == device_type ||
7494 NI_DEVICE_TYPE_AI == device_type))
7495 {
7496 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7497 __func__, device_type);
7498 retval = NI_RETCODE_INVALID_PARAM;
7499 LRETURN;
7500 }
7501
7502 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7503 {
7504 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7505 __func__);
7507 LRETURN;
7508 }
7509
7510 ui32LBA = QUERY_INSTANCE_CUR_STATUS_INFO_R(p_ctx->session_id, device_type);
7511
7512 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
7513 {
7514 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7515 NI_ERRNO, __func__);
7517 LRETURN;
7518 }
7519 memset(p_buffer, 0, dataLen);
7520
7521 // Set session ID to be invalid. In case, the last command fails because the invalid session ID was submitted
7522 // with the command, the session id would remain invalid.
7523 // If the Last command is processed successfully in session manager, the session id would become valid.
7524 ((ni_session_statistic_t *)p_buffer)->ui16SessionId =
7525 (uint16_t)NI_INVALID_SESSION_ID;
7526
7528 p_buffer, dataLen, ui32LBA) < 0)
7529 {
7530 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): NVME command Failed\n", __func__);
7531 p_session_statistic->ui32LastTransactionCompletionStatus =
7533 p_session_statistic->ui32LastErrorStatus =
7536 LRETURN;
7537 }
7538
7539 ni_parse_session_statistic_info(p_ctx, p_session_statistic, p_buffer);
7540 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
7541 {
7543 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, %s return.\n",
7544 __func__, ni_get_device_type_str((int)p_ctx->device_type));
7545 LRETURN;
7546 }
7547 p_ctx->session_statistic = *p_session_statistic;
7548
7549END:
7550 ni_aligned_free(p_buffer);
7551 ni_log2(p_ctx, NI_LOG_TRACE, "%s():exit\n", __func__);
7552
7553 return retval;
7554}
7555/*!*****************************************************************************
7556 * \brief Query a particular xcoder instance to get buffer/data Info data
7557 *
7558 * \param ni_session_context_t p_ctx - xcoder Context
7559 * \param ni_instance_buf_info_rw_type_t rw_type
7560 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7561 * \param ni_instance_buf_info_t *out - Struct preallocated from the caller
7562 * where the resulting data will be placed
7563 *
7564 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
7565 * NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on
7566 * failure
7567 ******************************************************************************/
7570 ni_device_type_t device_type,
7571 ni_instance_buf_info_t *p_inst_buf_info)
7572{
7573 void* p_buffer = NULL;
7575 uint32_t ui32LBA = 0;
7576 uint32_t dataLen =
7580
7581 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7582
7583 if (!p_ctx || !p_inst_buf_info)
7584 {
7585 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7586 __func__);
7587 retval = NI_RETCODE_INVALID_PARAM;
7588 LRETURN;
7589 }
7590
7591 if (!(NI_DEVICE_TYPE_DECODER == device_type ||
7592 NI_DEVICE_TYPE_ENCODER == device_type ||
7593 NI_DEVICE_TYPE_SCALER == device_type ||
7594 NI_DEVICE_TYPE_AI == device_type))
7595 {
7596 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7597 __func__, device_type);
7598 retval = NI_RETCODE_INVALID_PARAM;
7599 LRETURN;
7600 }
7601
7602 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7603 {
7604 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7605 __func__);
7607 LRETURN;
7608 }
7609
7610 if (INST_BUF_INFO_RW_READ == rw_type)
7611 {
7612 ui32LBA = QUERY_INSTANCE_RBUFF_SIZE_R(p_ctx->session_id, device_type);
7613 }
7614 else if (INST_BUF_INFO_RW_WRITE == rw_type)
7615 {
7616 ui32LBA = QUERY_INSTANCE_WBUFF_SIZE_R(p_ctx->session_id, device_type);
7617 }
7618 else if(INST_BUF_INFO_RW_WRITE_BY_EP == rw_type)
7619 {
7621 "65") >= 0)
7622 {
7623 ui32LBA = QUERY_INSTANCE_WBUFF_SIZE_R_BY_EP(p_ctx->session_id, device_type);
7624 }
7625 else
7626 {
7628 LRETURN;
7629 }
7630 }
7631 else if (INST_BUF_INFO_RW_UPLOAD == rw_type)
7632 {
7633 ui32LBA = QUERY_INSTANCE_UPLOAD_ID_R(p_ctx->session_id, device_type);
7634 } else if (INST_BUF_INFO_R_ACQUIRE == rw_type)
7635 {
7636 ui32LBA = QUERY_INSTANCE_ACQUIRE_BUF(p_ctx->session_id, device_type);
7637 } else if (INST_BUF_INFO_RW_READ_BUSY == rw_type)
7638 {
7639 ui32LBA =
7640 QUERY_INSTANCE_RBUFF_SIZE_BUSY_R(p_ctx->session_id, device_type);
7641 } else if (INST_BUF_INFO_RW_WRITE_BUSY == rw_type)
7642 {
7643 ui32LBA =
7644 QUERY_INSTANCE_WBUFF_SIZE_BUSY_R(p_ctx->session_id, device_type);
7645 } else if (INST_BUF_INFO_RW_READ_BY_AI == rw_type)
7646 {
7647 ui32LBA = QUERY_INSTANCE_AI_INFO_R(p_ctx->session_id, device_type);
7648 } else
7649 {
7650 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown query type %d, return\n",
7651 __func__, rw_type);
7652 retval = NI_RETCODE_INVALID_PARAM;
7653 LRETURN;
7654 }
7655
7656 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
7657 {
7658 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7659 NI_ERRNO, __func__);
7661 LRETURN;
7662 }
7663
7664 memset(p_buffer, 0, dataLen);
7665
7666 if (ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, dataLen, ui32LBA) < 0)
7667 {
7668 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7670 LRETURN;
7671 }
7672
7673 memcpy((void*)p_inst_buf_info, p_buffer, sizeof(ni_instance_buf_info_t));
7674
7675 p_inst_buf_info->buf_avail_size = ni_htonl(p_inst_buf_info->buf_avail_size);
7676
7677END:
7678
7679 ni_aligned_free(p_buffer);
7680 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7681
7682 return retval;
7683}
7684
7685/*!*****************************************************************************
7686 * \brief Configure the read/write pipe for a session to control its behavior
7687 *
7688 * \param ni_session_context_t p_ctx - xcoder Context
7689 * \param ni_session_config_rw_t rw_type
7690 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7691 * \param uint8_t enable
7692 * \param uint8_t hw_action
7693 * \param uint16_t frame_id
7694 *
7695 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
7696 * NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on
7697 * failure
7698 ******************************************************************************/
7701 uint8_t enable, uint8_t hw_action,
7702 uint16_t frame_id)
7703{
7705 uint32_t ui32LBA = 0;
7706 void * p_buffer = NULL;
7707 uint32_t buffer_size = 0;
7708 ni_session_config_rw_t * rw_config = NULL;
7709
7710 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7711
7712 if (!p_ctx)
7713 {
7714 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7715 __func__);
7716 retval = NI_RETCODE_INVALID_PARAM;
7717 LRETURN;
7718 }
7719
7720 if (!((SESSION_READ_CONFIG == rw_type) || (SESSION_WRITE_CONFIG == rw_type)))
7721 {
7722 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown config type %d, return\n",
7723 __func__, rw_type);
7724 retval = NI_RETCODE_INVALID_PARAM;
7725 LRETURN;
7726 }
7727
7729 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
7730 {
7731 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
7732 NI_ERRNO, __func__);
7734 LRETURN;
7735 }
7736 memset(p_buffer, 0, buffer_size);
7737 rw_config = (ni_session_config_rw_t *)p_buffer;
7738 rw_config->ui8Enable = enable;
7739 rw_config->ui8HWAccess = hw_action;
7740 switch(rw_type)
7741 {
7743 rw_config->uHWAccessField.ui16ReadFrameId = frame_id;
7744 break;
7746 rw_config->uHWAccessField.ui16WriteFrameId = frame_id;
7747 break;
7748 default:
7749 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown config type %d, return\n",
7750 __func__, rw_type);
7751 retval = NI_RETCODE_INVALID_PARAM;
7752 LRETURN;
7753 }
7754
7755 switch(rw_type)
7756 {
7758 ui32LBA = CONFIG_SESSION_Read_W(p_ctx->session_id);
7759 break;
7761 ui32LBA = CONFIG_SESSION_Write_W(p_ctx->session_id);
7762 break;
7763 default:
7764 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown config type %d, return\n",
7765 __func__, rw_type);
7766 retval = NI_RETCODE_INVALID_PARAM;
7767 LRETURN;
7768 }
7769 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, buffer_size, ui32LBA) < 0)
7770 {
7771 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7773 LRETURN;
7774 }
7775
7776END:
7777
7778 ni_aligned_free(p_buffer);
7779 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7780
7781 return retval;
7782}
7783
7784/*!******************************************************************************
7785 * \brief Send a p_config command for Start Of Stream
7786 *
7787 * \param ni_session_context_t p_ctx - xcoder Context
7788 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7789 *
7790 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION. NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7791 *******************************************************************************/
7793{
7795 uint32_t ui32LBA = 0;
7796
7797 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7798
7799 if (!p_ctx)
7800 {
7801 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7802 __func__);
7803 retval = NI_RETCODE_INVALID_PARAM;
7804 LRETURN;
7805 }
7806
7807 if (! (NI_DEVICE_TYPE_DECODER == device_type ||
7808 NI_DEVICE_TYPE_ENCODER == device_type))
7809 {
7810 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7811 __func__, device_type);
7812 retval = NI_RETCODE_INVALID_PARAM;
7813 LRETURN;
7814 }
7815
7816 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7817 {
7818 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7819 __func__);
7821 LRETURN;
7822 }
7823
7824 ui32LBA = CONFIG_INSTANCE_SetSOS_W(p_ctx->session_id, device_type);
7825
7826 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)
7827 {
7828 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7830 }
7831
7832END:
7833
7834 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7835 return retval;
7836}
7837
7838/*!******************************************************************************
7839 * \brief Send a p_config command for End Of Stream
7840 *
7841 * \param ni_session_context_t p_ctx - xcoder Context
7842 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7843 *
7844 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7845 *******************************************************************************/
7847{
7849 uint32_t ui32LBA = 0;
7850
7851 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7852
7853 if (!p_ctx)
7854 {
7855 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7856 __func__);
7857 retval = NI_RETCODE_INVALID_PARAM;
7858 LRETURN;
7859 }
7860
7861 if (! (NI_DEVICE_TYPE_DECODER == device_type ||
7862 NI_DEVICE_TYPE_ENCODER == device_type))
7863 {
7864 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7865 __func__, device_type);
7866 retval = NI_RETCODE_INVALID_PARAM;
7867 LRETURN;
7868 }
7869
7870 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7871 {
7872 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7873 __func__);
7875 LRETURN;
7876 }
7877
7878 ui32LBA = CONFIG_INSTANCE_SetEOS_W(p_ctx->session_id, device_type);
7879
7880 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)
7881 {
7882 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
7884 }
7885
7886END:
7887
7888 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7889
7890 return retval;
7891}
7892
7893/*!******************************************************************************
7894 * \brief Send a p_config command to flush the stream
7895 *
7896 * \param ni_session_context_t p_ctx - xcoder Context
7897 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7898 *
7899 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7900 *******************************************************************************/
7902{
7904 uint32_t ui32LBA = 0;
7905
7906 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7907
7908 if (!p_ctx)
7909 {
7910 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7911 __func__);
7912 retval = NI_RETCODE_INVALID_PARAM;
7913 LRETURN;
7914 }
7915
7916 if (NI_DEVICE_TYPE_DECODER != device_type)
7917 {
7918 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7919 __func__, device_type);
7920 retval = NI_RETCODE_INVALID_PARAM;
7921 LRETURN;
7922 }
7923
7924 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7925 {
7926 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7927 __func__);
7929 LRETURN;
7930 }
7931
7932 ui32LBA = CONFIG_INSTANCE_Flush_W(p_ctx->session_id, device_type);
7933 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
7935 ui32LBA);
7937 p_ctx->device_type, p_ctx->hw_id,
7938 &(p_ctx->session_id), OPT_1);
7939 CHECK_VPU_RECOVERY(retval);
7940
7941END:
7942
7943 if (NI_RETCODE_SUCCESS != retval)
7944 {
7946 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed with %d\n", __func__, retval);
7947 }
7948
7949 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
7950
7951 return retval;
7952}
7953
7954/*!******************************************************************************
7955 * \brief Send a p_config command to set the length for the incoming write packet
7956 *
7957 * \param ni_session_context_t p_ctx - xcoder Context
7958 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
7959 * \param
7960 *
7961 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
7962 *******************************************************************************/
7964{
7966 uint32_t ui32LBA = 0;
7967 void * p_buffer = NULL;
7968 uint32_t buffer_size = 0;
7969
7970 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
7971
7972 if (!p_ctx)
7973 {
7974 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
7975 __func__);
7976 retval = NI_RETCODE_INVALID_PARAM;
7977 LRETURN;
7978 }
7979
7980 if (!(NI_DEVICE_TYPE_DECODER == device_type ||
7981 NI_DEVICE_TYPE_ENCODER == device_type))
7982 {
7983 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Unknown device type %d, return\n",
7984 __func__, device_type);
7985 retval = NI_RETCODE_INVALID_PARAM;
7986 LRETURN;
7987 }
7988
7989 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
7990 {
7991 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
7992 __func__);
7994 LRETURN;
7995 }
7996
7997 buffer_size = ((sizeof(len) + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
7998 if (ni_posix_memalign(&p_buffer, 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 LRETURN;
8004 }
8005 memset(p_buffer, 0, buffer_size);
8006 memcpy(p_buffer, &len, sizeof(len));
8007
8008 ui32LBA = CONFIG_INSTANCE_SetPktSize_W(p_ctx->session_id, device_type);
8009
8010 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, buffer_size, ui32LBA) < 0)
8011 {
8012 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
8014 }
8015
8016END:
8017
8018 ni_aligned_free(p_buffer);
8019 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
8020
8021 return retval;
8022}
8023
8024/*!******************************************************************************
8025 * \brief Send a p_config command to inform encoder sequence change
8026 *
8027 * \param ni_session_context_t p_ctx - xcoder Context
8028 * \param ni_device_type_t device_type - xcoder type Encoder or Decoder
8029 * \param ni_resolution_t p_resolution - sequence change resolution
8030 *
8031 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
8032 *******************************************************************************/
8034{
8036 uint32_t ui32LBA = 0;
8037 void * p_buffer = NULL;
8038 uint32_t buffer_size = 0;
8039
8040 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
8041
8042 if (!p_ctx)
8043 {
8044 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
8045 __func__);
8046 retval = NI_RETCODE_INVALID_PARAM;
8047 LRETURN;
8048 }
8049
8050 if (!(NI_DEVICE_TYPE_ENCODER == device_type))
8051 {
8052 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Seq Change not supported for device type %d, return\n", device_type);
8053 retval = NI_RETCODE_INVALID_PARAM;
8054 LRETURN;
8055 }
8056
8057 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
8058 {
8059 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
8060 __func__);
8062 LRETURN;
8063 }
8064
8066 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), buffer_size))
8067 {
8068 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
8069 NI_ERRNO, __func__);
8071 LRETURN;
8072 }
8073 memset(p_buffer, 0, buffer_size);
8074 memcpy(p_buffer, p_resolution, sizeof(ni_resolution_t));
8075
8076 ui32LBA = CONFIG_INSTANCE_SetSeqChange_W(p_ctx->session_id, device_type);
8077
8078 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_buffer, buffer_size, ui32LBA) < 0)
8079 {
8080 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
8082 }
8083
8084END:
8085
8086 ni_aligned_free(p_buffer);
8087 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
8088
8089 return retval;
8090}
8091
8092/*!******************************************************************************
8093 * \brief Send a p_config command to configure encoding parameters.
8094 *
8095 * \param ni_session_context_t p_ctx - xcoder Context
8096 *
8097 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
8098 *******************************************************************************/
8100{
8101 void* p_encoder_config = NULL;
8102 void* p_encoder_roi_qp_map = NULL;
8103 ni_encoder_config_t* p_cfg = NULL;
8104 uint32_t buffer_size = 0;
8106 uint32_t ui32LBA = 0;
8107 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
8108
8109 if (!p_ctx)
8110 {
8111 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
8112 __func__);
8113 retval = NI_RETCODE_INVALID_PARAM;
8114 LRETURN;
8115 }
8116
8117 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
8118 {
8119 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
8120 __func__);
8122 LRETURN;
8123 }
8124
8125 if (ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rh") >= 0)
8126 {
8128 ni_xcoder_params_t *session_config = (ni_xcoder_params_t *)p_ctx->p_session_config;
8129 if (session_config->cfg_enc_params.customize_roi_qp_level > 64) {
8131 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
8132 if (ni_posix_memalign(&p_encoder_roi_qp_map, sysconf(_SC_PAGESIZE), buffer_size))
8133 {
8134 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
8135 NI_ERRNO, __func__);
8137 LRETURN;
8138 }
8139 memset(p_encoder_roi_qp_map, 0, buffer_size);
8140 memcpy(p_encoder_roi_qp_map, session_config->customize_roi_qp_map,
8142 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
8143 p_encoder_roi_qp_map, buffer_size, ui32LBA);
8145 p_ctx->device_type, p_ctx->hw_id,
8146 &(p_ctx->session_id), OPT_1);
8147 if (NI_RETCODE_SUCCESS != retval)
8148 {
8149 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);
8150 //Close the session since we can't configure it
8151 retval = ni_encoder_session_close(p_ctx, 0);
8152 if (NI_RETCODE_SUCCESS != retval)
8153 {
8154 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);
8155 }
8157 LRETURN;
8158 }
8159 session_config->cfg_enc_params.customize_roi_qp_level -= 64;
8160 } else if (session_config->cfg_enc_params.customize_roi_qp_level == 64) {
8161 ni_log2(p_ctx, NI_LOG_INFO, "customizeQpMapFile is ignored since customizeQpLevel=0");
8162 session_config->cfg_enc_params.customize_roi_qp_level = 0;
8163 }
8164 }
8165
8166 buffer_size = sizeof(ni_encoder_config_t);
8167 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
8168 if (ni_posix_memalign(&p_encoder_config, sysconf(_SC_PAGESIZE), buffer_size))
8169 {
8170 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
8171 NI_ERRNO, __func__);
8173 LRETURN;
8174 }
8175 memset(p_encoder_config, 0, buffer_size);
8176
8177 ni_set_custom_template(p_ctx, p_encoder_config, p_ctx->p_session_config);
8178 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));
8179 if (NI_RETCODE_PARAM_WARN == retval)
8180 {
8181 ni_log2(p_ctx, NI_LOG_INFO, "WARNING: ni_validate_custom_template() . %s\n", p_ctx->param_err_msg);
8182 (void)fflush(stdout);
8183 }
8184 else if (NI_RETCODE_SUCCESS != retval)
8185 {
8186 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: ni_validate_custom_template() failed. %s\n", p_ctx->param_err_msg);
8187 (void)fflush(stdout);
8188 retval = NI_RETCODE_INVALID_PARAM;
8189 LRETURN;
8190 }
8191 //configure the session here
8193
8194 //Flip the bytes!! any param 16bits in size need ni_htons, 32bit need ni_htonl
8195 p_cfg = (ni_encoder_config_t*)p_encoder_config;
8196 p_cfg->i32picWidth = (int32_t)ni_htonl(p_cfg->i32picWidth);
8197 p_cfg->i32picHeight = (int32_t)ni_htonl(p_cfg->i32picHeight);
8198 p_cfg->i32meBlkMode = (int32_t)ni_htonl(p_cfg->i32meBlkMode);
8199 p_cfg->i32frameRateInfo = (int32_t)ni_htonl(p_cfg->i32frameRateInfo);
8200 p_cfg->i32vbvBufferSize = (int32_t)ni_htonl(p_cfg->i32vbvBufferSize);
8201 p_cfg->i32userQpMax = (int32_t)ni_htonl(p_cfg->i32userQpMax);
8202 p_cfg->i32maxIntraSize = (int32_t)ni_htonl(p_cfg->i32maxIntraSize);
8203 p_cfg->i32userMaxDeltaQp = (int32_t)ni_htonl(p_cfg->i32userMaxDeltaQp);
8204 p_cfg->i32userMinDeltaQp = (int32_t)ni_htonl(p_cfg->i32userMinDeltaQp);
8205 p_cfg->i32userQpMin = (int32_t)ni_htonl(p_cfg->i32userQpMin);
8206 p_cfg->i32bitRate = (int32_t)ni_htonl(p_cfg->i32bitRate);
8207 p_cfg->i32bitRateBL = (int32_t)ni_htonl(p_cfg->i32bitRateBL);
8208 p_cfg->i32srcBitDepth = (int32_t)ni_htonl(p_cfg->i32srcBitDepth);
8209 p_cfg->hdrEnableVUI = ni_htonl(p_cfg->hdrEnableVUI);
8210 p_cfg->ui32VuiDataSizeBits = ni_htonl(p_cfg->ui32VuiDataSizeBits);
8211 p_cfg->ui32VuiDataSizeBytes = ni_htonl(p_cfg->ui32VuiDataSizeBytes);
8212 p_cfg->i32hwframes = (int32_t)ni_htonl(p_cfg->i32hwframes);
8213 p_cfg->ui16HDR10MaxLight = ni_htons(p_cfg->ui16HDR10MaxLight);
8214 p_cfg->ui16HDR10AveLight = ni_htons(p_cfg->ui16HDR10AveLight);
8215 p_cfg->ui16gdrDuration = ni_htons(p_cfg->ui16gdrDuration);
8216 p_cfg->ui32ltrRefInterval = ni_htonl(p_cfg->ui32ltrRefInterval);
8217 p_cfg->i32ltrRefQpOffset = (int32_t)ni_htonl(p_cfg->i32ltrRefQpOffset);
8218 p_cfg->ui32ltrFirstGap = ni_htonl(p_cfg->ui32ltrFirstGap);
8219 p_cfg->i32tolCtbRcInter = (int32_t)ni_htonl(p_cfg->i32tolCtbRcInter);
8220 p_cfg->i32tolCtbRcIntra = (int32_t)ni_htonl(p_cfg->i32tolCtbRcIntra);
8221 p_cfg->i16bitrateWindow = (int16_t)ni_htons(p_cfg->i16bitrateWindow);
8222 p_cfg->ui16hdr10_dx0 = ni_htons(p_cfg->ui16hdr10_dx0);
8223 p_cfg->ui16hdr10_dy0 = ni_htons(p_cfg->ui16hdr10_dy0);
8224 p_cfg->ui16hdr10_dx1 = ni_htons(p_cfg->ui16hdr10_dx1);
8225 p_cfg->ui16hdr10_dy1 = ni_htons(p_cfg->ui16hdr10_dy1);
8226 p_cfg->ui16hdr10_dx2 = ni_htons(p_cfg->ui16hdr10_dx2);
8227 p_cfg->ui16hdr10_dy2 = ni_htons(p_cfg->ui16hdr10_dy2);
8228 p_cfg->ui16hdr10_wx = ni_htons(p_cfg->ui16hdr10_wx);
8229 p_cfg->ui16hdr10_wy = ni_htons(p_cfg->ui16hdr10_wy);
8230 p_cfg->ui32hdr10_maxluma = ni_htonl(p_cfg->ui32hdr10_maxluma);
8231 p_cfg->ui32hdr10_minluma = ni_htonl(p_cfg->ui32hdr10_minluma);
8232 p_cfg->ui32lumaLinesize = ni_htons(p_cfg->ui32lumaLinesize);
8233 p_cfg->ui32chromaLinesize = ni_htons(p_cfg->ui32chromaLinesize);
8234
8235 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
8236 p_encoder_config, buffer_size, ui32LBA);
8238 p_ctx->device_type, p_ctx->hw_id,
8239 &(p_ctx->session_id), OPT_1);
8240 if (NI_RETCODE_SUCCESS != retval)
8241 {
8242 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);
8243 //Close the session since we can't configure it
8244 retval = ni_encoder_session_close(p_ctx, 0);
8245 if (NI_RETCODE_SUCCESS != retval)
8246 {
8247 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);
8248 }
8249
8251 }
8252
8253END:
8254
8255 ni_aligned_free(p_encoder_config);
8256 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
8257 return retval;
8258}
8259
8260/*!******************************************************************************
8261 * \brief Send a p_config command to configure encoding p_frame parameters.
8262 *
8263 * \param ni_session_context_t p_ctx - xcoder Context
8264 * \param ni_encoder_frame_params_t * params - pointer to the encoder ni_encoder_frame_params_t struct
8265 *
8266 * \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
8267 *******************************************************************************/
8269{
8271 uint32_t buffer_size = sizeof(ni_encoder_frame_params_t);
8273 uint32_t ui32LBA = 0;
8274
8275 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
8276
8277 if (!p_ctx || !p_params)
8278 {
8279 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
8280 __func__);
8282 }
8283
8284 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
8285 {
8286 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
8287 __func__);
8289 }
8290
8291 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
8292 if (ni_posix_memalign((void **)&p_cfg, sysconf(_SC_PAGESIZE), buffer_size))
8293 {
8294 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
8295 NI_ERRNO, __func__);
8297 }
8298
8299 //configure the session here
8301
8302 //Flip the bytes!!
8303 p_cfg->force_picture_type = ni_htons(p_params->force_picture_type);
8304 p_cfg->data_format = ni_htons(p_params->data_format);
8305 p_cfg->picture_type = ni_htons(p_params->picture_type);
8306 p_cfg->video_width = ni_htons(p_params->video_width);
8307 p_cfg->video_height = ni_htons(p_params->video_height);
8308 p_cfg->timestamp = ni_htonl(p_params->timestamp);
8309
8310 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_cfg,
8311 buffer_size, ui32LBA) < 0)
8312 {
8313 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);
8314 //Close the session since we can't configure it
8315 retval = ni_encoder_session_close(p_ctx, 0);
8316 if (NI_RETCODE_SUCCESS != retval)
8317 {
8318 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);
8319 }
8320
8322 }
8323
8324 ni_aligned_free(p_cfg);
8325 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
8326
8327 return retval;
8328}
8329
8330/*!******************************************************************************
8331 * \brief Get info from received p_frame
8332 *
8333 * \param
8334 *
8335 * \return
8336 *******************************************************************************/
8337int ni_create_frame(ni_frame_t* p_frame, uint32_t read_length, uint64_t*
8338 p_frame_offset, uint32_t* p_frame_dropped, bool is_hw_frame)
8339{
8340 uint32_t rx_size =
8341 read_length; //get the length since its the only thing in DW10 now
8342
8343 if (!p_frame || !p_frame_offset)
8344 {
8345 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
8346 __func__);
8348 }
8349
8350 *p_frame_offset = 0;
8351 if (p_frame_dropped)
8352 *p_frame_dropped = 0;
8353
8354 unsigned int metadata_size = NI_FW_META_DATA_SZ -
8356 unsigned int video_data_size = p_frame->data_len[0] + p_frame->data_len[1] +
8357 p_frame->data_len[2] + ((is_hw_frame) ? p_frame->data_len[3] : 0);
8358 ni_log(NI_LOG_DEBUG, "%s: rx_size = %d metadataSize = %d\n", __func__, rx_size,
8359 metadata_size);
8360
8361 p_frame->p_custom_sei_set = NULL;
8362
8363 if (rx_size == metadata_size)
8364 {
8365 video_data_size = 0;
8366 }
8367
8368 if (rx_size > video_data_size)
8369 {
8370 ni_metadata_dec_frame_t *p_meta =
8371 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
8372 video_data_size);
8373
8374 *p_frame_offset = p_meta->metadata_common.ui64_data.frame_offset;
8375 rx_size -= metadata_size;
8376 p_frame->crop_top = p_meta->metadata_common.crop_top;
8377 p_frame->crop_bottom = p_meta->metadata_common.crop_bottom;
8378 p_frame->crop_left = p_meta->metadata_common.crop_left;
8379 p_frame->crop_right = p_meta->metadata_common.crop_right;
8380 p_frame->ni_pict_type = p_meta->metadata_common.frame_type;
8381 p_frame->video_width = p_meta->metadata_common.frame_width;
8382 p_frame->video_height = p_meta->metadata_common.frame_height;
8383
8384 ni_log(
8386 "%s: [metadata] cropRight=%u, cropLeft=%u, "
8387 "cropBottom=%u, cropTop=%u, frame_offset=%" PRIu64 ", pic=%ux%u, "
8388 "pict_type=%d, crop=%ux%u, sei header: 0x%0x number %u size %u num_frame_dropped %u\n",
8389 __func__, p_frame->crop_right, p_frame->crop_left,
8390 p_frame->crop_bottom, p_frame->crop_top,
8393 p_meta->metadata_common.frame_height, p_frame->ni_pict_type,
8394 p_frame->crop_right - p_frame->crop_left,
8395 p_frame->crop_bottom - p_frame->crop_top, p_meta->sei_header,
8396 p_meta->sei_number, p_meta->sei_size, p_meta->metadata_common.num_frame_dropped);
8397
8398 p_frame->sei_total_len = 0;
8399 p_frame->sei_cc_offset = 0;
8400 p_frame->sei_cc_len = 0;
8405 p_frame->sei_hdr_plus_offset = 0;
8406 p_frame->sei_hdr_plus_len = 0;
8407 p_frame->sei_user_data_unreg_offset = 0;
8408 p_frame->sei_user_data_unreg_len = 0;
8409
8410 if (p_frame_dropped)
8411 {
8412 *p_frame_dropped = p_meta->metadata_common.num_frame_dropped;
8413 }
8414
8415 if (p_meta->sei_number)
8416 {
8417#if 1 // QUADRA_SEI_FMT
8418 ni_log(NI_LOG_DEBUG, "ui32SeiHeader 0x%x ui16SeiNumber %d ui16SeiSize %d SEI 0x%02x%02x\n",
8419 p_meta->sei_header, p_meta->sei_number, p_meta->sei_size,
8420 *((uint8_t*)p_meta + metadata_size),
8421 *((uint8_t*)p_meta + metadata_size+1));
8422
8423 { // retrieve sei from new format
8424 uint16_t ui16SeiProcessed = 0;
8425 ni_sei_header_t * pEntryHeader = &p_meta->first_sei_header;
8426 uint32_t ui32Offset = 0;
8427 uint32_t ui32Size;
8428
8429 rx_size -= p_meta->sei_size;
8430
8431 do
8432 {
8433 ui16SeiProcessed++;
8434
8435 if (pEntryHeader->status)
8436 {
8437 ui32Size = pEntryHeader->size;
8438 }
8439 else
8440 {
8441 ui32Size = 0;
8442 }
8443
8444 ni_log(NI_LOG_DEBUG, "SEI #%x st %d size %d ty %d sz/of %u/%u 0x%02x%02x\n",
8445 ui16SeiProcessed, pEntryHeader->status,
8446 pEntryHeader->size, pEntryHeader->type, ui32Size,
8447 ui32Offset,
8448 *((uint8_t *)p_meta + metadata_size + ui32Offset),
8449 *((uint8_t *)p_meta + metadata_size + ui32Offset + 1));
8450
8451 // - if multiple entries with same SEI type/subtype, only the last entry is saved;
8452 // consider to use sei_offset[] array instead of explicit sei_*_offset
8453 // - user_data_unreg (UDU) and custom sei passthru via HW and SW respectively
8454 // thus custom SEI is not processed here as it is by SW.
8455
8456 switch(pEntryHeader->type)
8457 {
8458 case 4: //HEVC_SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
8459 if (ui32Size)
8460 {
8461 uint8_t *ptr = (uint8_t*)p_meta + metadata_size + ui32Offset;
8462 if(ptr[0] == NI_HDR10P_SEI_BYTE0 && ptr[1] == NI_HDR10P_SEI_BYTE1 &&
8463 ptr[2] == NI_HDR10P_SEI_BYTE2 && ptr[3] == NI_HDR10P_SEI_BYTE3 &&
8464 ptr[4] == NI_HDR10P_SEI_BYTE4 && ptr[5] == NI_HDR10P_SEI_BYTE5)
8465 {
8466 p_frame->sei_hdr_plus_len = ui32Size;
8467 p_frame->sei_hdr_plus_offset =
8468 video_data_size + metadata_size + ui32Offset;
8469
8470 p_frame->sei_total_len += ui32Size;
8471
8472 ni_log(NI_LOG_DEBUG, "%s: hdr10+ size=%u hdr10+ offset=%u\n",
8473 __func__, p_frame->sei_hdr_plus_len,
8474 p_frame->sei_hdr_plus_offset);
8475 }
8476 else if(ptr[0] == NI_CC_SEI_BYTE0 && ptr[1] == NI_CC_SEI_BYTE1 &&
8477 ptr[2] == NI_CC_SEI_BYTE2 && ptr[3] == NI_CC_SEI_BYTE3 &&
8478 ptr[4] == NI_CC_SEI_BYTE4 && ptr[5] == NI_CC_SEI_BYTE5 &&
8479 ptr[6] == NI_CC_SEI_BYTE6 && ptr[7] == NI_CC_SEI_BYTE7)
8480 {
8481 // Found CC data
8482 // number of 3 byte close captions is bottom 5 bits of
8483 // 9th byte of T35 payload
8484 // uint32_t ui32CCSize = (ptr[8] & 0x1F) * 3; // avoid overwriting ui32CCSize
8485
8486 // return close caption data offset and length, and
8487 // skip past 10 header bytes to close caption data
8488 p_frame->sei_cc_len = (ptr[8] & 0x1F) * 3; // ui32CCSize;
8489 p_frame->sei_cc_offset = video_data_size + metadata_size
8490 + ui32Offset + 10;
8491
8492 p_frame->sei_total_len += p_frame->sei_cc_len;
8493
8495 "%s: close caption size %u ,"
8496 "offset %u = video size %u meta size %d off "
8497 " %u + 10\n",
8498 __func__, p_frame->sei_cc_len, p_frame->sei_cc_offset,
8499 video_data_size, metadata_size, ui32Offset);
8500 }
8501 else
8502 {
8504 "%s: unsupported T35; type %u size %u status %u "
8505 "offset %u\n",
8506 __func__, pEntryHeader->type, pEntryHeader->size,
8507 pEntryHeader->status, ui32Offset);
8508 }
8509 }
8510 else
8511 {
8513 "Error %s: T35 SEI dropped due to %s; type %u size %u status %u offset %u\n",
8514 __func__, pEntryHeader->status ? "missing payload" : "payload size exceeded SEI buffer size",
8515 pEntryHeader->type, pEntryHeader->size, pEntryHeader->status, ui32Offset);
8516 }
8517 break;
8518
8519 case 5: // HEVC_SEI_TYPE_USER_DATA_UNREGISTERED
8520 // set offset now so len=0 will signify an error if this SEI is dropped
8521 p_frame->sei_user_data_unreg_offset = video_data_size + metadata_size + ui32Offset;
8522 if (ui32Size)
8523 {
8524 p_frame->sei_user_data_unreg_len = ui32Size;
8525 p_frame->sei_total_len += ui32Size;
8526 ni_log(NI_LOG_DEBUG, "User Data Unreg size = %u\n", ui32Size);
8527 }
8528 else
8529 {
8530 p_frame->sei_user_data_unreg_len = 0; // in case there are multiple UDU SEI entries
8532 "Error %s: User Data Unreg dropped due to %s; type %u size %u status %u offset %u\n",
8533 __func__, pEntryHeader->status ? "missing payload" : "payload size exceeded SEI buffer size",
8534 pEntryHeader->type, pEntryHeader->size, pEntryHeader->status, ui32Offset);
8535 }
8536 break;
8537
8538 case 137: //HEVC_SEI_TYPE_MASTERING_DISPLAY_INFO
8539 if (ui32Size)
8540 {
8541 p_frame->sei_hdr_mastering_display_color_vol_len = ui32Size;
8543 video_data_size + metadata_size + ui32Offset;
8544
8545 p_frame->sei_total_len += ui32Size;
8548 *)((uint8_t *)p_meta + metadata_size + ui32Offset);
8549
8550 ni_log(NI_LOG_DEBUG, "Display Primaries x[0]=%u y[0]=%u\n",
8551 ni_ntohs(pColourVolume->display_primaries[0][0]),
8552 ni_ntohs(pColourVolume->display_primaries[0][1]));
8553 ni_log(NI_LOG_DEBUG, "Display Primaries x[1]=%u y[1]=%u\n",
8554 ni_ntohs(pColourVolume->display_primaries[1][0]),
8555 ni_ntohs(pColourVolume->display_primaries[1][1]));
8556 ni_log(NI_LOG_DEBUG, "Display Primaries x[2]=%u y[2]=%u\n",
8557 ni_ntohs(pColourVolume->display_primaries[2][0]),
8558 ni_ntohs(pColourVolume->display_primaries[2][1]));
8559
8560 ni_log(NI_LOG_DEBUG, "White Point x=%u y=%u\n",
8561 ni_ntohs(pColourVolume->white_point_x),
8562 ni_ntohs(pColourVolume->white_point_y));
8563 ni_log(NI_LOG_DEBUG, "Display Mastering Lum, Max=%u Min=%u\n",
8564 ni_ntohl(pColourVolume->max_display_mastering_luminance),
8565 ni_ntohl(pColourVolume->min_display_mastering_luminance));
8566 }
8567 else
8568 {
8570 "Error %s: mastering display info dropped due to %s; type %u size %u status %u offset %u\n",
8571 __func__, pEntryHeader->status ? "missing payload" : "payload size exceeded SEI buffer size",
8572 pEntryHeader->type, pEntryHeader->size, pEntryHeader->status, ui32Offset);
8573 }
8574 break;
8575
8576 case 144: //HEVC_SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO
8577 if (ui32Size)
8578 {
8579 p_frame->sei_hdr_content_light_level_info_len = ui32Size;
8581 video_data_size + metadata_size + ui32Offset;
8582
8583 p_frame->sei_total_len += ui32Offset;
8584
8587 (uint8_t*)p_meta + metadata_size + ui32Offset);
8588
8589 ni_log(NI_LOG_DEBUG, "Max Content Light level=%u Max Pic Avg Light Level=%u\n",
8590 ni_ntohs(pLightLevel->max_content_light_level),
8591 ni_ntohs(pLightLevel->max_pic_average_light_level));
8592 }
8593 else
8594 {
8596 "Error %s: content light level info dropped due to %s; type %u size %u status %u offset %u\n",
8597 __func__, pEntryHeader->status ? "missing payload" : "payload size exceeded SEI buffer size",
8598 pEntryHeader->type, pEntryHeader->size, pEntryHeader->status, ui32Offset);
8599 }
8600 break;
8601
8602 case 200: // Custom SEI not included in HEVC_SEI_Type
8603 if (ui32Size)
8604 {
8605 p_frame->vui_len = ui32Size;
8606 p_frame->vui_offset =
8607 video_data_size + metadata_size + ui32Offset;
8608 p_frame->sei_total_len += ui32Size;
8609 }
8610 break;
8611 case 206: // Customer reset ppu resolution, need dropped
8612 ni_log(NI_LOG_DEBUG, "Custom SEI PPU_RECONFIG dropped", __func__);
8613 break;
8614 default:
8616 "Warning %s: SEI message dropped (unsupported - check "
8617 "decoder SEI bitmap settings);"
8618 " type %u size %u status %u offset %u payload bytes %u\n",
8619 __func__, pEntryHeader->type, pEntryHeader->size,
8620 pEntryHeader->status, ui32Offset, ui32Size);
8621 break;
8622 }
8623 ui32Offset += ui32Size;
8624 pEntryHeader = (ni_sei_header_t *)((uint8_t*)p_meta + metadata_size + ui32Offset);
8625 ui32Offset += sizeof(ni_sei_header_t);
8626 } while (ui32Offset <= p_meta->sei_size && ui16SeiProcessed < p_meta->sei_number);
8627
8628 if (p_meta->sei_number != ui16SeiProcessed)
8629 {
8630 ni_log(
8632 "Error %s: number of SEI messages reported %u != processed %u\n",
8633 __func__, p_meta->sei_number, ui16SeiProcessed);
8634 }
8635 }
8636
8637#else // QUADRA_SEI_FMT
8638
8639 // ni_assert(p_meta->sei_header);
8640 // else // backward compatibility
8641 {
8642 ni_sei_user_data_entry_t *pEntry;
8643 uint32_t ui32CCOffset = 0, ui32CCSize = 0;
8644
8645 rx_size -= p_meta->sei_size;
8646
8647 pEntry = (ni_sei_user_data_entry_t *)((uint8_t*)p_meta + metadata_size);
8648
8649 if (find_t35_sei(p_meta->sei_header, NI_T35_SEI_HDR10_PLUS, pEntry,
8650 &ui32CCOffset, &ui32CCSize))
8651 {
8652 p_frame->sei_hdr_plus_len = ui32CCSize;
8653 p_frame->sei_hdr_plus_offset =
8654 video_data_size + metadata_size + ui32CCOffset;
8655
8656 p_frame->sei_total_len += ui32CCSize;
8657
8658 ni_log(NI_LOG_DEBUG, "%s: hdr10+ size=%u hdr10+ offset=%u\n", __func__,
8659 p_frame->sei_hdr_plus_len, p_frame->sei_hdr_plus_offset);
8660 }
8661 else
8662 {
8663 ni_log(NI_LOG_DEBUG, "%s: hdr+ NOT found in meta data!\n", __func__);
8664 }
8665
8666 if (find_t35_sei(p_meta->sei_header, NI_T35_SEI_CLOSED_CAPTION, pEntry,
8667 &ui32CCOffset, &ui32CCSize))
8668 {
8669 uint8_t *ptr;
8670 // Found CC data at pEntry + ui32CCOffset
8671 ptr = (uint8_t*)pEntry + ui32CCOffset;
8672 // number of 3 byte close captions is bottom 5 bits of
8673 // 9th byte of T35 payload
8674 ui32CCSize = (ptr[8] & 0x1F) * 3;
8675
8676 // return close caption data offset and length, and
8677 // skip past 10 header bytes to close caption data
8678 p_frame->sei_cc_len = ui32CCSize;
8679 p_frame->sei_cc_offset = video_data_size + metadata_size
8680 + ui32CCOffset + 10;
8681
8682 p_frame->sei_total_len += p_frame->sei_cc_len;
8683
8685 "%s: close caption size %u ,"
8686 "offset %u = video size %u meta size %u off "
8687 " %u + 10\n",
8688 __func__, p_frame->sei_cc_len, p_frame->sei_cc_offset,
8689 video_data_size, metadata_size, ui32CCOffset);
8690 }
8691 else
8692 {
8693 ni_log(NI_LOG_DEBUG, "%s: close caption NOT found in meta data!\n",
8694 __func__);
8695 }
8696
8697 if (find_sei(p_meta->sei_header, pEntry,
8699 &ui32CCOffset, &ui32CCSize))
8700 {
8701 p_frame->sei_hdr_mastering_display_color_vol_len = ui32CCSize;
8703 video_data_size + metadata_size + ui32CCOffset;
8704
8705 p_frame->sei_total_len += ui32CCSize;
8706
8707 ni_dec_mastering_display_colour_volume_t* pColourVolume =
8708 (ni_dec_mastering_display_colour_volume_t*)((uint8_t*)pEntry + ui32CCOffset);
8709
8710 ni_log(NI_LOG_DEBUG, "Display Primaries x[0]=%u y[0]=%u\n",
8711 pColourVolume->display_primaries_x[0],
8712 pColourVolume->display_primaries_y[0]);
8713 ni_log(NI_LOG_DEBUG, "Display Primaries x[1]=%u y[1]=%u\n",
8714 pColourVolume->display_primaries_x[1],
8715 pColourVolume->display_primaries_y[1]);
8716 ni_log(NI_LOG_DEBUG, "Display Primaries x[2]=%u y[2]=%u\n",
8717 pColourVolume->display_primaries_x[2],
8718 pColourVolume->display_primaries_y[2]);
8719
8720 ni_log(NI_LOG_DEBUG, "White Point x=%u y=%u\n",
8721 pColourVolume->white_point_x,
8722 pColourVolume->white_point_y);
8723 ni_log(NI_LOG_DEBUG, "Display Mastering Lum, Max=%u Min=%u\n",
8724 pColourVolume->max_display_mastering_luminance, pColourVolume->min_display_mastering_luminance);
8725 }
8726 if (find_sei(p_meta->sei_header, pEntry,
8728 &ui32CCOffset, &ui32CCSize))
8729 {
8730 p_frame->sei_hdr_content_light_level_info_len = ui32CCSize;
8732 video_data_size + metadata_size + ui32CCOffset;
8733
8734 p_frame->sei_total_len += ui32CCSize;
8735
8736 ni_content_light_level_info_t* pLightLevel =
8737 (ni_content_light_level_info_t*)((uint8_t*)pEntry + ui32CCOffset);
8738 ni_log(NI_LOG_DEBUG, "Max Content Light level=%u Max Pic Avg Light Level=%u\n",
8739 pLightLevel->max_content_light_level, pLightLevel->max_pic_average_light_level);
8740 }
8741
8742 if (find_sei(p_meta->sei_header, pEntry,
8744 &ui32CCOffset, &ui32CCSize) ||
8745 find_sei(p_meta->sei_header, pEntry,
8747 &ui32CCOffset, &ui32CCSize))
8748 {
8749 p_frame->sei_user_data_unreg_len = ui32CCSize;
8751 video_data_size + metadata_size + ui32CCOffset;
8752
8753 p_frame->sei_total_len += ui32CCSize;
8754
8755 ni_log(NI_LOG_DEBUG, "User Data Unreg size = %u\n", ui32CCSize);
8756 }
8757 }
8758#endif // QUADRA_SEI_FMT
8759 if (0 == p_frame->sei_total_len)
8760 {
8761 ni_log(NI_LOG_DEBUG, "Warning retrieved 0 supported SEI !\n");
8762 }
8763 }
8764 }
8765
8766 p_frame->dts = NI_NOPTS_VALUE;
8767 p_frame->pts = NI_NOPTS_VALUE;
8768 //p_frame->end_of_stream = isEndOfStream;
8769 p_frame->start_of_stream = 0;
8770
8771 if (rx_size == 0)
8772 {
8773 p_frame->data_len[0] = 0;
8774 p_frame->data_len[1] = 0;
8775 p_frame->data_len[2] = 0;
8776 p_frame->data_len[3] = 0;
8777 }
8778
8779 ni_log(NI_LOG_DEBUG, "received [0x%08x] data size: %d, end of stream=%u\n",
8780 read_length, rx_size, p_frame->end_of_stream);
8781
8782 return (int)rx_size;
8783}
8784
8785/*!******************************************************************************
8786 * \brief Get info from received xcoder capability
8787 *
8788 * \param
8789 *
8790 * \return
8791 *******************************************************************************/
8793 ni_device_handle_t device_handle, bool device_in_ctxt)
8794{
8795 int i, total_types = 0, total_modules = 0;
8796 ni_nvme_identity_t *p_id_data = (ni_nvme_identity_t *)p_data;
8797
8798 COMPILE_ASSERT(sizeof(p_cap->xcoder_cnt) <= sizeof(p_id_data->xcoder_cnt) &&
8800 sizeof(p_id_data->xcoder_cnt[0]) ==
8801 sizeof(p_cap->xcoder_cnt));
8802
8803 if (!p_cap || !p_data)
8804 {
8805 ni_log(NI_LOG_ERROR, "ERROR: %s(): Null pointer parameters passed\n",
8806 __func__);
8807 LRETURN;
8808 }
8809
8810 if ((p_id_data->ui16Vid != NETINT_PCI_VENDOR_ID) ||
8811 (p_id_data->ui16Ssvid != NETINT_PCI_VENDOR_ID))
8812 {
8813 if (device_in_ctxt)
8814 {
8816 "ERROR: Previously in context device got an invalid vendor ID 0x%X SSVID 0x%X. Netint "
8817 "ID 0x%X. Retrying\n",
8818 p_id_data->ui16Vid, p_id_data->ui16Ssvid, NETINT_PCI_VENDOR_ID);
8819 //print some other fields as a test to see if they are invalid too
8820 ni_log(NI_LOG_ERROR, "Model Number: %.*s\n",
8821 (int)sizeof(p_id_data->ai8Sn), p_id_data->ai8Sn);
8822 ni_log(NI_LOG_ERROR, "Serial Number: %.*s\n",
8823 (int)sizeof(p_id_data->ai8Mn), p_id_data->ai8Mn);
8824 ni_log(NI_LOG_ERROR, "Firmware Revision: %.*s\n",
8825 (int)sizeof(p_id_data->ai8Fr), p_id_data->ai8Fr);
8826 ni_log(NI_LOG_ERROR, "xcoder_num_elements: %d\n",
8827 p_id_data->xcoder_num_elements);
8828
8829 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
8830 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
8831 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_data,
8832 NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
8833 {
8834 LRETURN;
8835 }
8836 if ((p_id_data->ui16Vid != NETINT_PCI_VENDOR_ID) ||
8837 (p_id_data->ui16Ssvid != NETINT_PCI_VENDOR_ID))
8838 {
8840 "ERROR: %s(): Retry got an invalid vendor ID too 0x%X SSVID "
8841 "0x%X!\n",
8842 __func__, p_id_data->ui16Vid, p_id_data->ui16Ssvid);
8843 //print some other fields as a test to see if they are invalid too
8844 ni_log(NI_LOG_ERROR, "Model Number: %.*s\n",
8845 (int)sizeof(p_id_data->ai8Sn), p_id_data->ai8Sn);
8846 ni_log(NI_LOG_ERROR, "Serial Number: %.*s\n",
8847 (int)sizeof(p_id_data->ai8Mn), p_id_data->ai8Mn);
8848 ni_log(NI_LOG_ERROR, "Firmware Revision: %.*s\n",
8849 (int)sizeof(p_id_data->ai8Fr), p_id_data->ai8Fr);
8850 ni_log(NI_LOG_ERROR, "xcoder_num_elements: %d\n",
8851 p_id_data->xcoder_num_elements);
8852 LRETURN;
8853 }
8854 else
8855 {
8857 "Retry got valid a vendor ID 0x%X SSVID 0x%X. Netint ID 0x%X\n",
8858 p_id_data->ui16Vid, p_id_data->ui16Ssvid, NETINT_PCI_VENDOR_ID);
8859 }
8860 }
8861 else
8862 {
8863 LRETURN;
8864 }
8865 }
8866
8867 memcpy(p_cap->serial_number, p_id_data->ai8Sn, sizeof(p_cap->serial_number));
8868 memcpy(p_cap->model_number, p_id_data->ai8Mn, sizeof(p_cap->model_number));
8869
8870 memset(p_cap->fw_rev, 0, sizeof(p_cap->fw_rev));
8871 memcpy(p_cap->fw_rev, p_id_data->ai8Fr, sizeof(p_cap->fw_rev));
8872
8873 p_cap->warning_temp = p_id_data->ui16Wctemp;
8874 p_cap->critical_temp = p_id_data->ui16Cctemp;
8875
8876 ni_log(NI_LOG_DEBUG, "F/W rev: %.*s\n", (int)sizeof(p_cap->fw_rev),
8877 p_cap->fw_rev);
8878
8879 if (p_id_data->xcoder_num_elements)
8880 {
8881 ni_log(NI_LOG_DEBUG, "xcoder_num_elements: %d xcoder_num_devices: %d\n",
8882 p_id_data->xcoder_num_elements,
8883 p_id_data->xcoder_num_devices);
8884
8885 for (i = 0; i < NI_DEVICE_TYPE_XCODER_MAX; i++)
8886 {
8887 if (p_id_data->xcoder_cnt[i])
8888 {
8889 total_types++;
8890 total_modules += p_id_data->xcoder_cnt[i];
8891 ni_log(NI_LOG_DEBUG, "type #%d: xcoder_cnt[%d] = %d\n", total_types, i,
8892 p_id_data->xcoder_cnt[i]);
8893 }
8894 }
8895
8896 if (p_id_data->xcoder_num_elements != total_types ||
8897 p_id_data->xcoder_num_devices != total_modules)
8898 {
8900 "Error: mismatch; xcoder_num_elements: %d (calculated: %d) "
8901 "xcoder_num_devices: %d (calculated: %d)\n",
8902 p_id_data->xcoder_num_elements, total_types,
8903 p_id_data->xcoder_num_devices, total_modules);
8904 LRETURN;
8905 }
8906
8908 p_cap->hw_elements_cnt = p_id_data->xcoder_num_elements;
8909 p_cap->xcoder_devices_cnt = p_id_data->xcoder_num_devices;
8910 memcpy(p_cap->xcoder_cnt, p_id_data->xcoder_cnt,
8911 NI_DEVICE_TYPE_XCODER_MAX * sizeof(p_id_data->xcoder_cnt[0]));
8912
8914 {
8915 if (!p_id_data->xcoder_cnt[i])
8916 continue;
8917
8918 p_cap->xcoder_devices[i].hw_id = p_id_data->xcoder_devices[i].hw_id;
8922 p_cap->xcoder_devices[i].codec_format =
8923 p_id_data->xcoder_devices[i].hw_codec_format;
8924 p_cap->xcoder_devices[i].codec_type =
8925 p_id_data->xcoder_devices[i].hw_codec_type;
8928 if (i == NI_DEVICE_TYPE_ENCODER)
8929 {
8932 }
8933 else
8934 {
8937 }
8938
8939 p_cap->xcoder_devices[i].video_profile =
8940 p_id_data->xcoder_devices[i].hw_video_profile;
8941 p_cap->xcoder_devices[i].video_level =
8942 p_id_data->xcoder_devices[i].hw_video_level;
8943 }
8944
8945 goto CAP_POPULATED;
8946 }
8947
8948 p_cap->device_is_xcoder = p_id_data->device_is_xcoder;
8949 ni_log(NI_LOG_DEBUG, "device_is_xcoder: value in id cmd: %u\n",
8950 p_cap->device_is_xcoder);
8951 if (0 == p_cap->device_is_xcoder)
8952 {
8953 ni_log(NI_LOG_ERROR, "Not an xcoder device !\n");
8954
8955 if (device_in_ctxt)
8956 {
8958 "ERROR: Previously in context device is not a xcoder device "
8959 "now!\n");
8960 }
8961 LRETURN;
8962 }
8963
8964 p_cap->hw_elements_cnt = p_id_data->xcoder_num_hw;
8965
8966 total_modules = p_cap->xcoder_cnt[NI_DEVICE_TYPE_DECODER] =
8967 p_id_data->xcoder_num_h264_decoder_hw +
8968 p_id_data->xcoder_num_h265_decoder_hw;
8969
8971 p_id_data->xcoder_num_h264_encoder_hw +
8972 p_id_data->xcoder_num_h265_encoder_hw;
8973
8974 total_modules += p_cap->xcoder_cnt[NI_DEVICE_TYPE_ENCODER];
8975
8976 p_cap->xcoder_devices_cnt = total_modules;
8977
8978 if (total_modules >= 1)
8979 {
8980 p_cap->xcoder_devices[0].hw_id = p_id_data->hw0_id;
8984 p_cap->xcoder_devices[0].codec_format = p_id_data->hw0_codec_format;
8985 p_cap->xcoder_devices[0].codec_type = p_id_data->hw0_codec_type;
8990 p_cap->xcoder_devices[0].video_profile = p_id_data->hw0_video_profile;
8991 p_cap->xcoder_devices[0].video_level = p_id_data->hw0_video_level;
8992 }
8993 if (total_modules >= 2)
8994 {
8995 p_cap->xcoder_devices[1].hw_id = p_id_data->hw1_id;
8999 p_cap->xcoder_devices[1].codec_format = p_id_data->hw1_codec_format;
9000 p_cap->xcoder_devices[1].codec_type = p_id_data->hw1_codec_type;
9005 p_cap->xcoder_devices[1].video_profile = p_id_data->hw1_video_profile;
9006 p_cap->xcoder_devices[1].video_level = p_id_data->hw1_video_level;
9007 }
9008 if (total_modules >= 3)
9009 {
9010 p_cap->xcoder_devices[2].hw_id = p_id_data->hw2_id;
9014 p_cap->xcoder_devices[2].codec_format = p_id_data->hw2_codec_format;
9015 p_cap->xcoder_devices[2].codec_type = p_id_data->hw2_codec_type;
9020 p_cap->xcoder_devices[2].video_profile = p_id_data->hw2_video_profile;
9021 p_cap->xcoder_devices[2].video_level = p_id_data->hw2_video_level;
9022 }
9023 if (total_modules >= 4)
9024 {
9025 p_cap->xcoder_devices[3].hw_id = p_id_data->hw3_id;
9029 p_cap->xcoder_devices[3].codec_format = p_id_data->hw3_codec_format;
9030 p_cap->xcoder_devices[3].codec_type = p_id_data->hw3_codec_type;
9035 p_cap->xcoder_devices[3].video_profile = p_id_data->hw3_video_profile;
9036 p_cap->xcoder_devices[3].video_level = p_id_data->hw3_video_level;
9037 }
9038
9039CAP_POPULATED:
9040
9041 for (i = 0; i < NI_MAX_DEVICES_PER_HW_INSTANCE; i++)
9042 {
9043 ni_log(NI_LOG_DEBUG, "HW%d hw_id: %d\n", i, p_cap->xcoder_devices[i].hw_id);
9044 ni_log(NI_LOG_DEBUG, "HW%d max_number_of_contexts: %d\n", i,
9046 ni_log(NI_LOG_DEBUG, "HW%d max_4k_fps: %d\n", i,
9047 p_cap->xcoder_devices[i].max_4k_fps);
9048 ni_log(NI_LOG_DEBUG, "HW%d codec_format: %d\n", i,
9049 p_cap->xcoder_devices[i].codec_format);
9050 ni_log(NI_LOG_DEBUG, "HW%d codec_type: %d\n", i,
9051 p_cap->xcoder_devices[i].codec_type);
9052 ni_log(NI_LOG_DEBUG, "HW%d max_video_width: %d\n", i,
9054 ni_log(NI_LOG_DEBUG, "HW%d max_video_height: %d\n", i,
9056 ni_log(NI_LOG_DEBUG, "HW%d min_video_width: %d\n", i,
9058 ni_log(NI_LOG_DEBUG, "HW%d min_video_height: %d\n", i,
9060 ni_log(NI_LOG_DEBUG, "HW%d video_profile: %d\n", i,
9061 p_cap->xcoder_devices[i].video_profile);
9062 ni_log(NI_LOG_DEBUG, "HW%d video_level: %d\n", i,
9063 p_cap->xcoder_devices[i].video_level);
9064 }
9065
9066 memset(p_cap->fw_branch_name, 0, sizeof(p_cap->fw_branch_name));
9067 memcpy(p_cap->fw_branch_name, p_id_data->fw_branch_name,
9068 sizeof(p_cap->fw_branch_name) - 1);
9069 ni_log(NI_LOG_DEBUG, "F/W branch name: %s\n", p_cap->fw_branch_name);
9070 memset(p_cap->fw_commit_time, 0, sizeof(p_cap->fw_commit_time));
9071 memcpy(p_cap->fw_commit_time, p_id_data->fw_commit_time,
9072 sizeof(p_cap->fw_commit_time) - 1);
9073 ni_log(NI_LOG_DEBUG, "F/W commit time: %s\n", p_cap->fw_commit_time);
9074 memset(p_cap->fw_commit_hash, 0, sizeof(p_cap->fw_commit_hash));
9075 memcpy(p_cap->fw_commit_hash, p_id_data->fw_commit_hash,
9076 sizeof(p_cap->fw_commit_hash) - 1);
9077 ni_log(NI_LOG_DEBUG, "F/W commit hash: %s\n", p_cap->fw_commit_hash);
9078 memset(p_cap->fw_build_time, 0, sizeof(p_cap->fw_build_time));
9079 memcpy(p_cap->fw_build_time, p_id_data->fw_build_time,
9080 sizeof(p_cap->fw_build_time) - 1);
9081 ni_log(NI_LOG_DEBUG, "F/W build time: %s\n", p_cap->fw_build_time);
9082 memset(p_cap->fw_build_id, 0, sizeof(p_cap->fw_build_id));
9083 memcpy(p_cap->fw_build_id, p_id_data->fw_build_id,
9084 sizeof(p_cap->fw_build_id) - 1);
9085 ni_log(NI_LOG_DEBUG, "F/W build id: %s\n", p_cap->fw_build_id);
9086
9087END:
9088 return;
9089}
9090
9091static uint32_t presetGopSize[] = {
9092 1,
9093 1,
9094 1,
9095 1,
9096 2,
9097 4,
9098 4,
9099 4,
9100 8 };
9101
9102/*!******************************************************************************
9103 * \brief insert the 32 bits of integer value at bit position pos
9104 *
9105 * \param int pos, int value
9106 *
9107 * \return void
9108 ******************************************************************************/
9109void ni_fix_VUI(uint8_t *vui, int pos, int value)
9110{
9111 int pos_byte = (pos/8);
9112 int pos_in_byte = pos%8;
9113 int remaining_bytes_in_current_byte = 8 - pos_in_byte;
9114
9115 if (pos_in_byte == 0) // at beginning of the byte
9116 {
9117 vui[pos_byte] = (uint8_t)(value >> 24);
9118 vui[pos_byte+1] = (uint8_t)(value >> 16);
9119 vui[pos_byte+2] = (uint8_t)(value >> 8);
9120 vui[pos_byte+3] = (uint8_t)(value);
9121 }
9122 else
9123 {
9124 vui[pos_byte] = vui[pos_byte] + (uint8_t)(value >> (32-remaining_bytes_in_current_byte));
9125 vui[pos_byte+1] = (uint8_t)(value >> (32-remaining_bytes_in_current_byte-8));
9126 vui[pos_byte+2] = (uint8_t)(value >> (32-remaining_bytes_in_current_byte-16));
9127 vui[pos_byte+3] = (uint8_t)(value >> (32-remaining_bytes_in_current_byte-24));
9128 vui[pos_byte+4] = vui[pos_byte+4] + ((uint8_t)(value << remaining_bytes_in_current_byte));
9129 }
9130
9131}
9132
9133/*!******************************************************************************
9134* \brief Setup all xcoder configurations with custom parameters (Rev. B)
9135*
9136* \param
9137*
9138* \return
9139******************************************************************************/
9141 ni_decoder_config_t *p_cfg,
9142 ni_xcoder_params_t *p_src,
9143 uint32_t max_pkt_size)
9144{
9145 int i,j;
9146 ni_decoder_input_params_t* p_dec = NULL;
9147 if ((!p_ctx) || (!p_cfg) || (!p_src))
9148 {
9149 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
9150 __func__);
9151 return;
9152 }
9153 p_dec = &p_src->dec_input_params;
9154 int w = p_src->source_width;
9155 int h = p_src->source_height;
9156 bool shift_params = false;
9157
9158 p_cfg->ui8HWFrame = p_dec->hwframes;
9159 p_cfg->ui8MCMode = p_dec->mcmode;
9162 p_cfg->ui8DisablePictureReordering = (p_dec->decoder_low_delay > 0) ? 1 :
9163 (p_dec->decoder_disable_reorder ? 1 : 0);
9164 p_ctx->force_low_delay = p_dec->force_low_delay;
9166 p_cfg->ui32SourceWidth = w;
9167 p_cfg->ui32SourceHeight = h;
9168
9169 if (max_pkt_size)
9170 {
9171 p_cfg->ui32MaxPktSize = max_pkt_size;
9172 } else {
9173 // p_cfg->ui32MaxPktSize = width x height x 3/2 x min compression ratio(QP=0);
9174 // set min compression ratio = 1/2, so MaxPktSize = w * h * 3/4
9175 p_cfg->ui32MaxPktSize = w * h * 3 / 4;
9176 }
9177 // packet buffer aligned to NI_MAX_PACKET_SZ(128k)
9178 p_cfg->ui32MaxPktSize =
9180
9181 p_cfg->fps_number =
9182 ((ni_xcoder_params_t *)p_ctx->p_session_config)->fps_number;
9183 p_cfg->fps_denominator =
9184 ((ni_xcoder_params_t *)p_ctx->p_session_config)->fps_denominator;
9185 ni_log2(p_ctx, NI_LOG_INFO, "%s height %d width %d fps_number %d fps_denominator %d\n",
9186 __func__, h, w, p_cfg->fps_number, p_cfg->fps_denominator);
9187
9188 p_cfg->asOutputConfig[0].ui8Enabled = 1; // always enabled
9189 p_cfg->asOutputConfig[1].ui8Enabled = p_dec->enable_out1;
9190 p_cfg->asOutputConfig[2].ui8Enabled = p_dec->enable_out2;
9191 if (p_cfg->asOutputConfig[2].ui8Enabled && p_cfg->asOutputConfig[1].ui8Enabled == 0)
9192 {
9193 p_cfg->asOutputConfig[1].ui8Enabled = 1;
9194 p_cfg->asOutputConfig[2].ui8Enabled = 0;
9195 shift_params = true;
9196 ni_log2(p_ctx, NI_LOG_DEBUG, "Output 2 used before output 1, Shifting output2 settings to output1 and disabling output 2\n");
9197 }
9198
9199 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
9200 {
9201 if (!shift_params || i == 0)
9202 {
9203 j = i;
9204 }
9205 else
9206 {
9207 j = (i == 1) ? 2 : 1; //swap settings
9208 }
9209 p_cfg->asOutputConfig[i].ui8Force8Bit = p_dec->force_8_bit[j];
9210 p_cfg->asOutputConfig[i].ui8SemiPlanarEnabled = p_dec->semi_planar[j];
9211 p_cfg->asOutputConfig[i].ui8CropMode = p_dec->crop_mode[j];
9213 (uint16_t)((p_dec->crop_whxy[j][0]) & 0xFFFE);
9215 (uint16_t)((p_dec->crop_whxy[j][1]) & 0xFFFE);
9217 (uint16_t)((p_dec->crop_whxy[j][2]) & 0xFFFE);
9219 (uint16_t)((p_dec->crop_whxy[j][3]) & 0xFFFE);
9220
9221 //Offset resized if out of bounds
9223 {
9225 }
9227 {
9229 }
9230
9231 if (p_dec->enable_ppu_scale_adapt)
9232 {
9234 }
9235 else if (p_dec->scale_long_short_edge[j] == 1)
9236 {
9238 }
9239 else if (p_dec->scale_long_short_edge[j] == 2)
9240 {
9242 }
9243 else
9244 {
9246 }
9248
9249 if (p_dec->scale_round[j] == -1)
9250 {
9251 if (p_cfg->asOutputConfig[i].ui8EnablePpuScaleAdapt == 1 ||
9253 {
9254 p_cfg->asOutputConfig[i].ui8ScaleResCeil = p_dec->scale_resolution_ceil[j] - 1;
9255 }
9256 else
9257 {
9259 }
9260 }
9261 else if (p_dec->scale_round[j] == 0)
9262 {
9264 }
9265 else
9266 {
9267 p_cfg->asOutputConfig[i].ui8ScaleResCeil = p_dec->scale_resolution_ceil[j] - 1;
9268 }
9269
9270 if (p_cfg->ui8MaxExtraHwFrameCnt != 255 &&
9272 {
9273 p_cfg->asOutputConfig[i].sOutputPictureSize.i16Width = (int16_t)((p_dec->scale_wh[j][0] < 0) ?
9274 (p_dec->scale_wh[j][0] & -2) : ((p_dec->scale_wh[j][0]+1) & 0xFFFE));
9275 p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height = (int16_t)((p_dec->scale_wh[j][1] < 0) ?
9276 (p_dec->scale_wh[j][1] & -2) : ((p_dec->scale_wh[j][1]+1) & 0xFFFE));
9277 }
9278 else
9279 {
9280 p_cfg->asOutputConfig[i].sOutputPictureSize.i16Width = (int16_t)((p_dec->scale_wh[j][0] < 0) ?
9281 0 : ((p_dec->scale_wh[j][0]+1) & 0xFFFE));
9282 p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height = (int16_t)((p_dec->scale_wh[j][1] < 0) ?
9283 0 : ((p_dec->scale_wh[j][1]+1) & 0xFFFE));
9284 }
9285
9288 {
9289 p_cfg->asOutputConfig[i].ui8ScaleEnabled = 1;
9290 }
9291 else
9292 {
9293 p_cfg->asOutputConfig[i].ui8ScaleEnabled = 0;
9294 }
9295 }
9296
9298 if (p_cfg->ui8MaxExtraHwFrameCnt != 255 &&
9300 {
9301 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): maxExtraHwFrameCnt is not support for FW < 6rB\n", __func__);
9302 }
9303
9304 p_cfg->ui8ExtendPoolSize = p_dec->extend_pool_size;
9305 if (p_cfg->ui8ExtendPoolSize != 0 &&
9307 {
9308 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): extendPoolSize is not support for FW < 6t2\n", __func__);
9309 }
9310
9311 p_cfg->ui8DecoderMode = p_dec->decoder_mode;
9312 if (p_cfg->ui8DecoderMode != 0)
9313 {
9314 if (p_ctx->codec_format != NI_CODEC_FORMAT_H264 &&
9316 {
9317 ni_log2(p_ctx, NI_LOG_ERROR, "Warning %s(): decoderMode is only supported for H.264/H.265, resetting to default normal\n", __func__);
9318 p_cfg->ui8DecoderMode = 0;
9319 }
9320 else if (ni_cmp_fw_api_ver((char *)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6tC") < 0)
9321 {
9322 ni_log2(p_ctx, NI_LOG_ERROR, "Warning %s(): decoderMode is not supported for FW < 6tC, resetting to default normal\n", __func__);
9323 p_cfg->ui8DecoderMode = 0;
9324 }
9325 }
9326
9327 p_cfg->ui8EcPolicy = p_dec->ec_policy;
9330 if (p_cfg->ui8EnableAdvancedEc == 2 &&
9332 {
9333 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): (enableAdvancedEc == 2) is not support for FW < 6rO\n", __func__);
9334 p_cfg->ui8EnableAdvancedEc = 1;
9335 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): reset enableAdvancedEc to %d\n", __func__, p_cfg->ui8EnableAdvancedEc);
9336 }
9339 {
9340 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): (EcPolicy == limited_error) not supported for FW < 6ri\n", __func__);
9342 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): reset EcPolicy to %d\n", __func__, p_cfg->ui8EcPolicy);
9343 }
9346 {
9347 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): setting ecErrThreshold not supported for FW < 6ri\n", __func__);
9349 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): reset ecErrThreshold to %d\n", __func__, NI_EC_ERR_THRESHOLD_DEFAULT);
9350 }
9353 {
9354 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): (EcPolicy == best_effort_out_dc) not supported for FW < 6s1\n", __func__);
9356 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): reset EcPolicy to %d\n", __func__, p_cfg->ui8EcPolicy);
9357 }
9360 if (p_cfg->ui8SurviveStreamErr != 0 &&
9361 ni_cmp_fw_api_ver((char *)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rl") < 0) {
9362 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): surviveStreamErr is not supported for FW < 6rl\n", __func__);
9363 }
9364 if (p_dec->reduce_dpb_delay)
9365 {
9366 if (p_ctx->codec_format == NI_CODEC_FORMAT_H264 &&
9368 p_cfg->ui8ReduceDpbDelay = p_dec->reduce_dpb_delay;
9369 else
9370 {
9371 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s():Not support to reduce dpb delay and reset.\n", __func__);
9372 p_dec->reduce_dpb_delay = 0;
9373 }
9374 }
9375
9376 //print it all out
9377 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8HWFrame = %d\n", p_cfg->ui8HWFrame);
9378 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8MCMode = %d\n", p_cfg->ui8MCMode);
9379 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8UduSeiEnabled = %d\n", p_cfg->ui8UduSeiEnabled);
9380 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16MaxSeiDataSize = %d\n", p_cfg->ui16MaxSeiDataSize);
9381 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8DisablePictureReordering = %d\n", p_cfg->ui8DisablePictureReordering);
9382 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8Enabled0 = %d\n", p_cfg->asOutputConfig[0].ui8Enabled);
9383 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8Enabled1 = %d\n", p_cfg->asOutputConfig[1].ui8Enabled);
9384 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8Enabled2 = %d\n", p_cfg->asOutputConfig[2].ui8Enabled);
9385 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32MaxPktSize = %u\n", p_cfg->ui32MaxPktSize);
9386 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
9387 {
9388 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8Force8Bit %d\n", i, p_cfg->asOutputConfig[i].ui8Force8Bit);
9389 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8SemiPlanarEnabled %d\n", i, p_cfg->asOutputConfig[i].ui8SemiPlanarEnabled);
9390 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8CropMode %d\n", i, p_cfg->asOutputConfig[i].ui8CropMode);
9391 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] sCroppingRectable.ui16XYWH %d,%d - %d x %d\n", i,
9396 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] sOutputPictureSize.i16Width x height %d x %d\n", i,
9399 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8ScaleEnabled %d\n", i, p_cfg->asOutputConfig[i].ui8ScaleEnabled);
9400 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8EnablePpuScaleAdapt %u\n", i, p_cfg->asOutputConfig[i].ui8EnablePpuScaleAdapt);
9401 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8EnablePpuScaleLimit %u\n", i, p_cfg->asOutputConfig[i].ui8EnablePpuScaleLimit);
9402 ni_log2(p_ctx, NI_LOG_DEBUG, "[%d] ui8ScaleResCeil %u\n", i, p_cfg->asOutputConfig[i].ui8ScaleResCeil);
9403 }
9404 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8MaxExtraHwFrameCnt %u\n", p_cfg->ui8MaxExtraHwFrameCnt);
9405 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EcPolicy = %u\n", p_cfg->ui8EcPolicy);
9406 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnableAdvancedEc = %u\n", p_cfg->ui8EnableAdvancedEc);
9407 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnablelowDelayCheck = %u\n", p_cfg->ui8EnablelowDelayCheck);
9408 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8DisableAdaptiveBuffers = %u\n", p_cfg->ui8DisableAdaptiveBuffers);
9409 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32ErrRatioThreshold = %u\n", p_cfg->ui32ErrRatioThreshold);
9410 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8ReduceDpbDelay = %u\n", p_cfg->ui8ReduceDpbDelay);
9411 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8ExtendPoolSize = %u\n", p_cfg->ui8ExtendPoolSize);
9412 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8DecoderMode = %u\n", p_cfg->ui8DecoderMode);
9413}
9414
9415
9416/*!******************************************************************************
9417 * \brief Setup all xcoder configurations with custom parameters (Rev. B)
9418 *
9419 * \param
9420 *
9421 * \return
9422 ******************************************************************************/
9424 ni_encoder_config_t *p_cfg,
9425 ni_xcoder_params_t *p_src)
9426{
9427 ni_t408_config_t* p_t408 = NULL;
9428 ni_encoder_cfg_params_t *p_enc = NULL;
9429 int i = 0;
9430
9431 if ((!p_ctx) || (!p_cfg) || (!p_src))
9432 {
9433 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
9434 __func__);
9435 return;
9436 }
9437 p_t408 = &(p_cfg->niParamT408);
9438 p_enc = &p_src->cfg_enc_params;
9439
9440 ni_set_default_template(p_ctx, p_cfg);
9441
9442 p_cfg->i32picWidth = p_src->source_width;
9443 p_cfg->i32picHeight = p_src->source_height;
9444 p_t408->tier = p_enc->high_tier;
9446 p_t408->cu_size_mode = p_enc->cu_size_mode;
9447 p_t408->max_num_merge = p_enc->max_num_merge;
9448 p_cfg->ui8AiEnhanceMode = p_src->enable_ai_enhance;
9450 // enhance_level is in range [1,3] set level when paramters is valid, otherwise make it to 1.
9451 if(p_cfg->ui8AiEnhanceMode && p_src->ai_enhance_level > 0 && p_src->ai_enhance_level < 4){
9452 p_cfg->ui8AiEnhanceLevel = p_src->ai_enhance_level;
9453 }else{
9454 p_cfg->ui8AiEnhanceLevel = 1;
9455 }
9456 p_cfg->i8statisticOutputLevel = (int8_t)p_enc->statistic_output_level;
9457 p_cfg->i8skipFrameEnable = (int8_t)p_enc->skip_frame_enable;
9460 p_cfg->ui16iFrameSizeRatio = p_enc->iframe_size_ratio;
9461 p_cfg->ui8EnableAcqLimit = p_enc->enable_acq_limit;
9464 if (p_enc->crfFloat == (float)-1.0 && p_enc->enable_smooth_crf == 1)
9465 {
9466 //smooth crf only support when setting float crf
9467 p_enc->enable_smooth_crf = 0;
9468 }
9469 p_cfg->ui8enableSmoothCrf = p_enc->enable_smooth_crf;
9472 p_cfg->ui8adaptiveCrfMode = p_enc->adaptiveCrfMode;
9475 p_cfg->ui8cutreeFlushIframe = (p_src->minFramesDelay >> 2);
9476
9477 // enable_dynamic_8x8_merge, enable_dynamic_16x16_merge, enable_dynamic_32x32_merge,
9478 // trans_rate, enable_hvs_qp_scale:
9479 // are not present in Rev B p_config
9480
9481#if 0
9482 if ((p_enc->rc.enable_rate_control == 0) &&
9483 ((p_enc->rc.enable_mb_level_rc == 1) || (p_enc->rc.enable_cu_level_rate_control == 1)))
9484 {
9486 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");
9487 }
9488#endif
9489
9490 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__,
9491 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,
9492 p_enc->rc.vbv_buffer_size, p_enc->crf, p_enc->crfFloat);
9493
9494 if (!p_enc->preset_enabled && p_enc->preset_index != NI_PRESETS_NONE) {
9495 p_enc->preset_enabled = 1;
9496 p_enc->reset_dts_offset = 1;
9497 p_enc->rc.enable_rate_control = 1;
9499 p_enc->EnableRdoQuant = (STD_AV1 == p_cfg->ui8bitstreamFormat) ? 0 : (p_enc->EnableRdoQuant != -1 ? p_enc->EnableRdoQuant : 1);
9500
9501 // Disable CRF if enabled
9502 if (p_enc->crf != -1 || p_enc->crfFloat != -1.0f) {
9503 p_enc->crf = -1;
9504 p_enc->crfFloat = -1.0f;
9505 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): CRF disabled due to preset enabled\n", __func__);
9506 }
9507
9508 // Ensure preset_index is valid to avoid out-of-bounds access
9509 if (p_enc->preset_index >= 0 && p_enc->preset_index < sizeof(preset_configs) / sizeof(preset_configs[0])) {
9510 const PresetConfig *cfg = &preset_configs[p_enc->preset_index];
9511
9512 p_enc->rdoLevel = cfg->rdoLevel;
9513 p_enc->lookAheadDepth = cfg->lookAheadDepth;
9515 p_enc->rc.vbv_buffer_size = (p_enc->rc.vbv_buffer_size != -1) ? p_enc->rc.vbv_buffer_size : cfg->vbvBufferSize;
9517
9518 // Only set tolCtbRcInter/Intra for veryfast, faster, fast presets
9519 if (p_enc->preset_index <= NI_VQ_FAST) {
9520 p_enc->tolCtbRcInter = (p_enc->tolCtbRcInter != 0.1f) ? p_enc->tolCtbRcInter : cfg->tolCtbRcInter;
9521 p_enc->tolCtbRcIntra = (p_enc->tolCtbRcIntra != 0.1f) ? p_enc->tolCtbRcIntra : cfg->tolCtbRcIntra;
9522 }
9523 }
9524
9525 // Adjust rdoLevel for AVC format
9526 if (STD_AVC == p_cfg->ui8bitstreamFormat) {
9527 p_enc->rdoLevel = 1;
9528 }
9529 }
9530
9531 if (p_enc->EnableRdoQuant == -1)
9532 {
9533 p_enc->EnableRdoQuant = 0;
9534 }
9535
9537 {
9539 }
9540
9541 if(p_ctx->last_bitrate != 0)
9542 {
9543 // Slow sequence change happened. Retain the last bitrate.
9544 ni_log2(p_ctx, NI_LOG_DEBUG, "### %s: Slow sequence happened retain last_bitrate %d. assigned bitrate %d\n",
9545 __FUNCTION__, p_ctx->last_bitrate, p_src->bitrate);
9546 p_src->bitrate = p_ctx->last_bitrate;
9547 }
9548
9549 if (p_src->bitrate != 0)
9550 {
9551 p_cfg->i32bitRate = p_src->bitrate;
9552 }
9553
9554 p_cfg->ui8rcEnable = p_enc->rc.enable_rate_control;
9555
9556 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__,
9557 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,
9559
9560 // Update the bitrate to be used after Slow sequence change
9561 p_ctx->last_bitrate = p_cfg->i32bitRate;
9562
9563 p_t408->gop_preset_index = p_enc->gop_preset_index;
9565 p_t408->enable_hvs_qp = p_enc->rc.enable_hvs_qp;
9566 p_t408->hvs_qp_scale = p_enc->rc.hvs_qp_scale;
9567 p_t408->minQpI = p_enc->rc.min_qp;
9568 p_t408->minQpP = p_enc->rc.min_qp;
9569 p_t408->minQpB = p_enc->rc.min_qp;
9570 p_t408->maxQpI = p_enc->rc.max_qp;
9571 p_t408->maxQpP = p_enc->rc.max_qp;
9572 p_t408->maxQpB = p_enc->rc.max_qp;
9573
9574 p_t408->max_delta_qp = p_enc->rc.max_delta_qp;
9575 if (p_enc->rc.vbv_buffer_size != -1)
9576 {
9577 p_cfg->i32vbvBufferSize = p_enc->rc.vbv_buffer_size;
9578 }
9579 else
9580 {
9581 if (p_enc->rc.enable_rate_control)
9582 p_cfg->i32vbvBufferSize = 3000; // enable CBR (default vbv buffer size 3000) even if user does not set vbvBufferSize
9583 else
9584 p_cfg->i32vbvBufferSize = 0; // if user sets CRF but not vbvBufferSize, do not eanble capped CRF
9585 }
9586 p_cfg->ui32vbvMaxRate = p_enc->rc.vbv_max_rate;
9587 p_cfg->i8intraQpDelta = (int8_t)p_enc->rc.intra_qp_delta;
9588 p_cfg->ui8fillerEnable = p_enc->rc.enable_filler;
9589 p_cfg->ui8picSkipEnable = p_enc->rc.enable_pic_skip;
9590 p_cfg->ui16maxFrameSize = p_enc->maxFrameSize / 2000;
9591 p_t408->intra_period = p_enc->intra_period;
9592 p_t408->roiEnable = p_enc->roi_enable;
9593 p_t408->useLongTerm = p_enc->long_term_ref_enable;
9594 if (QUADRA)
9595 {
9598 }
9599 p_t408->conf_win_top = p_enc->conf_win_top;
9600 p_t408->conf_win_bottom = p_enc->conf_win_bottom;
9601 p_t408->conf_win_left = p_enc->conf_win_left;
9602 p_t408->conf_win_right = p_enc->conf_win_right;
9603 p_t408->avcIdrPeriod = p_enc->intra_period;
9604
9605 if (QUADRA)
9606 {
9607 if(p_ctx->last_framerate.framerate_num != 0)
9608 {
9609 // Slow sequence change happened. Retain the last framerate.
9610 ni_log2(p_ctx, NI_LOG_DEBUG, "### %s: Slow sequence happened retain last_framerate num %d den %d. assigned num %d den %d\n",
9611 __FUNCTION__, p_ctx->last_framerate.framerate_num, p_ctx->last_framerate.framerate_denom,
9613 p_src->fps_number = p_ctx->last_framerate.framerate_num;
9615
9616 if (!p_src->enable_vfr) {
9617 p_enc->frame_rate = (int)(p_src->fps_number / p_src->fps_denominator);
9618 }
9619 }
9620
9621 if (p_cfg->i32frameRateInfo != p_enc->frame_rate)
9622 {
9623 if (p_src->fps_denominator != 0 &&
9624 (p_src->fps_number % p_src->fps_denominator) != 0)
9625 {
9626 // Fractional FPS
9627 uint32_t numUnitsInTick = 1000;
9628 if (p_src->fps_denominator == numUnitsInTick + 1)
9629 {
9630 p_cfg->i32frameRateDenominator = (int32_t)(numUnitsInTick + 1);
9631 p_cfg->i32frameRateInfo = p_enc->frame_rate + 1;
9632 p_cfg->i32frameRateInfo *= (int32_t)numUnitsInTick;
9633 }
9634 else
9635 {
9636 p_cfg->i32frameRateDenominator = (int32_t)(numUnitsInTick + 1);
9637 p_cfg->i32frameRateInfo = (int32_t)(((uint64_t)p_src->fps_number * (uint64_t)numUnitsInTick) / (uint64_t)p_src->fps_denominator);
9638 }
9639 }
9640 else if (p_src->fps_denominator != 0 && p_src->fps_number < p_src->fps_denominator)
9641 {
9642 // Fractional FPS < 1, set to 1
9643 p_cfg->i32frameRateInfo = 1;
9644 p_cfg->i32frameRateDenominator = 1;
9645 }
9646 else
9647 {
9648 // Integer FPS: use the frame_rate directly
9649 p_cfg->i32frameRateInfo = p_enc->frame_rate;
9650 p_cfg->i32frameRateDenominator = 1;
9651 }
9652 }
9653
9654 // Update the framerate to be used after Slow sequence change
9657 }
9658 else
9659 {
9660 if (p_cfg->i32frameRateInfo != p_enc->frame_rate)
9661 {
9662 p_cfg->i32frameRateInfo = p_enc->frame_rate;
9663 p_t408->numUnitsInTick = 1000;
9664 if (p_src->fps_denominator != 0 &&
9665 (p_src->fps_number % p_src->fps_denominator) != 0)
9666 {
9667 p_t408->numUnitsInTick += 1;
9668 p_cfg->i32frameRateInfo += 1;
9669 }
9670 p_t408->timeScale = p_cfg->i32frameRateInfo * 1000;
9671 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
9672 {
9673 p_t408->timeScale *= 2;
9674 }
9675 }
9676 }
9677
9678 p_t408->intra_qp = p_enc->rc.intra_qp;
9679
9680 // "repeatHeaders" value 1 (all I frames) maps to forcedHeaderEnable
9681 // value 2; all other values are ignored
9682 if (p_t408->forcedHeaderEnable != p_enc->forced_header_enable &&
9684 {
9685 p_t408->forcedHeaderEnable = 2;
9686 p_cfg->ui8repeatHeaders = p_enc->forced_header_enable;
9687 }
9688
9690
9691 if (STD_AVC == p_cfg->ui8bitstreamFormat)
9692 {
9693 switch (p_t408->decoding_refresh_type)
9694 {
9695 case 0: // Non-IRAP I-p_frame
9696 {
9697 // intra_period set to user-configured (above), avcIdrPeriod set to 0
9698 p_t408->avcIdrPeriod = 0;
9699 break;
9700 }
9701 case 1: // CRA
9702 case 2: // IDR
9703 {
9704 // intra_period set to 0, avcIdrPeriod set to user-configured (above)
9705 p_t408->intra_period = 0;
9706 break;
9707 }
9708 default:
9709 {
9710 ni_log(
9712 "ERROR: %s() unknown value for p_t408->decoding_refresh_type: %d\n",
9713 __func__, p_t408->decoding_refresh_type);
9714 break;
9715 }
9716 }
9717 } else if (STD_HEVC == p_cfg->ui8bitstreamFormat ||
9718 STD_AV1 == p_cfg->ui8bitstreamFormat)
9719 {
9720 p_t408->avcIdrPeriod = 0;
9721 }
9722
9723 // Rev. B: H.264 only parameters.
9726
9727 // Rev. B: shared between HEVC and H.264
9728 p_t408->slice_mode = p_enc->slice_mode;
9729 p_t408->slice_arg = p_enc->slice_arg;
9730 if (p_t408->intra_mb_refresh_mode != p_enc->intra_mb_refresh_mode)
9731 {
9733 if (1 != p_t408->intra_mb_refresh_mode)
9734 {
9735 p_t408->intra_mb_refresh_mode = 1;
9736 ni_log2(p_ctx, NI_LOG_DEBUG, "force intraRefreshMode to 1 because quadra only supports intra refresh by rows\n");
9737 }
9738 }
9739
9740 if (p_t408->intra_mb_refresh_arg != p_enc->intra_mb_refresh_arg)
9741 {
9743 if (1 == p_t408->intra_mb_refresh_mode)
9744 {
9745 int mbHeight = (p_cfg->ui8bitstreamFormat == STD_AVC) ? 16 : 64;
9746 int mbRows = (p_cfg->i32picHeight + mbHeight - 1) / mbHeight;
9747 p_cfg->ui16gdrDuration = (mbRows + p_t408->intra_mb_refresh_arg - 1) / p_t408->intra_mb_refresh_arg;
9748 }
9749 }
9750
9752
9753 // Rev. B: could be shared for HEVC and H.264
9754 p_t408->enable_mb_level_rc = p_enc->rc.enable_mb_level_rc;
9755
9756 // profile setting: if user specified profile
9757 if (0 != p_enc->profile)
9758 {
9759 p_t408->profile = p_enc->profile;
9760 }
9761
9762 p_t408->level = p_enc->level_idc;
9763
9764 // main, extended or baseline profile of 8 bit (if input is 10 bit, Quadra auto converts to 8 bit) H.264 requires the following:
9765 // main: profile = 2 transform8x8Enable = 0
9766 // extended: profile = 3 entropyCodingMode = 0, transform8x8Enable = 0
9767 // baseline: profile = 1 entropyCodingMode = 0, transform8x8Enable = 0 and
9768 // gop with no B frames (gopPresetIdx=1, 2, 6, or 0
9769 // (custom with no B frames)
9770 if (STD_AVC == p_cfg->ui8bitstreamFormat)
9771 {
9772 if (2 == p_t408->profile)
9773 {
9774 p_t408->enable_transform_8x8 = 0;
9775 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_transform_8x8 set to 0 for profile 2 (main)\n");
9776 }
9777 else if (3 == p_t408->profile || 1 == p_t408->profile)
9778 {
9779 p_t408->entropy_coding_mode = p_t408->enable_transform_8x8 = 0;
9780 ni_log2(p_ctx, NI_LOG_DEBUG, "entropy_coding_mode and enable_transform_8x8 set to 0 "
9781 "for profile 3 (extended) or 1 (baseline)\n");
9782 }
9783 }
9784
9785 if (QUADRA)
9786 {
9787 p_enc->profile = p_t408->profile; // record profile for Bitstream Features reporting
9788 if (0 == p_t408->entropy_coding_mode && 1 == p_enc->EnableRdoQuant)
9789 {
9790 ni_log2(p_ctx, NI_LOG_DEBUG, "RDOQ does not support entropy_coding_mode 0 (CAVLC) "
9791 "force EnableRdoQuant 0 to accommodate HW limiation\n");
9792 p_enc->EnableRdoQuant = 0;
9793 }
9794 }
9795
9796#ifndef QUADRA
9797 if (!QUADRA)
9798 {
9800 {
9802 for (i = 0; i < p_t408->custom_gop_params.custom_gop_size; i++)
9803 {
9806 p_t408->custom_gop_params.pic_param[i].pic_qp = p_enc->custom_gop_params.pic_param[i].pic_qp + p_t408->intra_qp;
9807 p_t408->custom_gop_params.pic_param[i].num_ref_pic_L0 = p_enc->custom_gop_params.pic_param[i].num_ref_pic_L0;
9808 p_t408->custom_gop_params.pic_param[i].ref_poc_L0 = p_enc->custom_gop_params.pic_param[i].ref_poc_L0;
9809 p_t408->custom_gop_params.pic_param[i].ref_poc_L1 = p_enc->custom_gop_params.pic_param[i].ref_poc_L1;
9811 }
9812 }
9813 }
9814 else // QUADRA
9815#endif
9816 {
9820 {
9823 for (i = 0; i < p_t408->custom_gop_params.custom_gop_size; i++)
9824 {
9837 for (int j = 0;
9838 j < p_enc->custom_gop_params.pic_param[i].num_ref_pics; j++)
9839 {
9840 p_t408->custom_gop_params.pic_param[i].rps[j].ref_pic =
9844 }
9845 }
9846 }
9847 }
9848
9849 p_ctx->key_frame_type = p_t408->decoding_refresh_type; //Store to use when force key p_frame
9850
9851 // forceFrameType=1 requires intraPeriod=0 and avcIdrPeriod=0 and gopPresetIdx=8
9852 if (1 == p_src->force_frame_type)
9853 {
9854 p_t408->intra_period = 0;
9855 p_t408->avcIdrPeriod = 0;
9856 p_t408->gop_preset_index = 8;
9857 p_ctx->force_frame_type = 1;
9858 }
9859
9860 p_cfg->hdrEnableVUI = p_src->hdrEnableVUI;
9861
9862 if (p_cfg->i32hwframes != p_src->hwframes)
9863 {
9864 if (p_src->hwframes && p_ctx->auto_dl_handle == 0)
9865 {
9866 p_cfg->i32hwframes = p_src->hwframes;
9867 }
9868 else
9869 {
9870 p_cfg->i32hwframes = 0;
9871 }
9872 }
9873 p_cfg->ui16rootBufId = p_src->rootBufId;
9874
9875 //set VUI info deprecated
9876 //p_cfg->ui32VuiDataSizeBits = p_src->ui32VuiDataSizeBits;
9877 //p_cfg->ui32VuiDataSizeBytes = p_src->ui32VuiDataSizeBytes;
9878 //memcpy(p_cfg->ui8VuiRbsp, p_src->ui8VuiRbsp, NI_MAX_VUI_SIZE);
9879 //if ((p_src->pos_num_units_in_tick > p_src->ui32VuiDataSizeBits) || (p_src->pos_time_scale > p_src->ui32VuiDataSizeBits))
9880 //{
9881 // ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() VUI filling error\n", __func__);
9882 // return;
9883 //}
9884 //else
9885 //{
9886 // ni_fix_VUI(p_cfg->ui8VuiRbsp, p_src->pos_num_units_in_tick, p_t408->numUnitsInTick);
9887 // ni_fix_VUI(p_cfg->ui8VuiRbsp, p_src->pos_time_scale, p_t408->timeScale);
9888 //}
9889
9890 if (p_src->enable_vfr)
9891 {
9892 p_cfg->ui8fixedframerate = 0;
9893 } else
9894 {
9895 p_cfg->ui8fixedframerate = 1;
9896 }
9897
9898 //new QUADRA param
9899 if (p_enc->EnableAUD != 0)
9900 {
9901 p_cfg->ui8EnableAUD = p_enc->EnableAUD;
9902 }
9903 if (p_enc->lookAheadDepth != 0)
9904 {
9905 p_cfg->ui8LookAheadDepth = p_enc->lookAheadDepth;
9906 }
9907 if (p_enc->rdoLevel != 1)
9908 {
9909 p_cfg->ui8rdoLevel = p_enc->rdoLevel;
9910 }
9911 if (p_enc->crf != -1)
9912 {
9913 p_cfg->i8crf = (int8_t)p_enc->crf;
9914 }
9915 if (p_enc->HDR10MaxLight != 0)
9916 {
9917 p_cfg->ui16HDR10MaxLight = p_enc->HDR10MaxLight;
9918 }
9919 if (p_enc->HDR10AveLight != 0)
9920 {
9921 p_cfg->ui16HDR10AveLight = p_enc->HDR10AveLight;
9922 }
9923 if (p_enc->HDR10CLLEnable != 0)
9924 {
9925 p_cfg->ui8HDR10CLLEnable = p_enc->HDR10CLLEnable;
9926 }
9927 if (p_enc->HDR10Enable != 0)
9928 {
9929 p_cfg->ui8hdr10_enable = p_enc->HDR10Enable;
9930 p_cfg->ui16hdr10_dx0 = p_enc->HDR10dx0;
9931 p_cfg->ui16hdr10_dy0 = p_enc->HDR10dy0;
9932 p_cfg->ui16hdr10_dx1 = p_enc->HDR10dx1;
9933 p_cfg->ui16hdr10_dy1 = p_enc->HDR10dy1;
9934 p_cfg->ui16hdr10_dx2 = p_enc->HDR10dx2;
9935 p_cfg->ui16hdr10_dy2 = p_enc->HDR10dy2;
9936 p_cfg->ui16hdr10_wx = p_enc->HDR10wx;
9937 p_cfg->ui16hdr10_wy = p_enc->HDR10wy;
9938 p_cfg->ui32hdr10_maxluma = p_enc->HDR10maxluma;
9939 p_cfg->ui32hdr10_minluma = p_enc->HDR10minluma;
9940 }
9941
9942 if (p_enc->EnableRdoQuant != 0)
9943 {
9944 p_cfg->ui8EnableRdoQuant = p_enc->EnableRdoQuant;
9945 }
9946 if (p_enc->ctbRcMode != 0)
9947 {
9948 p_cfg->ui8ctbRcMode = p_enc->ctbRcMode;
9949 }
9950 if (p_enc->gopSize != 0)
9951 {
9952 p_cfg->ui8gopSize = p_enc->gopSize;
9953 }
9954 if (p_src->use_low_delay_poc_type != 0)
9955 {
9957 }
9958 if (p_enc->gopLowdelay != 0)
9959 {
9960 p_cfg->ui8gopLowdelay = p_enc->gopLowdelay;
9961 }
9962 if (p_enc->gdrDuration != 0)
9963 {
9964 p_cfg->ui16gdrDuration = p_enc->gdrDuration;
9965 }
9966 if (p_enc->colorDescPresent)
9967 {
9968 p_cfg->ui8colorDescPresent = 1;
9969 p_cfg->ui8colorPrimaries = p_enc->colorPrimaries;
9970 p_cfg->ui8colorTrc = p_enc->colorTrc;
9971 p_cfg->ui8colorSpace = p_enc->colorSpace;
9972 p_cfg->ui8videoFullRange = p_enc->videoFullRange;
9973 }
9974 if (p_enc->videoFullRange)
9975 {
9976 p_cfg->ui8videoFullRange = p_enc->videoFullRange;
9977 }
9978 if (p_enc->hrdEnable != 0)
9979 {
9980 p_cfg->ui8hrdEnable = p_enc->hrdEnable;
9981 }
9982
9983 p_cfg->ui8planarFormat = p_src->cfg_enc_params.planar;
9984 p_cfg->ui16aspectRatioWidth = p_enc->aspectRatioWidth;
9986
9987 if (p_enc->ltrRefInterval != 0)
9988 {
9989 p_cfg->ui32ltrRefInterval = p_enc->ltrRefInterval;
9990 p_cfg->i32ltrRefQpOffset = p_enc->ltrRefQpOffset;
9991 p_cfg->ui32ltrFirstGap = p_enc->ltrFirstGap;
9992 p_cfg->ui32ltrNextInterval = p_enc->ltrNextInterval;
9993 }
9994 if (p_enc->multicoreJointMode != 0)
9995 {
9997 }
9998 p_cfg->ui32QLevel = p_enc->qlevel;
9999
10000 if (p_enc->chromaQpOffset != 0)
10001 {
10002 p_cfg->i8chromaQpOffset = (int8_t)p_enc->chromaQpOffset;
10003 }
10004
10005 if (p_enc->tolCtbRcInter != (float)0.1)
10006 {
10007 p_cfg->i32tolCtbRcInter = (int32_t)(p_enc->tolCtbRcInter * 1000);
10008 }
10009
10010 if (p_enc->tolCtbRcIntra != (float)0.1)
10011 {
10012 p_cfg->i32tolCtbRcIntra = (int32_t)(p_enc->tolCtbRcIntra * 1000);
10013 }
10014
10015 if (p_enc->bitrateWindow != -255)
10016 {
10017 p_cfg->i16bitrateWindow = (int16_t)p_enc->bitrateWindow;
10018 }
10019
10020 if (p_enc->inLoopDSRatio != 1)
10021 {
10022 p_cfg->ui8inLoopDSRatio = p_enc->inLoopDSRatio;
10023 }
10024
10025 if (p_enc->blockRCSize != 0)
10026 {
10027 p_cfg->ui8blockRCSize = p_enc->blockRCSize;
10028 }
10029
10030 if (p_enc->rcQpDeltaRange != 10)
10031 {
10032 p_cfg->ui8rcQpDeltaRange = p_enc->rcQpDeltaRange;
10033 }
10034
10035 if (p_enc->ctbRowQpStep != 0)
10036 {
10037 p_cfg->i16ctbRowQpStep = (int16_t)p_enc->ctbRowQpStep;
10038 }
10039
10040 if (p_enc->newRcEnable != -1)
10041 {
10042 p_cfg->ui8NewRCEnable = p_enc->newRcEnable;
10043 }
10044
10045 // convert enable_mb_level_rc, enable_cu_level_rate_control, and enable_hvs_qp to ctbRcMode
10046 if (QUADRA)
10047 {
10048 // ctbRcMode has priority over enable_mb_level_rc, enable_cu_level_rate_control, and enable_hvs_qp
10049 if (!p_cfg->ui8ctbRcMode)
10050 {
10051 if (p_t408->enable_mb_level_rc || p_t408->enable_cu_level_rate_control)
10052 {
10053 if (p_t408->enable_hvs_qp)
10054 {
10055 p_cfg->ui8ctbRcMode = 3;
10056 // If hvsQP is enabled, disable strongIntraSmooth to apply one filtering at a time for better VQ.
10057 p_t408->strongIntraSmoothEnable = 0;
10059 "Turning off strongIntraSmoothing because hvsQPEnable=1 "
10060 "for better subjective VQ\n");
10061 } else
10062 {
10063 p_cfg->ui8ctbRcMode = 2;
10064 }
10065 }
10066 else if (p_t408->enable_hvs_qp)
10067 {
10068 p_cfg->ui8ctbRcMode = 1;
10069 // If hvsQP is enabled, disable strongIntraSmooth to apply one filtering at a time for better VQ.
10070 p_t408->strongIntraSmoothEnable = 0;
10072 "Turning off strongIntraSmoothing because hvsQPEnable=1 for "
10073 "better subjective VQ\n");
10074 }
10075 }
10076 }
10077
10078 if (p_src->low_delay_mode != 0)
10079 {
10080 p_cfg->ui8LowDelay = !!(p_src->low_delay_mode);
10081 }
10082
10083 if (p_enc->enable_ssim != 0)
10084 {
10085 p_cfg->ui8enableSSIM = p_enc->enable_ssim;
10086 }
10087
10088 if (p_enc->avcc_hvcc != 0)
10089 {
10090 p_cfg->ui8avccHvcc = p_enc->avcc_hvcc;
10091 }
10092
10093 if (p_enc->av1_error_resilient_mode != 0)
10094 {
10096 }
10097
10098 if (p_enc->temporal_layers_enable != 0)
10099 {
10101 }
10102
10103 if (p_enc->spatial_layers > 1)
10104 {
10105 p_cfg->ui8spatialLayersMinusOne = p_enc->spatial_layers - 1;
10106 if (ni_cmp_fw_api_ver((char *)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rw") < 0) {
10107 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): spatialLayers is not supported for FW < 6rw\n", __func__);
10108 }
10109 }
10110
10111 if (p_enc->spatial_layers_ref_base_layer != 0)
10112 {
10114 if (ni_cmp_fw_api_ver((char *)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6s0") < 0) {
10115 ni_log2(p_ctx, NI_LOG_INFO, "Warning %s(): spatialLayers is not supported for FW < 6s0\n", __func__);
10116 }
10117 }
10118
10119 if (p_ctx->pixel_format != NI_PIX_FMT_YUV420P)
10120 {
10121 p_cfg->ui8PixelFormat = p_ctx->pixel_format;
10122 }
10123
10124 if (p_enc->get_psnr_mode != 3)
10125 {
10126 if (p_enc->get_psnr_mode == 2 && p_ctx->codec_format == NI_CODEC_FORMAT_H265)
10127 {
10128 // h.265 psnr_y is supported by HW for 8-bit & 10-bit, no need to reject setting or disable luma RFC
10131 {
10132 p_enc->get_psnr_mode = 3;
10133 ni_log(NI_LOG_INFO, "Warning h.265 psnr_y is only supported for YUV420P, YUV420P10LE, NV12, and P010LE\n");
10134 }
10135 }
10136 else if (p_enc->get_psnr_mode == 4)
10137 {
10138 p_cfg->ui8compressor = 0;
10140 {
10141 p_enc->get_psnr_mode = 3;
10142 p_cfg->ui8compressor = 3;
10143 ni_log(NI_LOG_INFO, "Warning reconstructed frames only supported for YUV420P, NV12\n");
10144 }
10145 if (p_enc->crop_width || p_enc->crop_height)
10146 {
10147 p_cfg->ui8compressor = 3;
10148 p_enc->get_psnr_mode = 3;
10149 ni_log(NI_LOG_INFO, "Warning reconstructed frames feature is not supported when cropWidth x cropHeight are set\n");
10150 }
10151 }
10152 else
10153 {
10154 p_cfg->ui8compressor = p_enc->get_psnr_mode;
10155 if (p_cfg->ui8PixelFormat != NI_PIX_FMT_YUV420P)
10156 {
10157 p_cfg->ui8compressor = 3;
10158 p_enc->get_psnr_mode = 3;
10159 ni_log(NI_LOG_INFO, "Warning get psnr feature only support YUV420P (except for h.265 psnr_y)\n");
10160 }
10161 if (p_enc->crop_width || p_enc->crop_height)
10162 {
10163 p_cfg->ui8compressor = 3;
10164 p_enc->get_psnr_mode = 3;
10165 ni_log(NI_LOG_INFO, "Warning get psnr feature is not supported when cropWidth x cropHeight are set\n");
10166 }
10167 }
10168 }
10169
10170 if (p_src->zerocopy_mode == -1) // zero copy auto mode - disable zero copy for low resolution
10171 {
10172 bool is_rgba = (p_ctx->pixel_format == NI_PIX_FMT_RGBA ||
10173 p_ctx->pixel_format == NI_PIX_FMT_BGRA ||
10174 p_ctx->pixel_format == NI_PIX_FMT_ARGB ||
10175 p_ctx->pixel_format == NI_PIX_FMT_ABGR) ? true : false;
10176 if (is_rgba ||
10178 "6Q") >= 0) &&
10180 p_src->zerocopy_mode = 1;
10181 else
10182 p_src->zerocopy_mode = 0;
10183 }
10184
10185 if (p_src->zerocopy_mode)
10186 {
10187 p_cfg->ui32lumaLinesize = p_src->luma_linesize;
10188 p_cfg->ui32chromaLinesize = p_src->chroma_linesize;
10189 }
10190 else
10191 {
10192 p_cfg->ui32lumaLinesize = p_src->luma_linesize = 0;
10193 p_cfg->ui32chromaLinesize = p_src->chroma_linesize = 0;
10194 }
10195 // for fast sequence change linesize check
10196 p_ctx->ori_luma_linesize = p_src->luma_linesize;
10197 p_ctx->ori_chroma_linesize = p_src->chroma_linesize;
10198
10199 // calculate number for frames delay for minFramesDelay
10200 int lookAheadEnable = !!p_cfg->ui8LookAheadDepth;
10201
10202 int gopSize = g_map_preset_to_gopsize[lookAheadEnable][p_t408->gop_preset_index + 1];
10203 int mulitcoreDelay = p_cfg->ui8multicoreJointMode ? 3 : 0;
10204
10205 if (p_t408->gop_preset_index == 0) // Custom GOP
10206 gopSize = p_t408->custom_gop_params.custom_gop_size;
10207
10208 if (lookAheadEnable)
10209 {
10210 int firstGopEnd = gopSize + 1 + mulitcoreDelay; // first I-frame gopSize is 1
10211 int lookaheadGopEnd = mulitcoreDelay ?
10212 p_cfg->ui8LookAheadDepth + mulitcoreDelay + (gopSize - ((p_cfg->ui8LookAheadDepth-1+mulitcoreDelay) % gopSize)) :
10213 p_cfg->ui8LookAheadDepth + (gopSize - ((p_cfg->ui8LookAheadDepth-1) % gopSize)); // lookAheadDepth-1 because lookahead queue includes first I-frame
10214 int initialDelayNum = (firstGopEnd > lookaheadGopEnd) ? firstGopEnd : lookaheadGopEnd;
10215 int maxDelayNum = p_cfg->ui8LookAheadDepth + 1 + gopSize / 2 + mulitcoreDelay;
10216 int maxLookaheadQueue = initialDelayNum + (gopSize - 1) + mulitcoreDelay; // assume worst case scenario - gop size changes from initial gop to gop size 1
10217
10218 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
10219 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
10221 "6r2") >= 0)
10222 {
10223 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
10225 "6rX") >= 0)
10226 {
10227 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
10228 p_ctx->current_frame_delay = p_ctx->max_frame_delay;
10229 else
10231 }
10232 else
10233 {
10234 p_ctx->current_frame_delay = p_ctx->max_frame_delay;
10235 }
10236 }
10237 else
10238 {
10239 p_ctx->last_gop_size = gopSize;
10240 p_ctx->current_frame_delay = p_ctx->max_frame_delay;
10241 }
10242 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: firstGopEnd %d lookaheadGopEnd %d initialDelayNum %d maxDelayNum %d maxLookaheadQueue %d\n",
10243 __FUNCTION__, firstGopEnd, lookaheadGopEnd, initialDelayNum, maxDelayNum, maxLookaheadQueue);
10244 }
10245 else
10246 {
10247 p_ctx->last_gop_size = gopSize;
10248 p_ctx->initial_frame_delay = p_ctx->max_frame_delay = p_ctx->current_frame_delay = gopSize + mulitcoreDelay;
10249 }
10250
10251 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: preset %d lookAheadDepth %d gopSize %d mulitcoreDelay %d "
10252 "last_gop_size %d linitial_frame_delay %d current_frame_delay %d max_frame_delay %d\n",
10253 __FUNCTION__, p_t408->gop_preset_index, p_cfg->ui8LookAheadDepth, gopSize, mulitcoreDelay,
10255
10256 if (p_enc->crop_width != 0 && p_enc->crop_height != 0)
10257 {
10258 p_cfg->ui32cropWidth = p_enc->crop_width;
10259 p_cfg->ui32cropHeight = p_enc->crop_height;
10260 p_cfg->ui32horOffset = p_enc->hor_offset;
10261 p_cfg->ui32verOffset = p_enc->ver_offset;
10262 }
10263
10264 if (p_enc->crfMax != -1)
10265 {
10266 p_cfg->i8crfMax = (int8_t)(p_enc->crfMax + 1); // for old libxcoder backward compatibility, use 1 to represent 0
10267 }
10268
10269 if (p_enc->qcomp != (float)0.6)
10270 {
10271 p_cfg->i32qcomp = (int32_t)(p_enc->qcomp * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10272 }
10273
10274 if (p_enc->noMbtree != 0)
10275 {
10276 p_cfg->ui8noMbtree = p_enc->noMbtree;
10277 }
10278
10279 if (p_enc->noHWMultiPassSupport != 0)
10280 {
10282 }
10283
10284 if (p_enc->cuTreeFactor != 5)
10285 {
10286 p_cfg->i8cuTreeFactor = (int8_t)p_enc->cuTreeFactor;
10287 }
10288
10289 if (p_enc->ipRatio != (float)1.4)
10290 {
10291 p_cfg->i32ipRatio = (int32_t)(p_enc->ipRatio * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10292 }
10293
10294 if (p_enc->pbRatio != (float)1.3)
10295 {
10296 p_cfg->i32pbRatio = (int32_t)(p_enc->pbRatio * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10297 }
10298
10299 if (p_enc->cplxDecay != (float)0.5)
10300 {
10301 p_cfg->i32cplxDecay = (int32_t)(p_enc->cplxDecay * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10302 }
10303
10304 if (p_enc->pps_init_qp != -1)
10305 {
10306 p_cfg->i8ppsInitQp = (int8_t)(p_enc->pps_init_qp + 1); // for old libxcoder backward compatibility, use 1 to represent 0
10307 }
10308
10309 if (p_enc->bitrateMode != -1)
10310 {
10311 p_cfg->ui8bitrateMode = p_enc->bitrateMode;
10312 }
10313
10314 if (p_enc->pass1_qp != -1)
10315 {
10316 p_cfg->i8pass1Qp = (int8_t)((int8_t)(p_enc->pass1_qp) + 1); // for old libxcoder backward compatibility, use 1 to represent 0
10317 }
10318
10319 if (p_enc->crfFloat != (float)-1.0)
10320 {
10321 // for old libxcoder backward compatibility
10322 p_cfg->i8crf = (int8_t)(p_enc->crfFloat);
10323 p_cfg->i8crfDecimal = (int8_t)((p_enc->crfFloat - (float)p_cfg->i8crf) * 100);
10324 }
10325
10326 if (p_enc->hvsBaseMbComplexity != 15)
10327 {
10328 p_cfg->i8hvsBaseMbComplexity = (int8_t)((int8_t)p_enc->hvsBaseMbComplexity - 15); // for old libxcoder backward compatibility, use -15 to represent 0
10329 }
10330
10331 if (p_enc->enableipRatio != 0 && p_cfg->i32vbvBufferSize != 0) //vbvBufferSize !=0 for CBR not for ABR
10332 {
10333 p_cfg->i8enableipRatio = (int8_t)p_enc->enableipRatio;
10334 }
10335
10336 if (p_enc->crf_max_iframe_enable != 0)
10337 {
10339 }
10340
10341 if (p_enc->vbv_min_rate != 0)
10342 {
10343 p_cfg->ui32vbvMinRate = p_enc->vbv_min_rate;
10344 }
10345
10346 if (p_enc->disableBframeRdoq != 0)
10347 {
10349 }
10350
10351 if (p_enc->forceBframeQpfactor != (float)-1.0)
10352 {
10353 p_cfg->i32forceBframeQpFactor = (int32_t)(p_enc->forceBframeQpfactor * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
10354 }
10355
10356 if (p_enc->tune_bframe_visual != 0)
10357 {
10359 }
10360
10363 }
10364
10365 if (p_enc->motionConstrainedMode != 0)
10366 {
10368 }
10369
10370 if(p_enc->encMallocStrategy != 0)
10371 {
10372 p_cfg->ui8mallocStrategy = p_enc->encMallocStrategy;
10373 }
10374
10375 if (p_enc->enable_timecode != 0)
10376 {
10377 p_cfg->ui8enableTimecode = p_enc->enable_timecode;
10378 }
10379
10380 if (p_enc->vbvBufferReencode != 0)
10381 {
10383 }
10384
10385 if (p_enc->totalCuTreeDepth != 0)
10386 {
10387 p_cfg->ui8totalCuTreeDepth = p_enc->totalCuTreeDepth;
10388 }
10389
10390 if (p_enc->adaptiveCuTree != 0)
10391 {
10392 p_cfg->ui8adaptiveCuTree = p_enc->adaptiveCuTree;
10393 }
10394
10395 if (p_enc->preIntraHandling != 1)
10396 {
10397 p_cfg->ui8preIntraHandling = (uint8_t)p_enc->preIntraHandling - 1; // for old libxcoder backward compatibility, use -1 to represent 0
10398 }
10399
10400 if (p_enc->baseLayerOnly != 0)
10401 {
10402 p_cfg->ui8baseLayerOnly = p_enc->baseLayerOnly;
10403 }
10404
10405 if (p_enc->pastFrameMaxIntraRatio != 20)
10406 {
10407 p_cfg->ui8pastFrameMaxIntraRatio = (uint8_t)p_enc->pastFrameMaxIntraRatio - 20; // for old libxcoder backward compatibility, use -20 to represent 0
10408 }
10409
10410 if (p_enc->linkFrameMaxIntraRatio != 40)
10411 {
10412 p_cfg->ui8linkFrameMaxIntraRatio = (uint8_t)p_enc->linkFrameMaxIntraRatio - 40; // for old libxcoder backward compatibility, use -40 to represent 0
10413 }
10414
10415 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
10416 {
10417 if (p_enc->spatialLayerBitrate[i] != 0)
10418 {
10419 p_cfg->i32spatialLayerBitrate[i] = p_enc->spatialLayerBitrate[i];
10420 }
10421 if (p_enc->av1OpLevel[i] != 0)
10422 {
10423 p_cfg->ui8av1OpLevel[i] = p_enc->av1OpLevel[i];
10424 }
10425 }
10426
10427 if (p_enc->disableAv1TimingInfo != 0)
10428 {
10430 }
10431
10432 if (p_enc->qpScaleEnable != 0)
10433 {
10434 p_cfg->ui8qpScaleEnable = p_enc->qpScaleEnable;
10435 }
10436
10437 if (p_enc->getBitstreamFeatures != 0)
10438 {
10439 p_cfg->ui8getCuInfo = 1;
10440 }
10441
10442 ni_log2(p_ctx, NI_LOG_DEBUG, "lowDelay=%d\n", p_src->low_delay_mode);
10443 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8bitstreamFormat=%d\n", p_cfg->ui8bitstreamFormat);
10444 ni_log2(p_ctx, NI_LOG_DEBUG, "i32picWidth=%d\n", p_cfg->i32picWidth);
10445 ni_log2(p_ctx, NI_LOG_DEBUG, "i32picHeight=%d\n", p_cfg->i32picHeight);
10446 ni_log2(p_ctx, NI_LOG_DEBUG, "i32meBlkMode=%d\n", p_cfg->i32meBlkMode);
10447 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8sliceMode=%d\n", p_cfg->ui8sliceMode);
10448 ni_log2(p_ctx, NI_LOG_DEBUG, "i32frameRateInfo=%d\n", p_cfg->i32frameRateInfo);
10449 ni_log2(p_ctx, NI_LOG_DEBUG, "i32vbvBufferSize=%d\n", p_cfg->i32vbvBufferSize);
10450 ni_log2(p_ctx, NI_LOG_DEBUG, "i32userQpMax=%d\n", p_cfg->i32userQpMax);
10451 ni_log2(p_ctx, NI_LOG_DEBUG, "enableSSIM=%d\n", p_cfg->ui8enableSSIM);
10452 // AVC only
10453 ni_log2(p_ctx, NI_LOG_DEBUG, "i32maxIntraSize=%d\n", p_cfg->i32maxIntraSize);
10454 ni_log2(p_ctx, NI_LOG_DEBUG, "i32userMaxDeltaQp=%d\n", p_cfg->i32userMaxDeltaQp);
10455 ni_log2(p_ctx, NI_LOG_DEBUG, "i32userMinDeltaQp=%d\n", p_cfg->i32userMinDeltaQp);
10456 ni_log2(p_ctx, NI_LOG_DEBUG, "i32userQpMin=%d\n", p_cfg->i32userQpMin);
10457 ni_log2(p_ctx, NI_LOG_DEBUG, "i32bitRate=%d\n", p_cfg->i32bitRate);
10458 ni_log2(p_ctx, NI_LOG_DEBUG, "i32bitRateBL=%d\n", p_cfg->i32bitRateBL);
10459 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8rcEnable=%d\n", p_cfg->ui8rcEnable);
10460 ni_log2(p_ctx, NI_LOG_DEBUG, "i32srcBitDepth=%d\n", p_cfg->i32srcBitDepth);
10461 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8enablePTS=%d\n", p_cfg->ui8enablePTS);
10462 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8lowLatencyMode=%d\n", p_cfg->ui8lowLatencyMode);
10463 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32sourceEndian=%u\n", p_cfg->ui32sourceEndian);
10464 ni_log2(p_ctx, NI_LOG_DEBUG, "hdrEnableVUI=%u\n", p_cfg->hdrEnableVUI);
10465 ni_log2(p_ctx, NI_LOG_DEBUG, "i32hwframes=%i\n", p_cfg->i32hwframes);
10466
10467 ni_log2(p_ctx, NI_LOG_DEBUG, "** ni_t408_config_t: \n");
10468 ni_log2(p_ctx, NI_LOG_DEBUG, "profile=%d\n", p_t408->profile);
10469 ni_log2(p_ctx, NI_LOG_DEBUG, "level=%d\n", p_t408->level);
10470 ni_log2(p_ctx, NI_LOG_DEBUG, "tier=%d\n", p_t408->tier);
10471
10472 ni_log2(p_ctx, NI_LOG_DEBUG, "internalBitDepth=%d\n", p_t408->internalBitDepth);
10473 ni_log2(p_ctx, NI_LOG_DEBUG, "losslessEnable=%d\n", p_t408->losslessEnable);
10474 ni_log2(p_ctx, NI_LOG_DEBUG, "constIntraPredFlag=%d\n", p_t408->constIntraPredFlag);
10475
10476 ni_log2(p_ctx, NI_LOG_DEBUG, "decoding_refresh_type=%d\n", p_t408->decoding_refresh_type);
10477 ni_log2(p_ctx, NI_LOG_DEBUG, "intra_qp=%d\n", p_t408->intra_qp);
10478 ni_log2(p_ctx, NI_LOG_DEBUG, "intra_period=%d\n", p_t408->intra_period);
10479 ni_log2(p_ctx, NI_LOG_DEBUG, "roi_enable=%d\n", p_t408->roiEnable);
10480
10481 ni_log2(p_ctx, NI_LOG_DEBUG, "useLongTerm=%u\n", p_t408->useLongTerm);
10482 ni_log2(p_ctx, NI_LOG_DEBUG, "setLongTermInterval=%u\n", p_cfg->ui32setLongTermInterval);
10483 ni_log2(p_ctx, NI_LOG_DEBUG, "setLongTermCount=%u\n", p_cfg->ui8setLongTermCount);
10484
10485 ni_log2(p_ctx, NI_LOG_DEBUG, "conf_win_top=%d\n", p_t408->conf_win_top);
10486 ni_log2(p_ctx, NI_LOG_DEBUG, "conf_win_bottom=%d\n", p_t408->conf_win_bottom);
10487 ni_log2(p_ctx, NI_LOG_DEBUG, "conf_win_left=%d\n", p_t408->conf_win_left);
10488 ni_log2(p_ctx, NI_LOG_DEBUG, "conf_win_right=%d\n", p_t408->conf_win_right);
10489
10490 ni_log2(p_ctx, NI_LOG_DEBUG, "independSliceMode=%d\n", p_t408->independSliceMode);
10491 ni_log2(p_ctx, NI_LOG_DEBUG, "independSliceModeArg=%d\n", p_t408->independSliceModeArg);
10492
10493 ni_log2(p_ctx, NI_LOG_DEBUG, "dependSliceMode=%d\n", p_t408->dependSliceMode);
10494 ni_log2(p_ctx, NI_LOG_DEBUG, "dependSliceModeArg=%d\n", p_t408->dependSliceModeArg);
10495
10496 ni_log2(p_ctx, NI_LOG_DEBUG, "intraRefreshMode=%d\n", p_t408->intraRefreshMode);
10497
10498 ni_log2(p_ctx, NI_LOG_DEBUG, "intraRefreshArg=%d\n", p_t408->intraRefreshArg);
10499
10500 ni_log2(p_ctx, NI_LOG_DEBUG, "use_recommend_enc_params=%d\n", p_t408->use_recommend_enc_params);
10501 ni_log2(p_ctx, NI_LOG_DEBUG, "scalingListEnable=%d\n", p_t408->scalingListEnable);
10502
10503 ni_log2(p_ctx, NI_LOG_DEBUG, "cu_size_mode=%d\n", p_t408->cu_size_mode);
10504 ni_log2(p_ctx, NI_LOG_DEBUG, "tmvpEnable=%d\n", p_t408->tmvpEnable);
10505 ni_log2(p_ctx, NI_LOG_DEBUG, "wppEnable=%d\n", p_t408->wppEnable);
10506 ni_log2(p_ctx, NI_LOG_DEBUG, "max_num_merge=%d\n", p_t408->max_num_merge);
10507 ni_log2(p_ctx, NI_LOG_DEBUG, "disableDeblk=%d\n", p_t408->disableDeblk);
10508 ni_log2(p_ctx, NI_LOG_DEBUG, "lfCrossSliceBoundaryEnable=%d\n", p_t408->lfCrossSliceBoundaryEnable);
10509 ni_log2(p_ctx, NI_LOG_DEBUG, "betaOffsetDiv2=%d\n", p_t408->betaOffsetDiv2);
10510 ni_log2(p_ctx, NI_LOG_DEBUG, "tcOffsetDiv2=%d\n", p_t408->tcOffsetDiv2);
10511 ni_log2(p_ctx, NI_LOG_DEBUG, "skipIntraTrans=%d\n", p_t408->skipIntraTrans);
10512 ni_log2(p_ctx, NI_LOG_DEBUG, "saoEnable=%d\n", p_t408->saoEnable);
10513 ni_log2(p_ctx, NI_LOG_DEBUG, "intraNxNEnable=%d\n", p_t408->intraNxNEnable);
10514 ni_log2(p_ctx, NI_LOG_DEBUG, "bitAllocMode=%d\n", p_t408->bitAllocMode);
10515
10516 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_cu_level_rate_control=%d\n", p_t408->enable_cu_level_rate_control);
10517
10518 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_hvs_qp=%d\n", p_t408->enable_hvs_qp);
10519
10520 ni_log2(p_ctx, NI_LOG_DEBUG, "hvs_qp_scale=%d\n", p_t408->hvs_qp_scale);
10521
10522 ni_log2(p_ctx, NI_LOG_DEBUG, "max_delta_qp=%d\n", p_t408->max_delta_qp);
10523
10524 // CUSTOM_GOP
10525 ni_log2(p_ctx, NI_LOG_DEBUG, "gop_preset_index=%d\n", p_t408->gop_preset_index);
10526#ifndef QUADRA
10527 if (!QUADRA)
10528 {
10530 {
10531 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.custom_gop_size=%d\n", p_t408->custom_gop_params.custom_gop_size);
10532 for (i = 0; i < 8; i++)
10533 //for (i = 0; i < p_t408->custom_gop_params.custom_gop_size; i++)
10534 {
10535 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);
10536 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);
10537 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);
10538 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);
10539 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);
10540 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);
10541 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);
10542 }
10543 }
10544 }
10545 else // QUADRA
10546#endif
10547 {
10549 {
10550 int j;
10551 ni_log2(p_ctx, NI_LOG_DEBUG, "custom_gop_params.custom_gop_size=%d\n", p_t408->custom_gop_params.custom_gop_size);
10552 for (i = 0; i < NI_MAX_GOP_NUM; i++)
10553 {
10554 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);
10555 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);
10556 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);
10557 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);
10558 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);
10559 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);
10560 for (j = 0; j < NI_MAX_REF_PIC; j++)
10561 {
10562 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);
10563 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);
10564 }
10565 }
10566 }
10567 }
10568
10569 ni_log2(p_ctx, NI_LOG_DEBUG, "roiEnable=%d\n", p_t408->roiEnable);
10570
10571 ni_log2(p_ctx, NI_LOG_DEBUG, "numUnitsInTick=%u\n", p_t408->numUnitsInTick);
10572 ni_log2(p_ctx, NI_LOG_DEBUG, "timeScale=%u\n", p_t408->timeScale);
10573 ni_log2(p_ctx, NI_LOG_DEBUG, "numTicksPocDiffOne=%u\n", p_t408->numTicksPocDiffOne);
10574
10575 ni_log2(p_ctx, NI_LOG_DEBUG, "chromaCbQpOffset=%d\n", p_t408->chromaCbQpOffset);
10576 ni_log2(p_ctx, NI_LOG_DEBUG, "chromaCrQpOffset=%d\n", p_t408->chromaCrQpOffset);
10577
10578 ni_log2(p_ctx, NI_LOG_DEBUG, "initialRcQp=%d\n", p_t408->initialRcQp);
10579
10580 ni_log2(p_ctx, NI_LOG_DEBUG, "nrYEnable=%u\n", p_t408->nrYEnable);
10581 ni_log2(p_ctx, NI_LOG_DEBUG, "nrCbEnable=%u\n", p_t408->nrCbEnable);
10582 ni_log2(p_ctx, NI_LOG_DEBUG, "nrCrEnable=%u\n", p_t408->nrCrEnable);
10583
10584 // ENC_NR_WEIGHT
10585 ni_log2(p_ctx, NI_LOG_DEBUG, "nrIntraWeightY=%u\n", p_t408->nrIntraWeightY);
10586 ni_log2(p_ctx, NI_LOG_DEBUG, "nrIntraWeightCb=%u\n", p_t408->nrIntraWeightCb);
10587 ni_log2(p_ctx, NI_LOG_DEBUG, "nrIntraWeightCr=%u\n", p_t408->nrIntraWeightCr);
10588 ni_log2(p_ctx, NI_LOG_DEBUG, "nrInterWeightY=%u\n", p_t408->nrInterWeightY);
10589 ni_log2(p_ctx, NI_LOG_DEBUG, "nrInterWeightCb=%u\n", p_t408->nrInterWeightCb);
10590 ni_log2(p_ctx, NI_LOG_DEBUG, "nrInterWeightCr=%u\n", p_t408->nrInterWeightCr);
10591
10592 ni_log2(p_ctx, NI_LOG_DEBUG, "nrNoiseEstEnable=%u\n", p_t408->nrNoiseEstEnable);
10593 ni_log2(p_ctx, NI_LOG_DEBUG, "nrNoiseSigmaY=%u\n", p_t408->nrNoiseSigmaY);
10594 ni_log2(p_ctx, NI_LOG_DEBUG, "nrNoiseSigmaCb=%u\n", p_t408->nrNoiseSigmaCb);
10595 ni_log2(p_ctx, NI_LOG_DEBUG, "nrNoiseSigmaCr=%u\n", p_t408->nrNoiseSigmaCr);
10596
10597 // newly added for T408
10598 ni_log2(p_ctx, NI_LOG_DEBUG, "monochromeEnable=%u\n", p_t408->monochromeEnable);
10599 ni_log2(p_ctx, NI_LOG_DEBUG, "strongIntraSmoothEnable=%u\n",
10600 p_t408->strongIntraSmoothEnable);
10601
10602 ni_log2(p_ctx, NI_LOG_DEBUG, "weightPredEnable=%u\n", p_t408->weightPredEnable);
10603 ni_log2(p_ctx, NI_LOG_DEBUG, "bgDetectEnable=%u\n", p_t408->bgDetectEnable);
10604 ni_log2(p_ctx, NI_LOG_DEBUG, "bgThrDiff=%u\n", p_t408->bgThrDiff);
10605 ni_log2(p_ctx, NI_LOG_DEBUG, "bgThrMeanDiff=%u\n", p_t408->bgThrMeanDiff);
10606 ni_log2(p_ctx, NI_LOG_DEBUG, "bgLambdaQp=%u\n", p_t408->bgLambdaQp);
10607 ni_log2(p_ctx, NI_LOG_DEBUG, "bgDeltaQp=%d\n", p_t408->bgDeltaQp);
10608
10609 ni_log2(p_ctx, NI_LOG_DEBUG, "customLambdaEnable=%u\n", p_t408->customLambdaEnable);
10610 ni_log2(p_ctx, NI_LOG_DEBUG, "customMDEnable=%u\n", p_t408->customMDEnable);
10611 ni_log2(p_ctx, NI_LOG_DEBUG, "pu04DeltaRate=%d\n", p_t408->pu04DeltaRate);
10612 ni_log2(p_ctx, NI_LOG_DEBUG, "pu08DeltaRate=%d\n", p_t408->pu08DeltaRate);
10613 ni_log2(p_ctx, NI_LOG_DEBUG, "pu16DeltaRate=%d\n", p_t408->pu16DeltaRate);
10614 ni_log2(p_ctx, NI_LOG_DEBUG, "pu32DeltaRate=%d\n", p_t408->pu32DeltaRate);
10615 ni_log2(p_ctx, NI_LOG_DEBUG, "pu04IntraPlanarDeltaRate=%d\n", p_t408->pu04IntraPlanarDeltaRate);
10616 ni_log2(p_ctx, NI_LOG_DEBUG, "pu04IntraDcDeltaRate=%d\n", p_t408->pu04IntraDcDeltaRate);
10617 ni_log2(p_ctx, NI_LOG_DEBUG, "pu04IntraAngleDeltaRate=%d\n", p_t408->pu04IntraAngleDeltaRate);
10618 ni_log2(p_ctx, NI_LOG_DEBUG, "pu08IntraPlanarDeltaRate=%d\n", p_t408->pu08IntraPlanarDeltaRate);
10619 ni_log2(p_ctx, NI_LOG_DEBUG, "pu08IntraDcDeltaRate=%d\n", p_t408->pu08IntraDcDeltaRate);
10620 ni_log2(p_ctx, NI_LOG_DEBUG, "pu08IntraAngleDeltaRate=%d\n", p_t408->pu08IntraAngleDeltaRate);
10621 ni_log2(p_ctx, NI_LOG_DEBUG, "pu16IntraPlanarDeltaRate=%d\n", p_t408->pu16IntraPlanarDeltaRate);
10622 ni_log2(p_ctx, NI_LOG_DEBUG, "pu16IntraDcDeltaRate=%d\n", p_t408->pu16IntraDcDeltaRate);
10623 ni_log2(p_ctx, NI_LOG_DEBUG, "pu16IntraAngleDeltaRate=%d\n", p_t408->pu16IntraAngleDeltaRate);
10624 ni_log2(p_ctx, NI_LOG_DEBUG, "pu32IntraPlanarDeltaRate=%d\n", p_t408->pu32IntraPlanarDeltaRate);
10625 ni_log2(p_ctx, NI_LOG_DEBUG, "pu32IntraDcDeltaRate=%d\n", p_t408->pu32IntraDcDeltaRate);
10626 ni_log2(p_ctx, NI_LOG_DEBUG, "pu32IntraAngleDeltaRate=%d\n", p_t408->pu32IntraAngleDeltaRate);
10627 ni_log2(p_ctx, NI_LOG_DEBUG, "cu08IntraDeltaRate=%d\n", p_t408->cu08IntraDeltaRate);
10628 ni_log2(p_ctx, NI_LOG_DEBUG, "cu08InterDeltaRate=%d\n", p_t408->cu08InterDeltaRate);
10629 ni_log2(p_ctx, NI_LOG_DEBUG, "cu08MergeDeltaRate=%d\n", p_t408->cu08MergeDeltaRate);
10630 ni_log2(p_ctx, NI_LOG_DEBUG, "cu16IntraDeltaRate=%d\n", p_t408->cu16IntraDeltaRate);
10631 ni_log2(p_ctx, NI_LOG_DEBUG, "cu16InterDeltaRate=%d\n", p_t408->cu16InterDeltaRate);
10632 ni_log2(p_ctx, NI_LOG_DEBUG, "cu16MergeDeltaRate=%d\n", p_t408->cu16MergeDeltaRate);
10633 ni_log2(p_ctx, NI_LOG_DEBUG, "cu32IntraDeltaRate=%d\n", p_t408->cu32IntraDeltaRate);
10634 ni_log2(p_ctx, NI_LOG_DEBUG, "cu32InterDeltaRate=%d\n", p_t408->cu32InterDeltaRate);
10635 ni_log2(p_ctx, NI_LOG_DEBUG, "cu32MergeDeltaRate=%d\n", p_t408->cu32MergeDeltaRate);
10636 ni_log2(p_ctx, NI_LOG_DEBUG, "coefClearDisable=%d\n", p_t408->coefClearDisable);
10637 ni_log2(p_ctx, NI_LOG_DEBUG, "minQpI=%d\n", p_t408->minQpI);
10638 ni_log2(p_ctx, NI_LOG_DEBUG, "maxQpI=%d\n", p_t408->maxQpI);
10639 ni_log2(p_ctx, NI_LOG_DEBUG, "minQpP=%d\n", p_t408->minQpP);
10640 ni_log2(p_ctx, NI_LOG_DEBUG, "maxQpP=%d\n", p_t408->maxQpP);
10641 ni_log2(p_ctx, NI_LOG_DEBUG, "minQpB=%d\n", p_t408->minQpB);
10642 ni_log2(p_ctx, NI_LOG_DEBUG, "maxQpB=%d\n", p_t408->maxQpB);
10643
10644 // for H.264 on T408
10645 ni_log2(p_ctx, NI_LOG_DEBUG, "avcIdrPeriod=%d\n", p_t408->avcIdrPeriod);
10646 ni_log2(p_ctx, NI_LOG_DEBUG, "rdoSkip=%d\n", p_t408->rdoSkip);
10647 ni_log2(p_ctx, NI_LOG_DEBUG, "lambdaScalingEnable=%d\n", p_t408->lambdaScalingEnable);
10648 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_transform_8x8=%d\n", p_t408->enable_transform_8x8);
10649 ni_log2(p_ctx, NI_LOG_DEBUG, "slice_mode=%d\n", p_t408->slice_mode);
10650 ni_log2(p_ctx, NI_LOG_DEBUG, "slice_arg=%d\n", p_t408->slice_arg);
10651 ni_log2(p_ctx, NI_LOG_DEBUG, "intra_mb_refresh_mode=%d\n", p_t408->intra_mb_refresh_mode);
10652 ni_log2(p_ctx, NI_LOG_DEBUG, "intra_mb_refresh_arg=%d\n", p_t408->intra_mb_refresh_arg);
10653 ni_log2(p_ctx, NI_LOG_DEBUG, "enable_mb_level_rc=%d\n", p_t408->enable_mb_level_rc);
10654 ni_log2(p_ctx, NI_LOG_DEBUG, "entropy_coding_mode=%d\n", p_t408->entropy_coding_mode);
10655 ni_log2(p_ctx, NI_LOG_DEBUG, "forcedHeaderEnable=%u\n", p_t408->forcedHeaderEnable);
10656
10657 //QUADRA
10658 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnableAUD=%d\n", p_cfg->ui8EnableAUD);
10659 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8LookAheadDepth=%d\n", p_cfg->ui8LookAheadDepth);
10660 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8rdoLevel=%d\n", p_cfg->ui8rdoLevel);
10661 ni_log2(p_ctx, NI_LOG_DEBUG, "i8crf=%d\n", p_cfg->i8crf);
10662 ni_log2(p_ctx, NI_LOG_DEBUG, "i8crfDecimal=%d\n", p_cfg->i8crfDecimal);
10663 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16HDR10MaxLight=%d\n", p_cfg->ui16HDR10MaxLight);
10664 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16HDR10AveLight=%d\n", p_cfg->ui16HDR10AveLight);
10665 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8HDR10CLLEnable=%d\n", p_cfg->ui8HDR10CLLEnable);
10666 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnableRdoQuant=%d\n", p_cfg->ui8EnableRdoQuant);
10667 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8ctbRcMode=%d\n", p_cfg->ui8ctbRcMode);
10668 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8gopSize=%d\n", p_cfg->ui8gopSize);
10669 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8useLowDelayPocType=%d\n", p_cfg->ui8useLowDelayPocType);
10670 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8gopLowdelay=%d\n", p_cfg->ui8gopLowdelay);
10671 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16gdrDuration=%d\n", p_cfg->ui16gdrDuration);
10672 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8hrdEnable=%d\n", p_cfg->ui8hrdEnable);
10673 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8colorDescPresent=%d\n", p_cfg->ui8colorDescPresent);
10674 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8colorPrimaries=%d\n", p_cfg->ui8colorPrimaries);
10675 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8colorTrc=%d\n", p_cfg->ui8colorTrc);
10676 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8colorSpace=%d\n", p_cfg->ui8colorSpace);
10677 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16aspectRatioWidth=%d\n", p_cfg->ui16aspectRatioWidth);
10678 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16aspectRatioHeight=%d\n", p_cfg->ui16aspectRatioHeight);
10679 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16rootBufId=%d\n", p_cfg->ui16rootBufId);
10680 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8planarFormat=%d\n", p_cfg->ui8planarFormat);
10681 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8PixelFormat=%d\n", p_cfg->ui8PixelFormat);
10682 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32ltrRefInterval=%u\n", p_cfg->ui32ltrRefInterval);
10683 ni_log2(p_ctx, NI_LOG_DEBUG, "i32ltrRefQpOffset=%d\n", p_cfg->i32ltrRefQpOffset);
10684 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32ltrFirstGap=%u\n", p_cfg->ui32ltrFirstGap);
10685 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32ltrNextInterval=%u\n", p_cfg->ui32ltrNextInterval);
10686 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8multicoreJointMode=%d\n", p_cfg->ui8multicoreJointMode);
10687 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8videoFullRange=%u\n", p_cfg->ui8videoFullRange);
10688 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32QLevel=%u\n", p_cfg->ui32QLevel);
10689 ni_log2(p_ctx, NI_LOG_DEBUG, "i8chromaQpOffset=%d\n", p_cfg->i8chromaQpOffset);
10690 ni_log2(p_ctx, NI_LOG_DEBUG, "i32tolCtbRcInter=0x%x\n", p_cfg->i32tolCtbRcInter);
10691 ni_log2(p_ctx, NI_LOG_DEBUG, "i32tolCtbRcIntra=0x%x\n", p_cfg->i32tolCtbRcIntra);
10692 ni_log2(p_ctx, NI_LOG_DEBUG, "i16bitrateWindow=%d\n", p_cfg->i16bitrateWindow);
10693 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8inLoopDSRatio=%u\n", p_cfg->ui8inLoopDSRatio);
10694 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8blockRCSize=%u\n", p_cfg->ui8blockRCSize);
10695 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8rcQpDeltaRange=%u\n", p_cfg->ui8rcQpDeltaRange);
10696 ni_log2(p_ctx, NI_LOG_DEBUG, "i16ctbRowQpStep=%u\n", p_cfg->i16ctbRowQpStep);
10697 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8NewRCEnable=%u\n", p_cfg->ui8NewRCEnable);
10698 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8LowDelay=%d\n", p_cfg->ui8LowDelay);
10699 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8hdr10_enable=%u\n", p_cfg->ui8hdr10_enable);
10700 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dx0=%u\n", p_cfg->ui16hdr10_dx0);
10701 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dy0=%u\n", p_cfg->ui16hdr10_dy0);
10702 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dx1=%u\n", p_cfg->ui16hdr10_dx1);
10703 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dy1=%u\n", p_cfg->ui16hdr10_dy1);
10704 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dx2=%u\n", p_cfg->ui16hdr10_dx2);
10705 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_dy2=%u\n", p_cfg->ui16hdr10_dy2);
10706 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_wx=%u\n", p_cfg->ui16hdr10_wx);
10707 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16hdr10_wy=%u\n", p_cfg->ui16hdr10_wy);
10708 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32hdr10_maxluma=%u\n", p_cfg->ui32hdr10_maxluma);
10709 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32hdr10_minluma=%u\n", p_cfg->ui32hdr10_minluma);
10710 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8avccHvcc=%u\n", p_cfg->ui8avccHvcc);
10711 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8av1ErrResilientMode=%u\n", p_cfg->ui8av1ErrResilientMode);
10712 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8intraResetRefresh=%d\n", p_cfg->ui8intraResetRefresh);
10713 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8temporalLayersEnable=%u\n", p_cfg->ui8temporalLayersEnable);
10714 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8enable2PassGopPattern=%u\n", p_cfg->ui8enable2PassGopPatern);
10715 ni_log2(p_ctx, NI_LOG_DEBUG, "zerocopy_mode=%d\n", p_src->zerocopy_mode);
10716 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32lumaLinesize=%u\n", p_cfg->ui32lumaLinesize);
10717 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32chromaLinesize=%u\n", p_cfg->ui32chromaLinesize);
10718 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32cropWidth=%u\n", p_cfg->ui32cropWidth);
10719 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32cropHeight=%u\n", p_cfg->ui32cropHeight);
10720 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32horOffset=%u\n", p_cfg->ui32horOffset);
10721 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32verOffset=%u\n", p_cfg->ui32verOffset);
10722 ni_log2(p_ctx, NI_LOG_DEBUG, "i8crfMax=%d\n", p_cfg->i8crfMax);
10723 ni_log2(p_ctx, NI_LOG_DEBUG, "i32qcomp=%d\n", p_cfg->i32qcomp);
10724 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8noMbtree=%u\n", p_cfg->ui8noMbtree);
10725 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8noHWMultiPassSupport=%u\n", p_cfg->ui8noHWMultiPassSupport);
10726 ni_log2(p_ctx, NI_LOG_DEBUG, "i8cuTreeFactor=%d\n", p_cfg->i8cuTreeFactor);
10727 ni_log2(p_ctx, NI_LOG_DEBUG, "i32ipRatio=%d\n", p_cfg->i32ipRatio);
10728 ni_log2(p_ctx, NI_LOG_DEBUG, "i32pbRatio=%d\n", p_cfg->i32pbRatio);
10729 ni_log2(p_ctx, NI_LOG_DEBUG, "i32cplxDecay=%d\n", p_cfg->i32cplxDecay);
10730 ni_log2(p_ctx, NI_LOG_DEBUG, "i8ppsInitQp=%d\n", p_cfg->i8ppsInitQp);
10731 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8bitrateMode=%u\n", p_cfg->ui8bitrateMode);
10732 ni_log2(p_ctx, NI_LOG_DEBUG, "i8pass1Qp=%d\n", p_cfg->i8pass1Qp);
10733 ni_log2(p_ctx, NI_LOG_DEBUG, "i8crfDecimal=%d\n", p_cfg->i8crfDecimal);
10734 ni_log2(p_ctx, NI_LOG_DEBUG, "i8hvsBaseMbComplexity=%u\n", p_cfg->i8hvsBaseMbComplexity);
10735 ni_log2(p_ctx, NI_LOG_DEBUG, "i8enableipRatio=%d\n",p_cfg->i8enableipRatio);
10736 ni_log2(p_ctx, NI_LOG_DEBUG, "ui16iFrameSizeRatio=%u\n",p_cfg->ui16iFrameSizeRatio);
10737 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8crfMaxIframeEnable=%u\n", p_cfg->ui8crfMaxIframeEnable);
10738 ni_log2(p_ctx, NI_LOG_DEBUG, "ui32vbvMinRate=%u\n", p_cfg->ui32vbvMinRate);
10739 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8disableBframeRDOQ=%u\n", p_cfg->ui8disableBframeRDOQ);
10740 ni_log2(p_ctx, NI_LOG_DEBUG, "i32forceBframeQpFactor=%d\n", p_cfg->i32forceBframeQpFactor);
10741 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8tuneBframeVisual=%u\n", p_cfg->ui8tuneBframeVisual);
10742 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8EnableAcqLimit=%u\n", p_cfg->ui8EnableAcqLimit);
10743 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8compressor=%u\n", p_cfg->ui8compressor);
10744 ni_log2(p_ctx, NI_LOG_DEBUG, "u8customizeRoiQpLevel=%u\n", p_cfg->u8customizeRoiQpLevel);
10745 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8motionConstrainedMode=%d\n", p_cfg->ui8motionConstrainedMode);
10746 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8mallocStrategy=%d\n", p_cfg->ui8mallocStrategy);
10747 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8spatialLayersMinusOne=%d\n", p_cfg->ui8spatialLayersMinusOne);
10748 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8enableTimecode=%d\n", p_cfg->ui8enableTimecode);
10749 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8spatialLayersRefBaseLayer=%d\n", p_cfg->ui8spatialLayersRefBaseLayer);
10750 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8vbvBufferReencode=%d\n", p_cfg->ui8vbvBufferReencode);
10751 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8totalCuTreeDepth=%u\n", p_cfg->ui8totalCuTreeDepth);
10752 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8adaptiveCuTree=%u\n", p_cfg->ui8adaptiveCuTree);
10753 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8preIntraHandling=%u\n", p_cfg->ui8preIntraHandling);
10754 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8baseLayerOnly=%u\n", p_cfg->ui8baseLayerOnly);
10755 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8pastFrameMaxIntraRatio=%u\n", p_cfg->ui8pastFrameMaxIntraRatio);
10756 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8linkFrameMaxIntraRatio=%u\n", p_cfg->ui8linkFrameMaxIntraRatio);
10757 ni_log2(p_ctx, NI_LOG_DEBUG, "i32spatialLayerBitrate=%d,%d,%d,%d\n", p_cfg->i32spatialLayerBitrate[0],
10759 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8disableAv1TimingInfo=%u\n", p_cfg->ui8disableAv1TimingInfo);
10760 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8av1OpLevel=%u,%u,%u,%u\n", p_cfg->ui8av1OpLevel[0],
10761 p_cfg->ui8av1OpLevel[1], p_cfg->ui8av1OpLevel[2], p_cfg->ui8av1OpLevel[3]);
10762 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8adaptiveLamdaMode=%u\n",p_cfg->ui8adaptiveLamdaMode);
10763 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8getCuInfo=%u\n", p_cfg->ui8getCuInfo);
10764 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8adaptiveCrfMode=%u\n",p_cfg->ui8adaptiveCrfMode);
10765 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8cutreeFlushIframe=%u\n",p_cfg->ui8cutreeFlushIframe);
10766 ni_log2(p_ctx, NI_LOG_DEBUG, "ui8qpScaleEnable=%u\n", p_cfg->ui8qpScaleEnable);
10767}
10768
10769/*!******************************************************************************
10770 * \brief Setup and initialize all xcoder configuration to default (Rev. B)
10771 *
10772 * \param
10773 *
10774 * \return
10775 ******************************************************************************/
10777{
10778 int i = 0;
10779
10780 if( (!p_ctx) || (!p_config) )
10781 {
10782 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
10783 __func__);
10784 return;
10785 }
10786
10787 memset(p_config, 0, sizeof(ni_encoder_config_t));
10788
10789 // fill in common attributes values
10790 p_config->i32picWidth = 720;
10791 p_config->i32picHeight = 480;
10792 p_config->i32meBlkMode = 0; // (AVC ONLY) 0 means use all possible block partitions
10793 p_config->ui8sliceMode = 0; // 0 means 1 slice per picture
10794 p_config->i32frameRateInfo = 30;
10795 p_config->i32frameRateDenominator = 1;
10796 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
10797 p_config->i32userQpMax = 51; // this should also be h264-only parameter
10798
10799 // AVC only
10800 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
10801 {
10802 p_config->i32maxIntraSize = 8000000; // how big an intra p_frame can get?
10803 p_config->i32userMaxDeltaQp = 51;
10804 p_config->i32userMinDeltaQp = 51;
10805 p_config->i32userQpMin = 8;
10806 }
10807
10808 p_config->i32bitRate = 0;
10809 p_config->i32bitRateBL = 0;
10810 p_config->ui8rcEnable = 0;
10811 p_config->i32srcBitDepth = p_ctx->src_bit_depth;
10812 p_config->ui8enablePTS = 0;
10813 p_config->ui8lowLatencyMode = 0;
10814
10815 // profiles for H.264: 1 = baseline, 2 = main, 3 = extended, 4 = high
10816 // 5 = high10 (default 8 bit: 4, 10 bit: 5)
10817 // profiles for HEVC: 1 = main, 2 = main10 (default 8 bit: 1, 10 bit: 2)
10818
10819 // bitstream type: H.264 or HEVC
10820 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
10821 {
10822 p_config->ui8bitstreamFormat = STD_AVC;
10823
10824 p_config->niParamT408.profile = 4;
10825 if (10 == p_ctx->src_bit_depth)
10826 {
10827 p_config->niParamT408.profile = 5;
10828 }
10829 } else if (NI_CODEC_FORMAT_JPEG == p_ctx->codec_format)
10830 {
10831 p_config->ui8bitstreamFormat = STD_JPEG;
10832 } else if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
10833 {
10834 p_config->ui8bitstreamFormat = STD_AV1;
10835
10836 p_config->niParamT408.profile = 1;
10837 } else
10838 {
10840
10841 p_config->ui8bitstreamFormat = STD_HEVC;
10842
10843 p_config->niParamT408.profile = 1;
10844 if (10 == p_ctx->src_bit_depth)
10845 {
10846 p_config->niParamT408.profile = 2;
10847 }
10848 }
10849
10850 p_config->hdrEnableVUI = 0;
10851 p_config->ui32sourceEndian = p_ctx->src_endian;
10852
10853 p_config->niParamT408.level = 0;
10854 p_config->niParamT408.tier = 0; // 0 means main tier
10855
10856 p_config->niParamT408.internalBitDepth = p_ctx->src_bit_depth;
10857 p_config->niParamT408.losslessEnable = 0;
10858 p_config->niParamT408.constIntraPredFlag = 0;
10859
10860 if (QUADRA)
10862 else
10864
10865 p_config->niParamT408.decoding_refresh_type = 1;
10866 p_config->niParamT408.intra_qp = 22;
10867 // avcIdrPeriod (H.264 on T408), NOT shared with intra_period
10868 p_config->niParamT408.intra_period = 120;
10869 p_config->niParamT408.avcIdrPeriod = 120;
10870
10871 p_config->niParamT408.conf_win_top = 0;
10872 p_config->niParamT408.conf_win_bottom = 0;
10873 p_config->niParamT408.conf_win_left = 0;
10874 p_config->niParamT408.conf_win_right = 0;
10875
10876 p_config->niParamT408.independSliceMode = 0;
10877 p_config->niParamT408.independSliceModeArg = 0;
10878 p_config->niParamT408.dependSliceMode = 0;
10879 p_config->niParamT408.dependSliceModeArg = 0;
10880 p_config->niParamT408.intraRefreshMode = 0;
10881 p_config->niParamT408.intraRefreshArg = 0;
10882
10883 p_config->niParamT408.use_recommend_enc_params = 0; //1;
10884 p_config->niParamT408.scalingListEnable = 0;
10885
10886 p_config->niParamT408.cu_size_mode = 7;
10887 p_config->niParamT408.tmvpEnable = 1;
10888 p_config->niParamT408.wppEnable = 0;
10889 p_config->niParamT408.max_num_merge = 2;
10890 p_config->niParamT408.disableDeblk = 0;
10892 p_config->niParamT408.betaOffsetDiv2 = 0;
10893 p_config->niParamT408.tcOffsetDiv2 = 0;
10894 p_config->niParamT408.skipIntraTrans = 1;
10895 p_config->niParamT408.saoEnable = 1;
10896 p_config->niParamT408.intraNxNEnable = 1;
10897
10898 p_config->niParamT408.bitAllocMode = 0;
10899
10900 for (i = 0; i < NI_MAX_GOP_NUM; i++)
10901 {
10902 p_config->niParamT408.fixedBitRatio[i] = 1;
10903 }
10904
10905 if (QUADRA)
10907 else
10909
10910 p_config->niParamT408.enable_hvs_qp = 0;
10911 p_config->niParamT408.hvs_qp_scale = 2;
10912
10913 p_config->niParamT408.max_delta_qp = 10;
10914
10915 // CUSTOM_GOP
10917#ifndef QUADRA
10918 if (!QUADRA)
10919 {
10920 for (i = 0; i < p_config->niParamT408.custom_gop_params.custom_gop_size; i++)
10921 {
10924 p_config->niParamT408.custom_gop_params.pic_param[i].pic_qp = 0;
10925 p_config->niParamT408.custom_gop_params.pic_param[i].num_ref_pic_L0 = 0;
10926 p_config->niParamT408.custom_gop_params.pic_param[i].ref_poc_L0 = 0;
10927 p_config->niParamT408.custom_gop_params.pic_param[i].ref_poc_L1 = 0;
10929 }
10930 }
10931 else // QUADRA
10932#endif
10933 {
10934 int j;
10935 for (i = 0; i < NI_MAX_GOP_NUM; i++)
10936 {
10940 (float)0.3; // QP Factor range is between 0.3 and 1, higher values mean lower quality and less bits
10944 for (j = 0; j < NI_MAX_REF_PIC; j++)
10945 {
10948 }
10949 }
10950 }
10951
10952 p_config->niParamT408.roiEnable = 0;
10953
10954 p_config->niParamT408.numUnitsInTick = 1000;
10955 p_config->niParamT408.timeScale = p_config->i32frameRateInfo * 1000;
10956 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
10957 {
10958 p_config->niParamT408.timeScale *= 2;
10959 }
10960
10961 p_config->niParamT408.numTicksPocDiffOne = 0;
10962
10963 p_config->niParamT408.chromaCbQpOffset = 0;
10964 p_config->niParamT408.chromaCrQpOffset = 0;
10965
10966 p_config->niParamT408.initialRcQp = 63; //-1;
10967
10968 p_config->niParamT408.nrYEnable = 0;
10969 p_config->niParamT408.nrCbEnable = 0;
10970 p_config->niParamT408.nrCrEnable = 0;
10971
10972 // ENC_NR_WEIGHT
10973 p_config->niParamT408.nrIntraWeightY = 7;
10974 p_config->niParamT408.nrIntraWeightCb = 7;
10975 p_config->niParamT408.nrIntraWeightCr = 7;
10976 p_config->niParamT408.nrInterWeightY = 4;
10977 p_config->niParamT408.nrInterWeightCb = 4;
10978 p_config->niParamT408.nrInterWeightCr = 4;
10979
10980 p_config->niParamT408.nrNoiseEstEnable = 0;
10981 p_config->niParamT408.nrNoiseSigmaY = 0;
10982 p_config->niParamT408.nrNoiseSigmaCb = 0;
10983 p_config->niParamT408.nrNoiseSigmaCr = 0;
10984
10985 p_config->niParamT408.useLongTerm = 0;
10986
10987 // newly added for T408
10988 p_config->niParamT408.monochromeEnable = 0;
10990
10991 p_config->niParamT408.weightPredEnable = 0;
10992 p_config->niParamT408.bgDetectEnable = 0;
10993 p_config->niParamT408.bgThrDiff = 8; // matching the C-model
10994 p_config->niParamT408.bgThrMeanDiff = 1; // matching the C-model
10995 p_config->niParamT408.bgLambdaQp = 32; // matching the C-model
10996 p_config->niParamT408.bgDeltaQp = 3; // matching the C-model
10997
10998 p_config->niParamT408.customLambdaEnable = 0;
10999 p_config->niParamT408.customMDEnable = 0;
11000 p_config->niParamT408.pu04DeltaRate = 0;
11001 p_config->niParamT408.pu08DeltaRate = 0;
11002 p_config->niParamT408.pu16DeltaRate = 0;
11003 p_config->niParamT408.pu32DeltaRate = 0;
11005 p_config->niParamT408.pu04IntraDcDeltaRate = 0;
11008 p_config->niParamT408.pu08IntraDcDeltaRate = 0;
11011 p_config->niParamT408.pu16IntraDcDeltaRate = 0;
11014 p_config->niParamT408.pu32IntraDcDeltaRate = 0;
11016 p_config->niParamT408.cu08IntraDeltaRate = 0;
11017 p_config->niParamT408.cu08InterDeltaRate = 0;
11018 p_config->niParamT408.cu08MergeDeltaRate = 0;
11019 p_config->niParamT408.cu16IntraDeltaRate = 0;
11020 p_config->niParamT408.cu16InterDeltaRate = 0;
11021 p_config->niParamT408.cu16MergeDeltaRate = 0;
11022 p_config->niParamT408.cu32IntraDeltaRate = 0;
11023 p_config->niParamT408.cu32InterDeltaRate = 0;
11024 p_config->niParamT408.cu32MergeDeltaRate = 0;
11025 p_config->niParamT408.coefClearDisable = 0;
11026 p_config->niParamT408.minQpI = 8;
11027 p_config->niParamT408.maxQpI = 51;
11028 p_config->niParamT408.minQpP = 8;
11029 p_config->niParamT408.maxQpP = 51;
11030 p_config->niParamT408.minQpB = 8;
11031 p_config->niParamT408.maxQpB = 51;
11032
11033 // for H.264 on T408
11034 p_config->niParamT408.rdoSkip = 0;
11035 p_config->niParamT408.lambdaScalingEnable = 0;
11036 p_config->niParamT408.enable_transform_8x8 = 1;
11037 p_config->niParamT408.slice_mode = 0;
11038 p_config->niParamT408.slice_arg = 0;
11039 p_config->niParamT408.intra_mb_refresh_mode = 0;
11040 p_config->niParamT408.intra_mb_refresh_arg = 0;
11041 if (QUADRA)
11042 p_config->niParamT408.enable_mb_level_rc = 0;
11043 else
11044 p_config->niParamT408.enable_mb_level_rc = 1;
11045 p_config->niParamT408.entropy_coding_mode = 1; // 1 means CABAC, make sure profile is main or above, can't have CABAC in baseline
11046 p_config->niParamT408.forcedHeaderEnable = 0; // first IDR frame
11047
11048 //QUADRA
11049 p_config->ui8EnableAUD = 0;
11050 p_config->ui8LookAheadDepth = 0;
11051 p_config->ui8rdoLevel = (NI_CODEC_FORMAT_JPEG == p_ctx->codec_format) ? 0 : 1;
11052 p_config->i8crf = -1;
11053 p_config->ui16HDR10MaxLight = 0;
11054 p_config->ui16HDR10AveLight = 0;
11055 p_config->ui8HDR10CLLEnable = 0;
11056 p_config->ui8EnableRdoQuant = 0;
11057 p_config->ui8ctbRcMode = 0;
11058 p_config->ui8gopSize = 0;
11059 p_config->ui8useLowDelayPocType = 0;
11060 p_config->ui8gopLowdelay = 0;
11061 p_config->ui16gdrDuration = 0;
11062 p_config->ui8hrdEnable = 0;
11063 p_config->ui8colorDescPresent = 0;
11065 p_config->ui8colorPrimaries = 2;
11066 //AVCOL_TRC_UNSPECIFIED
11067 p_config->ui8colorTrc = 2;
11068 //AVCOL_SPC_UNSPECIFIED
11069 p_config->ui8colorSpace = 2;
11070 p_config->ui16aspectRatioWidth = 0;
11071 p_config->ui16aspectRatioHeight = 0;
11074 p_config->ui32ltrRefInterval = 0;
11075 p_config->i32ltrRefQpOffset = 0;
11076 p_config->ui32ltrFirstGap= 0;
11077 p_config->ui32ltrNextInterval = 1;
11078 p_config->ui8multicoreJointMode = 0;
11079 p_config->ui8videoFullRange = 0;
11080 p_config->ui32setLongTermInterval = 0;
11081 p_config->ui8setLongTermCount = 2;
11082 p_config->ui32QLevel = -1;
11083 p_config->i8chromaQpOffset = 0;
11084 p_config->i32tolCtbRcInter = (int32_t)(0.1 * 1000);
11085 p_config->i32tolCtbRcIntra = (int32_t)(0.1 * 1000);
11086 p_config->i16bitrateWindow = -255;
11087 p_config->ui8inLoopDSRatio = 1;
11088 p_config->ui8blockRCSize = 0;
11089 p_config->ui8rcQpDeltaRange = 10;
11090 p_config->i16ctbRowQpStep = 0;
11091 p_config->ui8NewRCEnable = 255;
11092 p_config->ui8LowDelay = 0;
11093 p_config->ui8fixedframerate = 1;
11094 p_config->ui8enableSSIM = 0;
11095 p_config->ui8hdr10_enable = 0;
11096 p_config->ui16hdr10_dx0 = 0;
11097 p_config->ui16hdr10_dy0 = 0;
11098 p_config->ui16hdr10_dx1 = 0;
11099 p_config->ui16hdr10_dy1 = 0;
11100 p_config->ui16hdr10_dx2 = 0;
11101 p_config->ui16hdr10_dy2 = 0;
11102 p_config->ui16hdr10_wx = 0;
11103 p_config->ui16hdr10_wy = 0;
11104 p_config->ui32hdr10_maxluma = 0;
11105 p_config->ui32hdr10_minluma = 0;
11106 p_config->ui8avccHvcc = 0;
11107 p_config->ui8av1ErrResilientMode = 0;
11108 p_config->ui8intraResetRefresh = 0;
11109 p_config->ui8temporalLayersEnable = 0;
11110 p_config->ui8enable2PassGopPatern = 0;
11111 p_config->i8crfMax = (int8_t)(-1) + 1; // for old libxcoder backward compatibility, use 1 to represent 0
11112 p_config->i32qcomp = (int32_t)(0.6 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
11113 p_config->ui8noMbtree = 0;
11114 p_config->ui8noHWMultiPassSupport = 0;
11115 p_config->i8cuTreeFactor = 5;
11116 p_config->i32ipRatio = (int32_t)(1.4 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
11117 p_config->i32pbRatio = (int32_t)(1.3 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
11118 p_config->i32cplxDecay = (int32_t)(0.5 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
11119 p_config->ui32vbvMaxRate = 0;
11120 p_config->i8ppsInitQp = (int8_t)(-1) + 1; // for old libxcoder backward compatibility, use 1 to represent 0
11121 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)
11122 p_config->i8pass1Qp = (int8_t)(-1) + 1; // for old libxcoder backward compatibility, use 1 to represent 0
11123 p_config->i8crfDecimal = 0;
11124 p_config->i8hvsBaseMbComplexity = (int8_t)(15)-15; // for old libxcoder backward compatibility, use -15 to represent 0
11125 p_config->i8statisticOutputLevel = 0;
11126 p_config->i8enableipRatio = 0;
11127 p_config->ui16iFrameSizeRatio = 100;
11128 p_config->ui8compressor = 3;
11129 p_config->u8skipFrameInterval = 0;
11130 p_config->ui8crfMaxIframeEnable = 0;
11131 p_config->ui32vbvMinRate = 0;
11132 p_config->ui8disableBframeRDOQ = 0;
11133 p_config->i32forceBframeQpFactor = (int32_t)(-1.0 * 1000) + 1000; // for old libxcoder backward compatibility, use 1000 to represent 0
11134 p_config->ui8tuneBframeVisual = 0;
11135 p_config->ui8EnableAcqLimit = 0;
11137 p_config->ui32cropWidth = 0;
11138 p_config->ui32cropHeight = 0;
11139 p_config->ui32horOffset = 0;
11140 p_config->ui32verOffset = 0;
11141 p_config->ui8motionConstrainedMode = 0;
11142 p_config->ui8stillImageDetectLevel = 0;
11143 p_config->ui8sceneChangeDetectLevel = 0;
11144 p_config->ui8mallocStrategy = 0;
11145 p_config->ui8spatialLayersMinusOne = 0;
11146 p_config->ui8enableTimecode = 0;
11147 p_config->ui8spatialLayersRefBaseLayer = 0;
11148 p_config->ui8vbvBufferReencode = 0;
11149 p_config->ui8totalCuTreeDepth = 0;
11150 p_config->ui8adaptiveCuTree = 0;
11151 p_config->ui8preIntraHandling = (uint8_t)(1)-1; // for old libxcoder backward compatibility, use -1 to represent 0
11152 p_config->ui8baseLayerOnly = 0;
11153 p_config->ui8pastFrameMaxIntraRatio = (uint8_t)(20)-20; // for old libxcoder backward compatibility, use -20 to represent 0
11154 p_config->ui8linkFrameMaxIntraRatio = (uint8_t)(40)-40; // for old libxcoder backward compatibility, use -40 to represent 0
11155 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
11156 {
11157 p_config->i32spatialLayerBitrate[i] = 0;
11158 p_config->ui8av1OpLevel[i] = 0;
11159 }
11160 p_config->ui8disableAv1TimingInfo = 0;
11161 p_config->ui8adaptiveLamdaMode = 0;
11162 p_config->ui8getCuInfo = 0;
11163 p_config->ui8adaptiveCrfMode = 0;
11164 p_config->ui8cutreeFlushIframe = 0;
11165 p_config->ui8qpScaleEnable = 0;
11166}
11167
11168/*!******************************************************************************
11169* \brief Perform validation on custom dec parameters (Rev. B)
11170*
11171* \param
11172*
11173* \return
11174******************************************************************************/
11176 ni_session_context_t *p_ctx,
11177 ni_decoder_config_t *p_cfg,
11178 char *p_param_err,
11179 uint32_t max_err_len)
11180{
11181 ni_retcode_t param_ret = NI_RETCODE_SUCCESS;
11183 int w = p_src->source_width;
11184 int h = p_src->source_height;
11185 char *p_param_warn = NULL;
11186 int i;
11187
11188 if (!p_ctx || !p_cfg || !p_param_err)
11189 {
11190 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
11191 __func__);
11192 param_ret = NI_RETCODE_INVALID_PARAM;
11193 LRETURN;
11194 }
11195
11196 // Zero out the error buffer
11197 p_param_warn = malloc(sizeof(p_ctx->param_err_msg));
11198 if (!p_param_warn)
11199 {
11200 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() p_param_warn malloc failure\n",
11201 NI_ERRNO, __func__);
11202 param_ret = NI_RETCODE_ERROR_MEM_ALOC;
11203 LRETURN;
11204 }
11205
11206 memset(p_param_err, 0, max_err_len);
11207 memset(p_param_warn, 0, max_err_len);
11208
11209
11210 //if (p_cfg->i32bitRate > NI_MAX_BITRATE)
11211 //{
11212 // ni_strncpy(p_param_err, max_err_len, "Invalid i32bitRate: too big", max_err_len - 1);
11213 // param_ret = NI_RETCODE_PARAM_ERROR_BRATE;
11214 // LRETURN;
11215 //}
11216
11217 if (p_cfg->ui8HWFrame == 0 &&
11218 (p_cfg->asOutputConfig[1].ui8Enabled || p_cfg->asOutputConfig[2].ui8Enabled))
11219 {
11220 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);
11221 param_ret = NI_RETCODE_INVALID_PARAM;
11222 LRETURN;
11223 }
11224
11225 if (p_src->ddr_priority_mode >= 0)
11226 {
11228 "6e") < 0)
11229 {
11230 ni_strncpy(p_param_err, max_err_len, "ddr_priority_mode not supported on device with FW api version < 6.e",
11231 max_err_len - 1);
11233 LRETURN;
11234 }
11235 }
11236
11238 {
11239 ni_strncpy(p_param_err, max_err_len, "LowDelay is not supported on jpeg/vp9 decoder",
11240 max_err_len - 1);
11242 LRETURN;
11243 }
11244
11245 for (i = 0; i < NI_MAX_NUM_OF_DECODER_OUTPUTS; i++)
11246 {
11247 //checking cropping param
11249 {
11252 {
11253 ni_strncpy(p_param_err, max_err_len, "Invalid crop offset: extends past 48x48 minimum window", max_err_len - 1);
11254 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
11255 LRETURN;
11256 }
11259 {
11260 ni_strncpy(p_param_err, max_err_len, "Invalid crop w or h: must be at least 48x48 minimum window", max_err_len - 1);
11262 LRETURN;
11263 }
11264 if (p_cfg->asOutputConfig[i].sCroppingRectable.ui16W > w ||
11266 {
11267 ni_strncpy(p_param_err, max_err_len, "Invalid crop w or h: must be smaller than input", max_err_len - 1);
11268 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
11269 LRETURN;
11270 }
11273 {
11274 ni_strncpy(p_param_err, max_err_len, "Invalid crop rect: must fit in input", max_err_len - 1);
11275 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
11276 LRETURN;
11277 }
11278 if (p_cfg->asOutputConfig[i].sCroppingRectable.ui16X & 1 ||
11279 p_cfg->asOutputConfig[i].sCroppingRectable.ui16Y & 1 ||
11280 p_cfg->asOutputConfig[i].sCroppingRectable.ui16W & 1 ||
11282 {
11283 ni_strncpy(p_param_err, max_err_len, "Invalid crop value: even values only", max_err_len - 1);
11285 LRETURN;
11286 }
11287 if (p_cfg->asOutputConfig[i].ui8Enabled == 0)
11288 {
11289 ni_strncpy(p_param_warn, max_err_len, "crop param used but output not enabled!", max_err_len - 1);
11290 warning = NI_RETCODE_PARAM_WARN;
11291 }
11292
11293 }
11294
11295 //checking scaling param
11296 if (p_cfg->asOutputConfig[i].ui8ScaleEnabled)
11297 {
11298 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height == 0 ||
11300 {
11302 {
11303 //may need to revisit if based on cropped input or base input for w/h limit
11304 ni_strncpy(p_param_err, max_err_len, "Invalid scale dimensions: zero", max_err_len - 1);
11306 LRETURN;
11307 }
11308 }
11309 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height & 1 ||
11311 {
11312 ni_strncpy(p_param_err, max_err_len, "Invalid scale value: even values only", max_err_len - 1);
11314 LRETURN;
11315 }
11316
11317 if (p_cfg->asOutputConfig[i].ui8EnablePpuScaleLimit == 1)
11318 {
11319 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Width > w ||
11321 {
11322 ni_strncpy(p_param_err, max_err_len, "Invalid scale value: downscale only", max_err_len - 1);
11324 LRETURN;
11325 }
11326 }
11327
11329 {
11330 //reject if scale dimensions exceed crop dimensions
11333 {
11334 ni_strncpy(p_param_err, max_err_len, "Invalid scale dimensions: downscale only after cropping", max_err_len - 1);
11335 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
11336 LRETURN;
11337 }
11338 }
11339 if (p_cfg->asOutputConfig[i].ui8Enabled == 0)
11340 {
11341 ni_strncpy(p_param_warn, max_err_len, "scale param used but output not enabled!", max_err_len - 1);
11342 warning = NI_RETCODE_PARAM_WARN;
11343 }
11344 }
11345 if (p_cfg->asOutputConfig[i].ui8Enabled == 0)
11346 {
11348 {
11349 ni_strncpy(p_param_warn, max_err_len, "force8bit or semiPlanar used but output not enabled!", max_err_len - 1);
11350 warning = NI_RETCODE_PARAM_WARN;
11351 }
11352 }
11353
11354 //check tiled format compatibility
11356 {
11357 if (p_cfg->asOutputConfig[i].ui8Enabled == 0)
11358 {
11359 continue;
11360 }
11361 if (p_cfg->ui8HWFrame == 0)
11362 {
11363 ni_strncpy(p_param_err, max_err_len,
11364 "Invalid pairing: out=HW must be set with tiled format",
11365 max_err_len - 1);
11367 LRETURN;
11368 }
11369 if (p_ctx->codec_format == NI_CODEC_FORMAT_VP9)
11370 {
11371 ni_strncpy(p_param_err, max_err_len, "Invalid pairing: VP9 not compatible with tiled format",
11372 max_err_len - 1);
11374 LRETURN;
11375 }
11376 if (p_cfg->asOutputConfig[i].ui8ScaleEnabled)
11377 {
11378 //only no need to check crop compat if scale is set
11379 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Height % 4 ||
11381 {
11382 ni_strncpy(p_param_err, max_err_len,
11383 "Invalid scale height: mult of 4 only, >= 128",
11384 max_err_len - 1);
11386 LRETURN;
11387 }
11388 if (p_cfg->asOutputConfig[i].sOutputPictureSize.i16Width % 4 ||
11390 {
11391 //minimum supported dec is 128 but min enc is 144 so round up
11392 ni_strncpy(p_param_err, max_err_len,
11393 "Invalid scale width: mult of 128 only, >= 144",
11394 max_err_len - 1);
11396 LRETURN;
11397 }
11398 }
11400 {
11401 if (p_cfg->asOutputConfig[i].sCroppingRectable.ui16H % 4 ||
11402 p_cfg->asOutputConfig[i].sCroppingRectable.ui16H < 128)
11403 {
11404 ni_strncpy(p_param_err, max_err_len,
11405 "Invalid crop height: mult of 4 only, >= 128",
11406 max_err_len - 1);
11408 LRETURN;
11409 }
11410 if (p_cfg->asOutputConfig[i].sCroppingRectable.ui16W % 4 ||
11412 {
11413 //minimum supported dec is 128 but min enc is 144 so round up
11414 ni_strncpy(p_param_err, max_err_len,
11415 "Invalid crop width: mult of 128 only, >= 144",
11416 max_err_len - 1);
11418 LRETURN;
11419 }
11420 }
11421 if (p_cfg->asOutputConfig[i].ui8Force8Bit)
11422 {
11423 ni_strncpy(p_param_err, max_err_len, "Force 8 bit: not supported with tiled format\n", max_err_len - 1);
11425 LRETURN;
11426 }
11427 }
11428
11429 }//end forloop
11430 if (warning == NI_RETCODE_PARAM_WARN && param_ret == NI_RETCODE_SUCCESS)
11431 {
11432 param_ret = NI_RETCODE_PARAM_WARN;
11433 ni_strncpy(p_param_err, max_err_len, p_param_warn, max_err_len - 1);
11434 }
11435
11436END:
11437
11438 free(p_param_warn);
11439 return param_ret;
11440}
11441
11442// Check encoder level parameters
11443static ni_retcode_t ni_check_level(int level, int codec_id, int *level_index)
11444{
11445 // '99' value in l_levels_264 holds the slot for level '1b'.
11446 const int l_levels_264[] = {10, 99, 11, 12, 13, 20, 21, 22, 30, 31, 32,
11447 40, 41, 42, 50, 51, 52, 60, 61, 62, 0};
11448 const int l_levels_265[] = {10, 20, 21, 30, 31, 40, 41,
11449 50, 51, 52, 60, 61, 62, 0};
11450 const int l_levels_av1[] = {20, 21, 30, 31, 40, 41, 50, 51, 52, 53, 60, 61, 62, 63, 0};
11451 const int *l_levels = l_levels_264;
11452 int index = 0;
11453
11454 *level_index = -1;
11455
11456 if (level == 0)
11457 {
11458 return NI_RETCODE_SUCCESS;
11459 }
11460
11461 if (codec_id == NI_CODEC_FORMAT_H265)
11462 {
11463 l_levels = l_levels_265;
11464 } else if (codec_id == NI_CODEC_FORMAT_AV1)
11465 {
11466 l_levels = l_levels_av1;
11467 }
11468
11469 while (*l_levels != 0)
11470 {
11471 if (*l_levels == level)
11472 {
11473 *level_index = index;
11474 return NI_RETCODE_SUCCESS;
11475 }
11476 l_levels++;
11477 index++;
11478 }
11479
11480 return NI_RETCODE_FAILURE;
11481}
11482
11483static uint32_t get_max_pic_size( ni_codec_format_t codecFormat , int32_t levelIdx )
11484{
11485 assert( levelIdx >= 0);
11486 int32_t level = MAX(0, levelIdx);
11487 uint32_t maxPicSize = 0;
11488
11489 switch( codecFormat )
11490 {
11492 assert( level < HEVC_LEVEL_NUM );
11493 level = MIN( level, (HEVC_LEVEL_NUM - 1));
11494 maxPicSize = max_pic_size_h265[ level ];
11495 break;
11496
11498 assert( level < H264_LEVEL_NUM );
11499 level = MIN( level, (H264_LEVEL_NUM - 1));
11500 maxPicSize = max_pic_size_h264[ level ];
11501 break;
11502
11504 level = MIN( level, (AV1_LEVEL_NUM - 1));
11505 maxPicSize = max_pic_size_av1[ level ];
11506 break;
11507
11508 default:
11509 break;
11510 }
11511
11512 return maxPicSize;
11513}
11514
11515static uint64_t get_max_sample_rate_second( ni_codec_format_t codecFormat , int32_t levelIdx )
11516{
11517 assert( levelIdx >= 0);
11518 int32_t level = MAX(0, levelIdx);
11519 uint64_t maxSBPS = 0;
11520
11521 switch( codecFormat )
11522 {
11524 assert( level < HEVC_LEVEL_NUM );
11525 level = MIN( level, (HEVC_LEVEL_NUM - 1));
11526 maxSBPS = max_sample_rate_second_h265[ level ];
11527 break;
11528
11530 assert( level < H264_LEVEL_NUM );
11531 level = MIN( level, (H264_LEVEL_NUM - 1));
11532 maxSBPS = max_sample_rate_second_h264[ level ];
11533 break;
11534
11536 level = MIN( level, (AV1_LEVEL_NUM - 1));
11537 maxSBPS = max_sample_rate_second_av1[ level ];
11538 break;
11539
11540 default:
11541 break;
11542 }
11543
11544 return maxSBPS;
11545}
11546
11547// type 0: returns maximum bitrate, type 1: returns maximum vbv buffer size
11548static uint32_t get_max_cpb_bitrate( ni_codec_format_t codecFormat , int32_t levelIdx, int32_t profile, int32_t tier, int32_t type )
11549{
11550 assert( levelIdx >= 0);
11551 int32_t level = MAX(0, levelIdx);
11552 uint32_t maxBR = 0;
11553
11554 switch( codecFormat )
11555 {
11557 assert( level < HEVC_LEVEL_NUM );
11558 level = MIN( level, (HEVC_LEVEL_NUM - 1));
11559 maxBR = (tier == HIGH_TIER) ? max_cpb_hightier_second_h265[ level ] : max_cpb_second_h265[ level ];
11560 break;
11561
11563 assert( level < H264_LEVEL_NUM );
11564 level = MIN( level, (H264_LEVEL_NUM - 1));
11565 float h264_high10_factor = 1;
11566 if(profile == 4) /* High Profile */
11567 h264_high10_factor = (float)1.25;
11568 else if(profile == 5) /* High 10 Profile */
11569 h264_high10_factor = (float)3.0;
11570 if(type == 0)
11571 maxBR = (uint32_t)((float)max_bitrate_h264[ level ] * h264_high10_factor);
11572 else
11573 maxBR = (uint32_t)((float)max_cpb_second_h264[ level ] * h264_high10_factor);
11574 break;
11575
11577 level = MIN( level, (AV1_LEVEL_NUM - 1));
11578 maxBR = ((level > 7) && (tier == HIGH_TIER)) ? max_cpb_hightier_second_av1[ level ] : max_cpb_second_av1[ level ];
11579 break;
11580
11581 default:
11582 break;
11583 }
11584
11585 return maxBR;
11586}
11587
11588// Check encoder level parameters
11589static ni_retcode_t ni_check_level_tier_compliance(int level,
11590 ni_session_context_t *p_ctx,
11591 ni_encoder_config_t *p_cfg,
11592 ni_xcoder_params_t *p_src,
11593 char *p_param_err,
11594 char* p_param_warn,
11595 uint32_t max_err_len,
11596 ni_retcode_t *warning,
11597 int level_index)
11598{
11599 if( (!p_ctx) || (!p_cfg) || (!p_src) || (!p_param_err) || (!p_param_warn) || (!warning) )
11600 {
11601 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n", __func__);
11603 }
11604
11605 // level and tier check
11606 uint32_t sample_per_picture = p_src->source_width * p_src->source_height;
11607 uint64_t sample_per_second = sample_per_picture * p_cfg->i32frameRateInfo / p_cfg->i32frameRateDenominator;
11608 uint32_t max_pic_size = get_max_pic_size((ni_codec_format_t)p_ctx->codec_format, level_index);
11609 uint64_t max_sample_rate_second = get_max_sample_rate_second((ni_codec_format_t)p_ctx->codec_format, level_index);
11610 uint32_t max_bitrate = get_max_cpb_bitrate((ni_codec_format_t)p_ctx->codec_format, level_index, p_cfg->niParamT408.profile, p_cfg->niParamT408.tier, 0);
11611 uint32_t max_vbv = get_max_cpb_bitrate((ni_codec_format_t)p_ctx->codec_format, level_index, p_cfg->niParamT408.profile, p_cfg->niParamT408.tier, 1);
11612
11613 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",
11614 __func__, sample_per_picture, sample_per_second, p_cfg->i32frameRateInfo, p_cfg->i32frameRateDenominator,
11615 level_index);
11616 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): max_pic_size %d max_sample_rate_second %" PRIu64 " max_bitrate %u\n",
11617 __func__, max_pic_size, max_sample_rate_second, max_bitrate);
11618
11619 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): i8crf %d i32bitRate %d ui32vbvMaxRate %u i32vbvBufferSize %d\n",
11620 __func__, p_cfg->i8crf, p_cfg->i32bitRate, p_cfg->ui32vbvMaxRate, p_cfg->i32vbvBufferSize);
11621
11622 if (p_cfg->i8crf != -1)
11623 {
11624 if(p_cfg->i32vbvBufferSize == 0)
11625 {
11626 (void)snprintf(p_param_warn, max_err_len, "Level (%.1f): Switched crf to capped crf to be compliant with the level",
11627 (float) level/10);
11628 *warning = NI_RETCODE_PARAM_WARN;
11629 p_cfg->ui32vbvMaxRate = p_cfg->i32bitRate = (int32_t)max_bitrate;
11630 p_cfg->i32vbvBufferSize = 1000;
11631 }
11632 }
11633 else if (p_cfg->ui8rcEnable == 0) // enable rate control if fixed QP mode
11634 {
11635 ni_strncpy(p_param_warn, max_err_len, "Enabled rate control because level parameter is used", max_err_len - 1);
11636 *warning = NI_RETCODE_PARAM_WARN;
11638 p_cfg->i32vbvBufferSize = 1000;
11639 }
11640
11641 if(sample_per_picture > max_pic_size)
11642 {
11643 (void)snprintf(p_param_err, max_err_len, "Invalid Encoder Level (%.1f): picture size %u exceeds supported limits %u",
11644 (float) level/10, sample_per_picture, max_pic_size);
11646 }
11647
11648 if(sample_per_second > max_sample_rate_second)
11649 {
11650 (void)snprintf(p_param_err, max_err_len, "Invalid Encoder Level (%.1f): picture sample rate %" PRIu64 " exceeds supported limits %" PRIu64 "",
11651 (float) level/10, sample_per_second, max_sample_rate_second);
11653 }
11654
11655 if(p_cfg->i32bitRate > (int32_t)max_bitrate)
11656 {
11657 (void)snprintf(p_param_warn, max_err_len, "Level (%.1f): bitrate %d exceeds supported limit. Changed it to maximum %u",
11658 (float) level/10, p_cfg->i32bitRate, max_bitrate);
11659 *warning = NI_RETCODE_PARAM_WARN;
11660 p_cfg->i32bitRate = (int32_t)max_bitrate;
11661 }
11662
11663 if(p_cfg->ui32vbvMaxRate > (int32_t)max_vbv)
11664 {
11665 (void)snprintf(p_param_warn, max_err_len, "Level (%.1f): vbvMaxRate %u exceeds supported limit. Changed it to maximum %u",
11666 (float) level/10, p_cfg->ui32vbvMaxRate, max_vbv);
11667 *warning = NI_RETCODE_PARAM_WARN;
11668 p_cfg->ui32vbvMaxRate = (int32_t)max_vbv;
11669 }
11670
11671 return NI_RETCODE_SUCCESS;
11672}
11673
11674/*!******************************************************************************
11675 * \brief Perform validation on custom parameters (Rev. B)
11676 *
11677 * \param
11678 *
11679 * \return
11680 ******************************************************************************/
11682 ni_encoder_config_t *p_cfg,
11683 ni_xcoder_params_t *p_src,
11684 char *p_param_err,
11685 uint32_t max_err_len)
11686{
11687 ni_retcode_t param_ret = NI_RETCODE_SUCCESS;
11689 char* p_param_warn = malloc(sizeof(p_ctx->param_err_msg));
11691 int i;
11692 int level_index = 0;
11693
11694 if( (!p_ctx) || (!p_cfg) || (!p_src) || (!p_param_err) )
11695 {
11696 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
11697 __func__);
11698 param_ret = NI_RETCODE_INVALID_PARAM;
11699 LRETURN;
11700 }
11701
11702 //Zero out the error buffer
11703 p_enc = &p_src->cfg_enc_params;
11704 memset(p_param_err, 0, max_err_len);
11705 memset(p_param_warn, 0, max_err_len);
11706
11707 if (0 == p_cfg->i32frameRateInfo)
11708 {
11709 ni_strncpy(p_param_err, max_err_len, "Invalid frame_rate of 0 value", max_err_len - 1);
11710 param_ret = NI_RETCODE_PARAM_ERROR_FRATE;
11711 LRETURN;
11712 }
11713
11714 if (((p_cfg->i32frameRateInfo + p_cfg->i32frameRateDenominator - 1) /
11716 {
11717 ni_strncpy(p_param_err, max_err_len, "Invalid i32frameRateInfo: too big", max_err_len - 1);
11718 param_ret = NI_RETCODE_PARAM_ERROR_FRATE;
11719 LRETURN;
11720 }
11721
11722 if (p_cfg->i32bitRate <=
11723 ((p_cfg->i32frameRateInfo + p_cfg->i32frameRateDenominator - 1) / p_cfg->i32frameRateDenominator))
11724 {
11725 ni_strncpy(p_param_err, max_err_len, "Invalid i32bitRate: smaller than or equal to frame rate", max_err_len - 1);
11726 param_ret = NI_RETCODE_PARAM_ERROR_BRATE;
11727 LRETURN;
11728 }
11729
11730 if (p_cfg->i32bitRate > NI_MAX_BITRATE)
11731 {
11732 ni_strncpy(p_param_err, max_err_len, "Invalid i32bitRate: too big", max_err_len - 1);
11733 param_ret = NI_RETCODE_PARAM_ERROR_BRATE;
11734 LRETURN;
11735 }
11736
11737 if (p_cfg->i32bitRate < NI_MIN_BITRATE )
11738 {
11739 ni_strncpy(p_param_err, max_err_len, "Invalid i32bitRate: too low", max_err_len - 1);
11740 param_ret = NI_RETCODE_PARAM_ERROR_BRATE;
11741 LRETURN;
11742 }
11743
11745 {
11746 ni_strncpy(p_param_err, max_err_len, "Invalid Picture Width: too small", max_err_len - 1);
11748 LRETURN;
11749 }
11750
11752 {
11753 ni_strncpy(p_param_err, max_err_len, "Invalid Picture Width: too big", max_err_len - 1);
11755 LRETURN;
11756 }
11757
11759 {
11760 ni_strncpy(p_param_err, max_err_len, "Invalid Picture Height: too small", max_err_len - 1);
11762 LRETURN;
11763 }
11764
11766 {
11767 ni_strncpy(p_param_err, max_err_len, "Invalid Picture Height: too big", max_err_len - 1);
11769 LRETURN;
11770 }
11771
11772 if (p_cfg->ui32cropWidth || p_cfg->ui32cropHeight)
11773 {
11774 // check cropping width & height are both non-zero
11775 if (!p_cfg->ui32cropWidth || !p_cfg->ui32cropHeight)
11776 {
11777 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Width x Height (%u x %u): both need to be specified",
11778 p_cfg->ui32cropWidth, p_cfg->ui32cropHeight);
11779 param_ret = NI_RETCODE_INVALID_PARAM;
11780 LRETURN;
11781 }
11782 // check cropping width & height are even
11783 if ((p_cfg->ui32cropWidth % 2) || (p_cfg->ui32cropHeight % 2))
11784 {
11785 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Width x Height (%u x %uu): must be even",
11786 p_cfg->ui32cropWidth, p_cfg->ui32cropHeight);
11787 param_ret = NI_RETCODE_INVALID_PARAM;
11788 LRETURN;
11789 }
11790 // check cropping width & height meet resoultion constraint (including AV1 max resoultion)
11791 if (p_cfg->ui32cropWidth < NI_MIN_WIDTH)
11792 {
11793 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Width: less than %d",
11794 NI_MIN_WIDTH);
11796 LRETURN;
11797 }
11798 if (p_cfg->ui32cropHeight < NI_MIN_HEIGHT)
11799 {
11800 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Height: less than %d",
11803 LRETURN;
11804 }
11805 if (p_cfg->ui32cropWidth > NI_PARAM_MAX_WIDTH)
11806 {
11807 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Width: exceeds %d",
11810 LRETURN;
11811 }
11813 {
11814 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Height: exceeds %d",
11817 LRETURN;
11818 }
11820 {
11821 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Width x Height: exceeds %d",
11824 LRETURN;
11825 }
11826
11827 if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
11828 {
11830 {
11831 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Width: exceeds %d",
11834 LRETURN;
11835 }
11837 {
11838 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Height: exceeds %d",
11841 LRETURN;
11842 }
11844 {
11845 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Width x Height: exceeds %d",
11848 LRETURN;
11849 }
11850 }
11851
11852 // check cropping horOffset & verOffset are even
11853 if ((p_cfg->ui32horOffset % 2) || (p_cfg->ui32verOffset % 2))
11854 {
11855 (void)snprintf(p_param_err, max_err_len, "Invalid Crop horOffset %u and/or verOffset %u: must be even",
11856 p_cfg->ui32horOffset, p_cfg->ui32verOffset);
11857 param_ret = NI_RETCODE_INVALID_PARAM;
11858 LRETURN;
11859 }
11860
11861 if (p_src->source_width < (int)(p_cfg->ui32horOffset + p_cfg->ui32cropWidth))
11862 {
11863 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Width: offset %u + crop width %u too big > %d",
11864 p_cfg->ui32horOffset, p_cfg->ui32cropWidth, p_src->source_width);
11866 LRETURN;
11867 }
11868 if (p_src->source_height < (int)(p_cfg->ui32verOffset + p_cfg->ui32cropHeight))
11869 {
11870 (void)snprintf(p_param_err, max_err_len, "Invalid Crop Height: offset %u + crop height %u too big > %d",
11871 p_cfg->ui32verOffset, p_cfg->ui32cropHeight, p_src->source_height);
11873 LRETURN;
11874 }
11875 if (p_enc->roi_enable)
11876 {
11877 (void)snprintf(p_param_err, max_err_len, "roiEnable must disabled when Crop Width > 0 || Crop Height > 0");
11878 param_ret = NI_RETCODE_INVALID_PARAM;
11879 LRETURN;
11880 }
11881 }
11882 else // check source width / height meet AV1 max resoultion constraint if cropping not specified
11883 {
11884 if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
11885 {
11887 {
11888 (void)snprintf(p_param_err, max_err_len, "Invalid Picture Width: exceeds %d",
11891 LRETURN;
11892 }
11894 {
11895 (void)snprintf(p_param_err, max_err_len, "Invalid Picture Height: exceeds %d",
11898 LRETURN;
11899 }
11900 if (p_src->source_width * p_src->source_height > NI_PARAM_AV1_MAX_AREA)
11901 {
11902 (void)snprintf(p_param_err, max_err_len, "Invalid Picture Width x Height: exceeds %d",
11905 LRETURN;
11906 }
11907 }
11908 }
11909
11911 {
11912 ni_strncpy(p_param_err, max_err_len, "Invalid input planar format: out of range", max_err_len - 1);
11913 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
11914 LRETURN;
11915 }
11917 {
11919 "68") < 0)
11920 {
11921 ni_strncpy(p_param_err, max_err_len, "Invalid input planar format for device with FW api version < 6.8",
11922 max_err_len - 1);
11924 LRETURN;
11925 }
11926 if (p_ctx->auto_dl_handle)
11927 {
11928 ni_strncpy(p_param_err, max_err_len, "Invalid Encoder Selected: Tiled format must be on same device",
11929 max_err_len - 1);
11931 LRETURN;
11932 }
11933 if (p_src->source_height % 4 != 0)
11934 {
11935 ni_strncpy(p_param_err, max_err_len,
11936 "Invalid Picture Height: tiled format only supports "
11937 "multiples of 4",
11938 max_err_len - 1);
11940 LRETURN;
11941 }
11942 if (p_src->source_width % 4 != 0)
11943 {
11944 ni_strncpy(p_param_err, max_err_len,
11945 "Invalid Picture Width: tiled format only supports "
11946 "multiples of 4",
11947 max_err_len - 1);
11949 LRETURN;
11950 }
11951 }
11952
11953 if (p_cfg->ui8PixelFormat == NI_PIX_FMT_RGBA ||
11954 p_cfg->ui8PixelFormat == NI_PIX_FMT_BGRA ||
11955 p_cfg->ui8PixelFormat == NI_PIX_FMT_ABGR ||
11957 {
11958 if (p_src->zerocopy_mode == 0)
11959 {
11960 ni_strncpy(p_param_err, max_err_len, "zeroCopyMode must not be disabled for RGBA / BGRA / ABGR / ARGB pixel formats", max_err_len - 1);
11961 param_ret = NI_RETCODE_INVALID_PARAM;
11962 LRETURN;
11963 }
11964 if (p_cfg->ui8PixelFormat == NI_PIX_FMT_RGBA ||
11966 {
11968 "6Y") < 0)
11969 {
11970 ni_strncpy(p_param_err, max_err_len, "RGBA / BGRA pixel formats not supported on device with FW api version < 6.Y",
11971 max_err_len - 1);
11973 LRETURN;
11974 }
11975 }
11976 }
11977 else if (p_cfg->ui8PixelFormat != NI_PIX_FMT_YUV420P &&
11979 p_cfg->ui8PixelFormat != NI_PIX_FMT_NV12 &&
11983 {
11984 (void)snprintf(p_param_err, max_err_len, "Unsupported pixel format %d in encoder", p_cfg->ui8PixelFormat);
11985 param_ret = NI_RETCODE_INVALID_PARAM;
11986 LRETURN;
11987 }
11988
11989 if (p_src->ddr_priority_mode >= 0)
11990 {
11992 "6e") < 0)
11993 {
11994 ni_strncpy(p_param_err, max_err_len, "ddr_priority_mode not supported on device with FW api version < 6.e",
11995 max_err_len - 1);
11997 LRETURN;
11998 }
11999 }
12000
12001 if (p_src->cfg_enc_params.level_idc)
12002 {
12003 if (NI_RETCODE_SUCCESS !=
12004 ni_check_level((int)p_src->cfg_enc_params.level_idc, (int)p_ctx->codec_format, &level_index))
12005 {
12006 ni_strncpy(p_param_err, max_err_len, "Invalid Encoder Level: out of range", max_err_len - 1);
12007 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
12008 LRETURN;
12009 }
12010
12011 param_ret = ni_check_level_tier_compliance(
12012 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);
12013 if(param_ret != NI_RETCODE_SUCCESS)
12014 {
12015 LRETURN;
12016 }
12017 }
12018
12019 if ((p_src->cfg_enc_params.intra_mb_refresh_mode < 0 ||
12023 {
12024 ni_strncpy(p_param_err, max_err_len, "Invalid intra_mb_refresh_mode: out of range",
12025 max_err_len - 1);
12026 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
12027 LRETURN;
12028 }
12029
12030 if (!QUADRA)
12031 {
12033 {
12035 {
12036 ni_strncpy(p_param_err, max_err_len, "Invalid custom GOP paramaters: custom_gop_size too small", max_err_len - 1);
12038 LRETURN;
12039 }
12042 {
12043 ni_strncpy(p_param_err, max_err_len, "Invalid custom GOP paramaters: custom_gop_size too big", max_err_len - 1);
12045 LRETURN;
12046 }
12047 }
12048 }
12049 else // QUADRA
12050 {
12052 {
12054 {
12055 ni_strncpy(p_param_err, max_err_len,
12056 "Invalid custom GOP paramaters: custom gop size must > 0",
12057 max_err_len - 1);
12059 LRETURN;
12060 }
12061 }
12063 {
12066 {
12067 ni_strncpy(p_param_err, max_err_len,
12068 "Invalid custom GOP paramaters: selected gopPresetIdx is "
12069 "not compatible with custom gop",
12070 max_err_len - 1);
12072 LRETURN;
12073 }
12075 {
12076 ni_strncpy(p_param_err, max_err_len, "Invalid custom GOP paramaters: custom_gop_size too small", max_err_len - 1);
12078 LRETURN;
12079 }
12082 {
12083 ni_strncpy(p_param_err, max_err_len, "Invalid custom GOP paramaters: custom_gop_size too big", max_err_len - 1);
12085 LRETURN;
12086 }
12087
12088 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size; i++)
12089 {
12092 {
12093 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: poc_offset larger"
12094 " than GOP size", max_err_len - 1);
12096 LRETURN;
12097 }
12098 }
12099 }
12100
12101 if(p_cfg->ui8useLowDelayPocType != 0)
12102 {
12103 if (NI_CODEC_FORMAT_H264 != p_ctx->codec_format)
12104 {
12105 p_cfg->ui8useLowDelayPocType = 0;
12106 ni_strncpy(p_param_warn, max_err_len, "useLowDelayPocType is only supported for H.264. Change useLowDelayPocType to 0", max_err_len - 1);
12107 warning = NI_RETCODE_PARAM_WARN;
12108 }
12109 }
12110 if(p_cfg->niParamT408.entropy_coding_mode != 1)
12111 {
12112 if (NI_CODEC_FORMAT_H264 != p_ctx->codec_format)
12113 {
12114 ni_strncpy(p_param_err, max_err_len,
12115 "entropyCodingMode is only supported for H.264.",
12116 max_err_len - 1);
12118 LRETURN;
12119 }
12120 }
12121 if (p_cfg->ui8av1ErrResilientMode)
12122 {
12123 if (NI_CODEC_FORMAT_AV1 != p_ctx->codec_format)
12124 {
12125 ni_strncpy(p_param_err, max_err_len,
12126 "av1ErrorResilientMode is only supported for AV1.",
12127 max_err_len - 1);
12129 LRETURN;
12130 }
12131 }
12132 if (0 != p_src->enable_ai_enhance)
12133 {
12134 if (NI_CODEC_FORMAT_JPEG == p_ctx->codec_format)
12135 {
12136 (void)snprintf(p_param_err, max_err_len, "%s is not supported for JPEG.",
12137 ((p_src->enable_ai_enhance == 2) ? "enableHVSPlus" : "enableAIEnhance"));
12139 LRETURN;
12140 }
12141 }
12142 if (-1 != p_cfg->ui32QLevel)
12143 {
12144 if (NI_CODEC_FORMAT_JPEG != p_ctx->codec_format)
12145 {
12146 ni_strncpy(p_param_err, max_err_len, "qLevel is only supported for JPEG.",
12147 max_err_len - 1);
12149 LRETURN;
12150 }
12151 }
12152
12153 if(p_cfg->ui8enableSSIM != 0)
12154 {
12156 "62") < 0 || NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
12157 {
12158 p_cfg->ui8enableSSIM = 0;
12159 ni_strncpy(p_param_warn, max_err_len, "enableSSIM only supported on device with FW api version < 6.2 "
12160 "and the encoder is not av1_ni_quadra_enc. Reported ssim will be 0.", max_err_len - 1);
12161 warning = NI_RETCODE_PARAM_WARN;
12162 }
12163 }
12164
12165 if (p_cfg->niParamT408.slice_mode || p_cfg->niParamT408.slice_arg)
12166 {
12168 {
12169 ni_strncpy(p_param_err, max_err_len, "sliceMode/sliceArg is only supported for H.264 or H.265.",
12170 max_err_len - 1);
12172 LRETURN;
12173 }
12174
12175 if (p_cfg->niParamT408.slice_mode)
12176 {
12177 int ctu_mb_size = (NI_CODEC_FORMAT_H264 == p_ctx->codec_format) ? 16 : 64;
12178 int max_num_ctu_mb_row = (p_src->source_height + ctu_mb_size - 1) / ctu_mb_size;
12179 if (p_cfg->niParamT408.slice_arg < 1 || p_cfg->niParamT408.slice_arg > max_num_ctu_mb_row ||
12181 {
12182 (void)snprintf(p_param_err, max_err_len, "Invalid number of rows per slice: should be between 1 and %d",
12183 max_num_ctu_mb_row < NI_MAX_SLICE_SIZE ? max_num_ctu_mb_row : NI_MAX_SLICE_SIZE);
12185 LRETURN;
12186 }
12187 }
12188 }
12189 if (p_src->use_low_delay_poc_type)
12190 {
12191 if (NI_CODEC_FORMAT_H264 != p_ctx->codec_format)
12192 {
12193 ni_strncpy(p_param_err, max_err_len, "useLowDelayPocType is only supported for H.264.",
12194 max_err_len - 1);
12196 LRETURN;
12197 }
12198 }
12199
12200 if(p_cfg->ui8enableCompensateQp != 0)
12201 {
12202 if (ni_cmp_fw_api_ver((char*) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6ru") < 0 ||
12203 NI_CODEC_FORMAT_AV1 == p_ctx->codec_format || p_cfg->ui16maxFrameSize == 0)
12204 {
12205 p_cfg->ui8enableCompensateQp = 0;
12206 ni_strncpy(p_param_warn, max_err_len, "ui8enableCompensateQp only supported when device with FW api version < 6rt "
12207 "and the encoder is not av1_ni_quadra_enc and ui16maxFrameSize > 0. Reported enableCompensateQp will be 0.", max_err_len - 1);
12208 warning = NI_RETCODE_PARAM_WARN;
12209 }
12210 }
12211
12212 if (p_cfg->ui8enableTimecode != 0)
12213 {
12214 if (NI_CODEC_FORMAT_H264 != p_ctx->codec_format)
12215 {
12216 p_cfg->ui8enableTimecode = 0;
12217 if (NI_CODEC_FORMAT_H265 == p_ctx->codec_format)
12218 {
12219 ni_strncpy(p_param_warn, max_err_len, "enableTimecode does not need to be set for H.265. Use ni_enc_insert_timecode API"
12220 "from libxcoder directly to insert time code SEI", max_err_len - 1);
12221 }
12222 else
12223 {
12224 ni_strncpy(p_param_warn, max_err_len, "enableTimecode not supported for the codec used. Forcing value to 0.", max_err_len - 1);
12225 }
12226 warning = NI_RETCODE_PARAM_WARN;
12227 }
12228 }
12229 }
12230
12231 if (QUADRA)
12232 {
12233 if (p_cfg->ui8LookAheadDepth != 0 || p_cfg->i8crf >= 0)
12234 {
12235 if ((1 == p_cfg->niParamT408.gop_preset_index && p_cfg->ui8LookAheadDepth != 0) ||
12236 3 == p_cfg->niParamT408.gop_preset_index ||
12237 7 == p_cfg->niParamT408.gop_preset_index ||
12238 10 == p_cfg->niParamT408.gop_preset_index ||
12239 15 == p_cfg->niParamT408.gop_preset_index)
12240 {
12241 ni_strncpy(p_param_err, max_err_len,
12242 "this gopPreset is not supported for lookahead and/or CRF",
12243 max_err_len - 1);
12245 LRETURN;
12246 }
12247
12249 {
12250 bool bIsgopLowdelay = true;
12251 // lookahead does not support gopLowDelay (all B-frames, encode in order) gop patterns
12252 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size;
12253 i++)
12254 {
12255 // check if all frames are B-frames
12257 {
12258 bIsgopLowdelay = false;
12259 break;
12260 }
12261 // check if all frames are encoded in display order
12262 if (p_cfg->niParamT408.custom_gop_params.pic_param[i].poc_offset != (i+1))
12263 {
12264 bIsgopLowdelay = false;
12265 break;
12266 }
12267 }
12268 if (bIsgopLowdelay)
12269 {
12270 ni_strncpy(p_param_err, max_err_len, "B-frames low delay custom gop is not supported for "
12271 "lookahead and/or CRF", max_err_len - 1);
12272 param_ret = NI_RETCODE_INVALID_PARAM;
12273 LRETURN;
12274 }
12275 }
12276
12277 if (p_enc->bitrateMode != -1)
12278 {
12279 ni_strncpy(p_param_err, max_err_len,
12280 "bitrateMode is invalid when lookahead is enabled (or in CRF mode)",
12281 max_err_len - 1);
12283 LRETURN;
12284 }
12285 }
12286
12287 if (p_cfg->ui8totalCuTreeDepth != 0)
12288 {
12289 if (p_cfg->ui8LookAheadDepth == 0 || p_cfg->ui8LookAheadDepth == 1)
12290 {
12291 ni_strncpy(p_param_err, max_err_len,
12292 "totalCuTreeDepth is invalid without lookahead",
12293 max_err_len - 1);
12295 LRETURN;
12296 }
12297
12298 if (p_cfg->ui8totalCuTreeDepth <= p_cfg->ui8LookAheadDepth)
12299 {
12300 ni_strncpy(p_param_warn, max_err_len, "totalCuTreeDepth does not take effects when its value <= lookahead depth", max_err_len - 1);
12301 warning = NI_RETCODE_PARAM_WARN;
12302 p_cfg->ui8totalCuTreeDepth = 0;
12303 }
12304 else
12305 {
12306 if (p_cfg->ui8multicoreJointMode != 0)
12307 {
12308 ni_strncpy(p_param_err, max_err_len,
12309 "totalCuTreeDepth is not supported in multicoreJointMode",
12310 max_err_len - 1);
12312 LRETURN;
12313 }
12314 }
12315
12316 if (p_cfg->ui8spatialLayersMinusOne > 0 && p_cfg->ui8totalCuTreeDepth)
12317 {
12318 ni_strncpy(p_param_err, max_err_len,
12319 "totalCuTreeDepth does not support multi spatial layers",
12320 max_err_len - 1);
12321 param_ret = NI_RETCODE_INVALID_PARAM;
12322 LRETURN;
12323 }
12324 }
12325
12326 if (p_cfg->ui8qpScaleEnable != 0)
12327 {
12328 if (p_cfg->ui8LookAheadDepth == 0 || p_cfg->ui8LookAheadDepth == 1)
12329 {
12330 ni_strncpy(p_param_err, max_err_len,
12331 "qpScaleEnable is invalid without lookahead",
12332 max_err_len - 1);
12334 LRETURN;
12335 }
12336
12337 if (p_cfg->i8crf < 0)
12338 {
12339 ni_strncpy(p_param_err, max_err_len,
12340 "qpScaleEnable is only supported in CRF or Capped CRF modes",
12341 max_err_len - 1);
12342 param_ret = NI_RETCODE_INVALID_PARAM;
12343 LRETURN;
12344 }
12345
12346 if (p_cfg->ui8adaptiveCrfMode != 0)
12347 {
12348 ni_strncpy(p_param_err, max_err_len,
12349 "adaptiveCrfMode is invalid when qpScaleEnable",
12350 max_err_len - 1);
12351 param_ret = NI_RETCODE_INVALID_PARAM;
12352 LRETURN;
12353 }
12354
12355 if (p_cfg->ui8spatialLayersMinusOne > 0)
12356 {
12357 ni_strncpy(p_param_err, max_err_len,
12358 "qpScaleEnable does not supported multi spatial layers",
12359 max_err_len - 1);
12360 param_ret = NI_RETCODE_INVALID_PARAM;
12361 LRETURN;
12362 }
12363 }
12364
12366 {
12367 // when gop_preset_index = -1 (default), gop pattern is decided by gopSize and gopLowdelay
12368 //p_cfg->ui8gopSize = 0;
12369 //p_cfg->ui8gopLowdelay = 0;
12370 }
12371 if (1 == p_cfg->niParamT408.gop_preset_index)
12372 {
12373 p_cfg->niParamT408.intra_period = 1;
12374 p_cfg->niParamT408.avcIdrPeriod = 1;
12375 p_cfg->ui8gopSize = 1;
12376 p_cfg->ui16gdrDuration = 0;
12377 }
12378 if (2 == p_cfg->niParamT408.gop_preset_index)
12379 {
12380 ni_strncpy(p_param_err, max_err_len,
12381 "gopPresetIdx 2 is obsolete, suggest to use gopPresetIdx 9 "
12382 "instead",
12383 max_err_len - 1);
12385 LRETURN;
12386 }
12387 if (3 == p_cfg->niParamT408.gop_preset_index)
12388 {
12389 p_cfg->ui8gopSize = 1;
12390 p_cfg->ui8gopLowdelay = 1;
12391 }
12392 if (4 == p_cfg->niParamT408.gop_preset_index)
12393 {
12394 p_cfg->ui8gopSize = 2;
12395 p_cfg->ui8gopLowdelay = 0;
12396 }
12397 if (5 == p_cfg->niParamT408.gop_preset_index)
12398 {
12399 p_cfg->ui8gopSize = 4;
12400 p_cfg->ui8gopLowdelay = 0;
12401 }
12402 if (6 == p_cfg->niParamT408.gop_preset_index)
12403 {
12404 ni_strncpy(p_param_err, max_err_len,
12405 "gopPresetIdx 6 is obsolete, suggest to use gopPresetIdx 7 "
12406 "instead",
12407 max_err_len - 1);
12409 LRETURN;
12410 }
12411 if (7 == p_cfg->niParamT408.gop_preset_index)
12412 {
12413 p_cfg->ui8gopSize = 4;
12414 p_cfg->ui8gopLowdelay = 1;
12415 }
12416 if (8 == p_cfg->niParamT408.gop_preset_index)
12417 {
12418 p_cfg->ui8gopSize = 8;
12419 p_cfg->ui8gopLowdelay = 0;
12420 }
12421 if (9 == p_cfg->niParamT408.gop_preset_index)
12422 {
12423 p_cfg->ui8gopSize = 1;
12424 p_cfg->ui8gopLowdelay = 0;
12425 }
12426 if (10 == p_cfg->niParamT408.gop_preset_index)
12427 {
12428 p_cfg->ui8gopSize = 4;
12429 p_cfg->ui8gopLowdelay = 0;
12430 }
12431 if (15 == p_cfg->niParamT408.gop_preset_index)
12432 {
12433 p_cfg->ui8gopSize = 16;
12434 p_cfg->ui8gopLowdelay = 0;
12435 }
12436
12437 if (p_cfg->ui8LookAheadDepth != 0
12438 || p_cfg->ui8bitrateMode == 1
12439 || p_cfg->ui32vbvMaxRate
12440 || p_cfg->ui32vbvMinRate
12441 || p_cfg->i8enableipRatio)
12442 {
12443 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");
12444 p_cfg->ui8NewRCEnable = 0;
12445 }
12446 else if (p_cfg->ui8NewRCEnable == 255)
12447 {
12448 if ((p_cfg->ui8gopSize > 1 || p_cfg->ui8gopSize == 0) && p_cfg->ui8gopLowdelay == 0)
12449 {
12450 ni_log2(p_ctx, NI_LOG_DEBUG, "Set newRcEnable to 0 in non low delay gop preset\n");
12451 p_cfg->ui8NewRCEnable = 0;
12452 }
12453 else if (p_cfg->i32spatialLayerBitrate[0] > 0)
12454 {
12455 ni_log2(p_ctx, NI_LOG_DEBUG, "Set newRcEnable to 0 in spatial layer separated rate control mode\n");
12456 p_cfg->ui8NewRCEnable = 0;
12457 }
12458 else if (p_cfg->niParamT408.intra_period == 1 || p_cfg->niParamT408.avcIdrPeriod == 1)
12459 {
12460 ni_log2(p_ctx, NI_LOG_DEBUG, "Set newRcEnable to 0 in intra only mode\n");
12461 p_cfg->ui8NewRCEnable = 0;
12462 }
12463 }
12464
12465 if ((p_cfg->ui8stillImageDetectLevel != 0 || p_cfg->ui8sceneChangeDetectLevel != 0) &&
12467 {
12468 ni_strncpy(p_param_warn, max_err_len, "StillImageDetect or SceneChangeDetect only support gopPresetIdx=9 with FW > 6rm\n", max_err_len - 1);
12469 warning = NI_RETCODE_PARAM_WARN;
12470 p_cfg->ui8stillImageDetectLevel = 0;
12471 p_cfg->ui8sceneChangeDetectLevel = 0;
12472 }
12473
12474 if (p_cfg->ui8spatialLayersMinusOne > 0 || p_cfg->i32spatialLayerBitrate[0] > 0)
12475 {
12477 {
12478 ni_strncpy(p_param_err, max_err_len,
12479 "currently do not support gop preset in multi spatial layers encode or spatial layer separated rate control mode",
12480 max_err_len - 1);
12482 LRETURN;
12483 }
12484 p_cfg->ui8gopSize = p_cfg->ui8spatialLayersMinusOne + 1;
12485 p_cfg->ui8gopLowdelay = 0;
12486 }
12487
12488 if (p_cfg->ui8spatialLayersRefBaseLayer != 0)
12489 {
12490 if (p_cfg->ui8spatialLayersMinusOne == 0)
12491 {
12492 ni_strncpy(p_param_err, max_err_len,
12493 "higher spatial layers referencing base layer is only supported in multi spatial layers encode",
12494 max_err_len - 1);
12496 LRETURN;
12497 }
12498 }
12499
12500 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
12501 {
12502 if (p_cfg->i32spatialLayerBitrate[i] == 0)
12503 {
12504 break;
12505 }
12506 }
12507 if (i > 0)
12508 {
12509 if (p_cfg->ui8spatialLayersMinusOne + 1 != i)
12510 {
12511 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);
12512 param_ret = NI_RETCODE_INVALID_PARAM;
12513 LRETURN;
12514 }
12515 if (p_cfg->ui8multicoreJointMode != 0)
12516 {
12519 "6sD") < 0)
12520 {
12521 ni_strncpy(p_param_err, max_err_len, "spatialLayerBitrate is not supported in multicoreJointMode for FW api version < 6sD", max_err_len - 1);
12523 LRETURN;
12524 }
12525 }
12526 }
12527
12528 for (i = 0; i < NI_MAX_SPATIAL_LAYERS; i++)
12529 {
12530 if (p_cfg->ui8av1OpLevel[i] == 0)
12531 {
12532 break;
12533 }
12534 else
12535 {
12536 if (NI_RETCODE_SUCCESS !=
12537 ni_check_level((int)p_cfg->ui8av1OpLevel[i], (int)p_ctx->codec_format, &level_index))
12538 {
12539 ni_strncpy(p_param_err, max_err_len, "Invalid av1OpLevel: out of range", max_err_len - 1);
12540 param_ret = NI_RETCODE_PARAM_ERROR_OOR;
12541 LRETURN;
12542 }
12543
12544 param_ret = ni_check_level_tier_compliance(
12545 p_cfg->ui8av1OpLevel[i], p_ctx, p_cfg, p_src, p_param_err, p_param_warn, max_err_len, &warning, level_index);
12546 if(param_ret != NI_RETCODE_SUCCESS)
12547 {
12548 LRETURN;
12549 }
12550 }
12551 }
12552 if (i > 0)
12553 {
12554 if (p_cfg->niParamT408.level != 0)
12555 {
12556 ni_strncpy(p_param_err, max_err_len, "av1OpLevel and level cannot be both specified", max_err_len - 1);
12557 param_ret = NI_RETCODE_INVALID_PARAM;
12558 LRETURN;
12559 }
12560
12561 if (p_cfg->ui8spatialLayersMinusOne + 1 != i)
12562 {
12563 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);
12564 param_ret = NI_RETCODE_INVALID_PARAM;
12565 LRETURN;
12566 }
12567 }
12568
12569 if (p_cfg->ui8crfMaxIframeEnable > 0)
12570 {
12571 if (p_cfg->i8crf < 0 || p_cfg->i32vbvBufferSize == 0 || p_cfg->ui8LookAheadDepth == 0)
12572 {
12573 ni_strncpy(p_param_err, max_err_len,
12574 "crfMaxIframeEnable is only supported in Capped CRF mode with lookahead enabled",
12575 max_err_len - 1);
12576 param_ret = NI_RETCODE_INVALID_PARAM;
12577 LRETURN;
12578 }
12579 }
12580 }
12581
12582 if (NI_CODEC_FORMAT_H264 == p_ctx->codec_format)
12583 {
12584 if (!QUADRA)
12585 {
12586 if (10 == p_ctx->src_bit_depth)
12587 {
12588 if (p_cfg->niParamT408.profile != 5)
12589 {
12590 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 5 (high10)",
12591 max_err_len - 1);
12592 param_ret = NI_RETCODE_INVALID_PARAM;
12593 LRETURN;
12594 }
12595 }
12596 else
12597 {
12598 if (p_cfg->niParamT408.profile < 1 || p_cfg->niParamT408.profile > 5)
12599 {
12600 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (baseline), 2 (main),"
12601 " 3 (extended), 4 (high), or 5 (high10)", max_err_len - 1);
12602 param_ret = NI_RETCODE_INVALID_PARAM;
12603 LRETURN;
12604 }
12605 }
12606 if (1 == p_cfg->niParamT408.profile &&
12607 ! (0 == p_cfg->niParamT408.gop_preset_index ||
12608 1 == p_cfg->niParamT408.gop_preset_index ||
12609 2 == p_cfg->niParamT408.gop_preset_index ||
12610 6 == p_cfg->niParamT408.gop_preset_index))
12611 {
12612 ni_strncpy(p_param_err, max_err_len, "Invalid gopPresetIdx for H.264 baseline profile:"
12613 " must be 1, 2, 6 or 0 (custom with no B frames)", max_err_len - 1);
12614 param_ret = NI_RETCODE_INVALID_PARAM;
12615 LRETURN;
12616 }
12617 if (1 == p_cfg->niParamT408.profile &&
12619 {
12620 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size;
12621 i++)
12622 {
12624 {
12625 ni_strncpy(p_param_err, max_err_len, "H.264 baseline profile: custom GOP can not "
12626 "have B frames", max_err_len - 1);
12627 param_ret = NI_RETCODE_INVALID_PARAM;
12628 LRETURN;
12629 }
12630 }
12631 }
12632 }
12633 else // QUADRA
12634 {
12635 if (p_cfg->niParamT408.profile < 1 || p_cfg->niParamT408.profile > 5 || p_cfg->niParamT408.profile == 3)
12636 {
12637 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (baseline), 2 (main),"
12638 " 4 (high), or 5 (high10)", max_err_len - 1);
12639 param_ret = NI_RETCODE_INVALID_PARAM;
12640 LRETURN;
12641 }
12642 if (10 == p_ctx->src_bit_depth && p_cfg->niParamT408.profile != 5)
12643 {
12644 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);
12645 warning = NI_RETCODE_PARAM_WARN;
12646 }
12647 if (1 == p_cfg->niParamT408.profile)
12648 {
12650 {
12651 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size; i++)
12652 {
12654 {
12655 ni_strncpy(p_param_err, max_err_len, "H.264 baseline profile: custom GOP can not "
12656 "have B frames", max_err_len - 1);
12657 param_ret = NI_RETCODE_INVALID_PARAM;
12658 LRETURN;
12659 }
12660 }
12661 } else if (((p_cfg->ui8gopSize != 1 || p_cfg->ui8gopLowdelay)) &&
12662 (p_cfg->niParamT408.intra_period != 1) &&
12664 {
12666 p_cfg->ui8gopSize != 0 ||
12667 p_cfg
12668 ->ui8gopLowdelay) // if gopSize is 0 (default / adapative gop), autoset to 1
12669 {
12670 ni_strncpy(p_param_err, max_err_len,
12671 "Must use gopPresetIdx 1,9,10 (no "
12672 "B frames) for profile 1",
12673 max_err_len - 1);
12674 param_ret = NI_RETCODE_INVALID_PARAM;
12675 LRETURN;
12676 }
12677 p_cfg->ui8gopSize = 1; //autoset to 1
12678 }
12679 }
12680 if (p_cfg->niParamT408.tier)
12681 {
12682 ni_strncpy(p_param_err, max_err_len, "Tier is not supported for H.264", max_err_len - 1);
12683 param_ret = NI_RETCODE_INVALID_PARAM;
12684 LRETURN;
12685 }
12686 if (p_cfg->ui8spatialLayersMinusOne > 0)
12687 {
12688 ni_strncpy(p_param_err, max_err_len,
12689 "spatialLayers is not supported for h.264 encode",
12690 max_err_len - 1);
12692 LRETURN;
12693 }
12694 if (p_cfg->ui8disableAv1TimingInfo != 0)
12695 {
12696 ni_strncpy(p_param_err, max_err_len, "disableAv1TimingInfo is not supported for h.264",
12697 max_err_len - 1);
12699 LRETURN;
12700 }
12701 if (p_cfg->ui8av1OpLevel[0] != 0)
12702 {
12703 ni_strncpy(p_param_err, max_err_len, "av1OpLevel is not supported for h.264",
12704 max_err_len - 1);
12706 LRETURN;
12707 }
12708 }
12709 }
12710 else if (NI_CODEC_FORMAT_H265 == p_ctx->codec_format)
12711 {
12712 if (!QUADRA)
12713 {
12714 if (10 == p_ctx->src_bit_depth)
12715 {
12716 if (p_cfg->niParamT408.profile != 2)
12717 {
12718 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 2 (main10)",
12719 max_err_len - 1);
12720 param_ret = NI_RETCODE_INVALID_PARAM;
12721 LRETURN;
12722 }
12723 }
12724 else
12725 {
12726 if (p_cfg->niParamT408.profile < 1 || p_cfg->niParamT408.profile > 2)
12727 {
12728 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (main) or 2 (main10)",
12729 max_err_len - 1);
12730 param_ret = NI_RETCODE_INVALID_PARAM;
12731 LRETURN;
12732 }
12733 }
12734 }
12735 else // QUADRA
12736 {
12737 if (p_cfg->niParamT408.profile < 1 || p_cfg->niParamT408.profile > 2)
12738 {
12739 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (main) or 2 (main10)",
12740 max_err_len - 1);
12741 param_ret = NI_RETCODE_INVALID_PARAM;
12742 LRETURN;
12743 }
12744 if (10 == p_ctx->src_bit_depth && p_cfg->niParamT408.profile != 2)
12745 {
12746 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);
12747 warning = NI_RETCODE_PARAM_WARN;
12748 }
12749 if (p_cfg->ui8spatialLayersMinusOne > 0)
12750 {
12751 ni_strncpy(p_param_err, max_err_len,
12752 "spatialLayers is not supported for h.265 encode",
12753 max_err_len - 1);
12755 LRETURN;
12756 }
12757 if (p_cfg->ui8disableAv1TimingInfo != 0)
12758 {
12759 ni_strncpy(p_param_err, max_err_len, "disableAv1TimingInfo is not supported for h.265",
12760 max_err_len - 1);
12762 LRETURN;
12763 }
12764 if (p_cfg->ui8av1OpLevel[0] != 0)
12765 {
12766 ni_strncpy(p_param_err, max_err_len, "av1OpLevel is not supported for h.265",
12767 max_err_len - 1);
12769 LRETURN;
12770 }
12771 if (p_enc->getBitstreamFeatures)
12772 {
12773 ni_strncpy(p_param_err, max_err_len, "getBitstreamFeatures is not supported for h.265 encoder",
12774 max_err_len - 1);
12776 LRETURN;
12777 }
12778 }
12779 } else if (NI_CODEC_FORMAT_AV1 == p_ctx->codec_format)
12780 {
12782 {
12783 ni_strncpy(p_param_err, max_err_len, "TuneBframeVisual MEDIUM is not supported for AV1", max_err_len - 1);
12784 param_ret = NI_RETCODE_INVALID_PARAM;
12785 LRETURN;
12786 }
12787 if (p_cfg->niParamT408.profile != 1)
12788 {
12789 ni_strncpy(p_param_err, max_err_len, "Invalid profile: must be 1 (main)",
12790 max_err_len - 1);
12791 param_ret = NI_RETCODE_INVALID_PARAM;
12792 LRETURN;
12793 }
12794 if (p_cfg->niParamT408.level) // 0 means auto level
12795 {
12796 if (p_cfg->niParamT408.level < 20)
12797 {
12798 p_cfg->niParamT408.level = 20;
12799 ni_strncpy(p_param_warn, max_err_len,
12800 "AV1 level < 2.0 is not supported, change to level 2.0",
12801 max_err_len - 1);
12802 warning = NI_RETCODE_PARAM_WARN;
12803 } else if (p_cfg->niParamT408.level > 63)
12804 {
12805 p_cfg->niParamT408.level = 63;
12806 ni_strncpy(p_param_warn, max_err_len,
12807 "AV1 level > 6.3 is not supported, change to level 6.3",
12808 max_err_len - 1);
12809 warning = NI_RETCODE_PARAM_WARN;
12810 }
12811 }
12812
12813 if (p_cfg->niParamT408.conf_win_top != 0)
12814 {
12816 0;
12817 ni_strncpy(p_param_warn, max_err_len, "confWinTop is not supported in AV1",
12818 max_err_len - 1);
12819 warning = NI_RETCODE_PARAM_WARN;
12820 }
12821 if (p_cfg->niParamT408.conf_win_bottom != 0)
12822 {
12825 ni_strncpy(p_param_warn, max_err_len, "confWinBottom is not supported in AV1",
12826 max_err_len - 1);
12827 warning = NI_RETCODE_PARAM_WARN;
12828 }
12829 if (p_cfg->niParamT408.conf_win_left != 0)
12830 {
12831 p_cfg->niParamT408.conf_win_left =
12832 p_src->cfg_enc_params.conf_win_left = 0;
12833 ni_strncpy(p_param_warn, max_err_len, "confWinLeft is not supported in AV1",
12834 max_err_len - 1);
12835 warning = NI_RETCODE_PARAM_WARN;
12836 }
12837 if (p_cfg->niParamT408.conf_win_right != 0)
12838 {
12840 p_src->cfg_enc_params.conf_win_right = 0;
12841 ni_strncpy(p_param_warn, max_err_len, "confWinRight is not supported in AV1",
12842 max_err_len - 1);
12843 warning = NI_RETCODE_PARAM_WARN;
12844 }
12845 if (p_cfg->ui8hrdEnable)
12846 {
12847 ni_strncpy(p_param_err, max_err_len, "hrdEnable is not supported on av1 encoder",
12848 max_err_len - 1);
12850 LRETURN;
12851 }
12852 if (p_cfg->ui8EnableAUD)
12853 {
12854 ni_strncpy(p_param_err, max_err_len, "enableAUD is not supported on av1 encoder",
12855 max_err_len - 1);
12857 LRETURN;
12858 }
12859 if (p_cfg->ui8repeatHeaders)
12860 {
12861 ni_strncpy(p_param_err, max_err_len, "repeatHeaders is not supported on av1 encoder",
12862 max_err_len - 1);
12863 warning = NI_RETCODE_PARAM_WARN;
12864 }
12865 if (p_cfg->ui8enableSSIM)
12866 {
12867 ni_strncpy(p_param_err, max_err_len, "enableSSIM is not supported on av1 encoder",
12868 max_err_len - 1);
12870 LRETURN;
12871 }
12872 if (p_cfg->ui8EnableRdoQuant)
12873 {
12874 ni_strncpy(p_param_err, max_err_len, "EnableRdoQuant is not supported on av1 encoder",
12875 max_err_len - 1);
12877 LRETURN;
12878 }
12879 if (p_cfg->ui8fillerEnable)
12880 {
12881 ni_strncpy(p_param_err, max_err_len, "fillerEnable is not supported on av1 encoder",
12882 max_err_len - 1);
12884 LRETURN;
12885 }
12886 if (p_cfg->i8ppsInitQp)
12887 {
12888 ni_strncpy(p_param_err, max_err_len, "ppsInitQp is not supported for av1 encoder",
12889 max_err_len - 1);
12891 LRETURN;
12892 }
12893 if (p_cfg->ui8vbvBufferReencode && p_cfg->ui8multicoreJointMode)
12894 {
12895 ni_strncpy(p_param_err, max_err_len, "vbvBufferReencode is not supported for av1 multicoreJointMode", max_err_len - 1);
12897 LRETURN;
12898 }
12899 if (p_enc->getBitstreamFeatures)
12900 {
12901 ni_strncpy(p_param_err, max_err_len, "getBitstreamFeatures is not supported for av1 encoder",
12902 max_err_len - 1);
12904 LRETURN;
12905 }
12906 } else if (NI_CODEC_FORMAT_JPEG == p_ctx->codec_format)
12907 {
12908 if (p_cfg->ui32cropWidth || p_cfg->ui32cropHeight || p_cfg->ui32horOffset || p_cfg->ui32verOffset)
12909 {
12910 ni_strncpy(p_param_err, max_err_len, "crop Parameters not supported for JPEG", max_err_len - 1);
12912 LRETURN;
12913 }
12914 if (p_cfg->niParamT408.tier)
12915 {
12916 ni_strncpy(p_param_err, max_err_len, "Tier is not supported for JPEG", max_err_len - 1);
12918 LRETURN;
12919 }
12920 if (p_cfg->ui8tuneBframeVisual)
12921 {
12922 ni_strncpy(p_param_err, max_err_len, "TuneBframeVisual is not supported for JPEG", max_err_len - 1);
12924 LRETURN;
12925 }
12926 if (p_cfg->ui8hdr10_enable)
12927 {
12928 ni_strncpy(p_param_err, max_err_len,
12929 "masterDisplay not supported for jpeg",
12930 max_err_len - 1);
12931 warning = NI_RETCODE_PARAM_WARN;
12932 }
12933 if (p_cfg->niParamT408.conf_win_top != 0)
12934 {
12935 ni_strncpy(p_param_err, max_err_len, "confWinTop is not supported in jpeg",
12936 max_err_len - 1);
12938 LRETURN;
12939 }
12940 if (p_cfg->niParamT408.conf_win_bottom != 0)
12941 {
12942 ni_strncpy(p_param_err, max_err_len, "confWinBottom is not supported in jpeg",
12943 max_err_len - 1);
12945 LRETURN;
12946 }
12947 if (p_cfg->niParamT408.conf_win_left != 0)
12948 {
12949 ni_strncpy(p_param_err, max_err_len, "confWinLeft is not supported in jpeg",
12950 max_err_len - 1);
12952 LRETURN;
12953 }
12954 if (p_cfg->niParamT408.conf_win_right != 0)
12955 {
12956 ni_strncpy(p_param_err, max_err_len, "confWinRight is not supported in jpeg",
12957 max_err_len - 1);
12959 LRETURN;
12960 }
12961 if (p_cfg->ui8hrdEnable)
12962 {
12963 ni_strncpy(p_param_err, max_err_len, "hrdEnable is not supported on jpeg encoder",
12964 max_err_len - 1);
12966 LRETURN;
12967 }
12968 if (p_cfg->ui8EnableAUD)
12969 {
12970 ni_strncpy(p_param_err, max_err_len, "enableAUD is not supported on jpeg encoder",
12971 max_err_len - 1);
12973 LRETURN;
12974 }
12975 if (p_cfg->ui8repeatHeaders)
12976 {
12977 ni_strncpy(p_param_err, max_err_len, "repeatHeaders is not supported on jpeg encoder",
12978 max_err_len - 1);
12980 LRETURN;
12981 }
12983 {
12984 ni_strncpy(p_param_err, max_err_len, "prefTRC is not supported on jpeg encoder",
12985 max_err_len - 1);
12987 LRETURN;
12988 }
12989 if (p_cfg->ui8HDR10CLLEnable)
12990 {
12991 ni_strncpy(p_param_err, max_err_len, "maxCLL is not supported on jpeg encoder",
12992 max_err_len - 1);
12994 LRETURN;
12995 }
12996 if (p_cfg->ui8colorPrimaries != 2)
12997 {
12998 ni_strncpy(p_param_err, max_err_len, "colorPri is not supported on jpeg encoder",
12999 max_err_len - 1);
13001 LRETURN;
13002 }
13003 if (p_cfg->ui8colorTrc != 2)
13004 {
13005 ni_strncpy(p_param_err, max_err_len, "colorTrc is not supported on jpeg encoder",
13006 max_err_len - 1);
13008 LRETURN;
13009 }
13010 if (p_cfg->ui8colorSpace != 2)
13011 {
13012 ni_strncpy(p_param_err, max_err_len, "colorSpc is not supported on jpeg encoder",
13013 max_err_len - 1);
13015 LRETURN;
13016 }
13017 if (p_src->sar_num)
13018 {
13019 ni_strncpy(p_param_err, max_err_len, "sarNum is not supported on jpeg encoder",
13020 max_err_len - 1);
13022 LRETURN;
13023 }
13024 if (p_src->sar_denom != 1)
13025 {
13026 ni_strncpy(p_param_err, max_err_len, "sarDenom is not supported on jpeg encoder",
13027 max_err_len - 1);
13029 LRETURN;
13030 }
13031 if (p_src->video_full_range_flag != -1)
13032 {
13033 ni_strncpy(p_param_err, max_err_len,
13034 "videoFullRangeFlag is not supported on jpeg encoder",
13035 max_err_len - 1);
13037 LRETURN;
13038 }
13039 if (p_cfg->ui8temporalLayersEnable)
13040 {
13041 ni_strncpy(p_param_err, max_err_len,
13042 "temporalLayersEnable is not supported on jpeg encoder",
13043 max_err_len - 1);
13045 LRETURN;
13046 }
13047 if (p_cfg->ui8spatialLayersMinusOne > 0)
13048 {
13049 ni_strncpy(p_param_err, max_err_len,
13050 "spatialLayers is not supported for jpeg encode",
13051 max_err_len - 1);
13053 LRETURN;
13054 }
13055 if (p_cfg->ui8LowDelay)
13056 {
13057 ni_strncpy(p_param_err, max_err_len, "LowDelay is not supported on jpeg encoder",
13058 max_err_len - 1);
13060 LRETURN;
13061 }
13062 if (p_cfg->ui8rdoLevel)
13063 {
13064 ni_strncpy(p_param_err, max_err_len, "rdoLevel is not supported on jpeg encoder",
13065 max_err_len - 1);
13067 LRETURN;
13068 }
13069 if (p_cfg->ui8EnableRdoQuant)
13070 {
13071 ni_strncpy(p_param_err, max_err_len, "EnableRdoQuant is not supported on jpeg encoder",
13072 max_err_len - 1);
13074 LRETURN;
13075 }
13076 if (p_cfg->ui8enable2PassGopPatern)
13077 {
13078 ni_strncpy(p_param_err, max_err_len,
13079 "enable2PassGop is not supported on jpeg encoder",
13080 max_err_len - 1);
13082 LRETURN;
13083 }
13084 if (p_cfg->ui8LookAheadDepth)
13085 {
13086 ni_strncpy(p_param_err, max_err_len,
13087 "lookAheadDepth is not supported on jpeg encoder",
13088 max_err_len - 1);
13090 LRETURN;
13091 }
13093 {
13094 ni_strncpy(p_param_err, max_err_len,
13095 "gopPresetIdx is not supported on jpeg encoder",
13096 max_err_len - 1);
13098 LRETURN;
13099 }
13100 if (p_cfg->niParamT408.roiEnable)
13101 {
13102 ni_strncpy(p_param_err, max_err_len, "roiEnable is not supported on jpeg encoder",
13103 max_err_len - 1);
13105 LRETURN;
13106 }
13107 if(p_src->roi_demo_mode)
13108 {
13109 ni_strncpy(p_param_err, max_err_len,
13110 "RoiDemoMode is not supported on jpeg encoder",
13111 max_err_len - 1);
13113 LRETURN;
13114 }
13115 if (p_src->cacheRoi)
13116 {
13117 ni_strncpy(p_param_err, max_err_len, "cacheRoi is not supported on jpeg encoder",
13118 max_err_len - 1);
13120 LRETURN;
13121 }
13123 {
13124 ni_strncpy(p_param_err, max_err_len,
13125 "ReconfDemoMode is not supported on jpeg encoder",
13126 max_err_len - 1);
13128 LRETURN;
13129 }
13130 if (p_cfg->niParamT408.intraRefreshMode)
13131 {
13132 ni_strncpy(p_param_err, max_err_len,
13133 "intraRefreshMode is not supported on jpeg encoder",
13134 max_err_len - 1);
13136 LRETURN;
13137 }
13138 if (p_cfg->niParamT408.intraRefreshArg)
13139 {
13140 ni_strncpy(p_param_err, max_err_len,
13141 "intraRefreshArg is not supported on jpeg encoder",
13142 max_err_len - 1);
13144 LRETURN;
13145 }
13146 if (p_cfg->niParamT408.intra_period != 120)
13147 {
13148 ni_strncpy(p_param_err, max_err_len,
13149 "intraPeriod is not supported on jpeg encoder",
13150 max_err_len - 1);
13152 LRETURN;
13153 }
13154 if (p_cfg->ui8intraResetRefresh)
13155 {
13156 ni_strncpy(
13157 p_param_err, max_err_len,
13158 "IntraRefreshResetOnForceIDR is not supported on jpeg encoder",
13159 max_err_len - 1);
13161 LRETURN;
13162 }
13163 if (p_cfg->niParamT408.useLongTerm)
13164 {
13165 ni_strncpy(p_param_err, max_err_len,
13166 "longTermReferenceEnable is not supported on jpeg encoder",
13167 max_err_len - 1);
13169 LRETURN;
13170 }
13171 if (p_cfg->ui32setLongTermInterval)
13172 {
13173 ni_strncpy(p_param_err, max_err_len,
13174 "longTermReferenceInterval is not supported on jpeg encoder",
13175 max_err_len - 1);
13177 LRETURN;
13178 }
13179 if (p_cfg->ui8setLongTermCount != 2)
13180 {
13181 ni_strncpy(p_param_err, max_err_len,
13182 "longTermReferenceCount is not supported on jpeg encoder",
13183 max_err_len - 1);
13185 LRETURN;
13186 }
13187 if (p_cfg->ui8multicoreJointMode)
13188 {
13189 ni_strncpy(p_param_err, max_err_len,
13190 "multicoreJointMode is not supported on jpeg encoder",
13191 max_err_len - 1);
13193 LRETURN;
13194 }
13195 if (p_cfg->ui8enableSSIM)
13196 {
13197 ni_strncpy(p_param_err, max_err_len, "enableSSIM is not supported on jpeg encoder",
13198 max_err_len - 1);
13200 LRETURN;
13201 }
13202 if (p_enc->rc.vbv_buffer_size != -1)
13203 {
13204 ni_strncpy(p_param_err, max_err_len,
13205 "vbvBufferSize is not supported on jpeg encoder",
13206 max_err_len - 1);
13208 LRETURN;
13209 }
13210 if (p_cfg->ui8fillerEnable)
13211 {
13212 ni_strncpy(p_param_err, max_err_len,
13213 "fillerEnable is not supported on jpeg encoder",
13214 max_err_len - 1);
13216 LRETURN;
13217 }
13218 if (p_cfg->ui8picSkipEnable)
13219 {
13220 ni_strncpy(p_param_err, max_err_len, "picSkip is not supported on jpeg encoder",
13221 max_err_len - 1);
13223 LRETURN;
13224 }
13225 if (p_cfg->ui16maxFrameSize)
13226 {
13227 ni_strncpy(p_param_err, max_err_len, "maxFrameSize is not supported on jpeg encoder",
13228 max_err_len - 1);
13230 LRETURN;
13231 }
13233 {
13234 ni_strncpy(p_param_err, max_err_len,
13235 "cuLevelRCEnable is not supported on jpeg encoder",
13236 max_err_len - 1);
13238 LRETURN;
13239 }
13240 if (p_cfg->niParamT408.enable_hvs_qp)
13241 {
13242 ni_strncpy(p_param_err, max_err_len, "hvsQPEnable is not supported on jpeg encoder",
13243 max_err_len - 1);
13245 LRETURN;
13246 }
13247 if (p_cfg->niParamT408.profile)
13248 {
13249 ni_strncpy(p_param_err, max_err_len, "profile is not supported on jpeg encoder",
13250 max_err_len - 1);
13252 LRETURN;
13253 }
13255 {
13256 ni_strncpy(p_param_err, max_err_len, "intraRefreshMode or intraRefreshArg is not supported on jpeg encoder",
13257 max_err_len - 1);
13259 LRETURN;
13260 }
13261 if (p_cfg->i8crf != -1)
13262 {
13263 ni_strncpy(p_param_err, max_err_len, "crf is not supported on jpeg encoder",
13264 max_err_len - 1);
13266 LRETURN;
13267 }
13268 if (p_cfg->i32tolCtbRcInter != (int32_t)(0.1 * 1000))
13269 {
13270 ni_strncpy(p_param_err, max_err_len, "tolCtbRcInter is not supported on jpeg encoder",
13271 max_err_len - 1);
13273 LRETURN;
13274 }
13275 if (p_cfg->i32tolCtbRcIntra != (int32_t)(0.1 * 1000))
13276 {
13277 ni_strncpy(p_param_err, max_err_len, "tolCtbRcIntra is not supported on jpeg encoder",
13278 max_err_len - 1);
13280 LRETURN;
13281 }
13282 if (p_cfg->ui8rcQpDeltaRange != 10)
13283 {
13284 ni_strncpy(p_param_err, max_err_len,
13285 "rcQpDeltaRange is not supported on jpeg encoder",
13286 max_err_len - 1);
13288 LRETURN;
13289 }
13290 if (p_cfg->i16bitrateWindow != -255)
13291 {
13292 ni_strncpy(p_param_err, max_err_len, "bitrateWindow is not supported on jpeg encoder",
13293 max_err_len - 1);
13295 LRETURN;
13296 }
13297 if (p_cfg->i16ctbRowQpStep)
13298 {
13299 ni_strncpy(p_param_err, max_err_len, "ctbRowQpStep is not supported on jpeg encoder",
13300 max_err_len - 1);
13302 LRETURN;
13303 }
13304 if (p_cfg->ui8AiEnhanceMode)
13305 {
13306 ni_strncpy(p_param_err, max_err_len,
13307 "enableAIEnhance is not supported on jpeg encoder",
13308 max_err_len - 1);
13310 LRETURN;
13311 }
13312 if (p_cfg->i8ppsInitQp)
13313 {
13314 ni_strncpy(p_param_err, max_err_len, "ppsInitQp is not supported for jpeg encoder",
13315 max_err_len - 1);
13317 LRETURN;
13318 }
13319 if (p_cfg->i8pass1Qp)
13320 {
13321 ni_strncpy(p_param_err, max_err_len, "pass1Qp is not supported for jpeg encoder",
13322 max_err_len - 1);
13324 LRETURN;
13325 }
13326 if (p_enc->bitrateMode != -1)
13327 {
13328 ni_strncpy(p_param_err, max_err_len, "bitrateMode is not supported for jpeg encoder",
13329 max_err_len - 1);
13331 LRETURN;
13332 }
13333 if (p_cfg->ui8vbvBufferReencode)
13334 {
13335 ni_strncpy(p_param_err, max_err_len,
13336 "vbvBufferReencode is not supported on jpeg encoder",
13337 max_err_len - 1);
13339 LRETURN;
13340 }
13341 if (p_enc->get_psnr_mode != 3)
13342 {
13343 ni_strncpy(p_param_err, max_err_len,
13344 "getPsnrMode or getReconstructedMode is not supported on jpeg encoder",
13345 max_err_len - 1);
13347 LRETURN;
13348 }
13349 if (p_cfg->ui8spatialLayersMinusOne > 0)
13350 {
13351 ni_strncpy(p_param_err, max_err_len,
13352 "spatialLayers is not supported for Jpeg encode",
13353 max_err_len - 1);
13355 LRETURN;
13356 }
13357 if (p_cfg->ui8disableAv1TimingInfo != 0)
13358 {
13359 ni_strncpy(p_param_err, max_err_len, "disableAv1TimingInfo is not supported for Jpeg",
13360 max_err_len - 1);
13362 LRETURN;
13363 }
13364 if (p_cfg->ui8av1OpLevel[0] != 0)
13365 {
13366 ni_strncpy(p_param_err, max_err_len, "av1OpLevel is not supported for Jpeg",
13367 max_err_len - 1);
13369 LRETURN;
13370 }
13371 if (p_enc->getBitstreamFeatures != 0)
13372 {
13373 ni_strncpy(p_param_err, max_err_len,
13374 "getBitstreamFeatures is not supported for jpeg encoder",
13375 max_err_len - 1);
13377 LRETURN;
13378 }
13379 }
13380
13381 if (p_src->force_frame_type != 0 && p_src->force_frame_type != 1)
13382 {
13383 ni_strncpy(p_param_err, max_err_len, "Invalid forceFrameType: out of range",
13384 max_err_len - 1);
13385 param_ret = NI_RETCODE_INVALID_PARAM;
13386 LRETURN;
13387 }
13388
13389 if (p_cfg->niParamT408.forcedHeaderEnable > 2)
13390 {
13391 ni_strncpy(p_param_err, max_err_len, "Invalid forcedHeaderEnable: out of range",
13392 max_err_len - 1);
13394 LRETURN;
13395 }
13396
13397 if (p_cfg->niParamT408.decoding_refresh_type < 0 ||
13399 {
13400 ni_strncpy(p_param_err, max_err_len, "Invalid decoding_refresh_type: out of range", max_err_len - 1);
13402 LRETURN;
13403 }
13404
13405 if (!QUADRA)
13406 {
13407 if (p_cfg->niParamT408.gop_preset_index < 0 ||
13408 p_cfg->niParamT408.gop_preset_index > 8)
13409 {
13410 ni_strcpy(p_param_err, max_err_len, "Invalid gop_preset_index: out of range");
13412 LRETURN;
13413 }
13414
13415 if (p_src->low_delay_mode && 1 != p_cfg->niParamT408.gop_preset_index &&
13416 2 != p_cfg->niParamT408.gop_preset_index &&
13417 3 != p_cfg->niParamT408.gop_preset_index &&
13418 6 != p_cfg->niParamT408.gop_preset_index &&
13419 7 != p_cfg->niParamT408.gop_preset_index &&
13420 !(0 == p_cfg->niParamT408.gop_preset_index &&
13422 {
13423 ni_strcpy(p_param_err, max_err_len, "GOP size must be 1 when lowDelay is enabled");
13425 LRETURN;
13426 }
13427 }
13428 else // QUADRA
13429 {
13430 if (p_cfg->ui8gopSize > 16)
13431 {
13432 ni_strncpy(p_param_err, max_err_len, "Invalid gopSize out of range", max_err_len - 1);
13434 LRETURN;
13435 }
13436
13437 if (p_cfg->ui8gopLowdelay &&
13438 p_cfg->ui8gopSize > 4)
13439 {
13440 ni_strncpy(p_param_err, max_err_len, "GOP size must be <= 4 for low delay GOP", max_err_len - 1);
13442 LRETURN;
13443 }
13444
13445 if (p_cfg->ui8LookAheadDepth)
13446 {
13447 if (p_cfg->ui8LookAheadDepth < 4 || p_cfg->ui8LookAheadDepth > 40)
13448 {
13449 ni_strncpy(p_param_err, max_err_len, "Invalid LookAheadDepth: out of range. <[4-40]>", max_err_len - 1);
13451 LRETURN;
13452 }
13453 if (p_cfg->ui8gopLowdelay)
13454 {
13455 ni_strncpy(p_param_err, max_err_len, "2-pass encode does not support low delay GOP", max_err_len - 1);
13457 LRETURN;
13458 }
13460 {
13461 ni_strncpy(p_param_err, max_err_len, "2-pass encode does not support tile4x4 format",
13462 max_err_len - 1);
13464 LRETURN;
13465 }
13466 if (p_cfg->ui8spatialLayersMinusOne > 0)
13467 {
13469 "6t8") < 0)
13470 {
13471 ni_strncpy(p_param_err, max_err_len, "lookahead encode with multi spatial layers is not supported on device with FW API version < 6t8", max_err_len - 1);
13473 LRETURN;
13474 }
13475 }
13476 }
13477
13478 if (p_src->low_delay_mode || p_cfg->ui8picSkipEnable)
13479 {
13481 {
13482 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size; i++)
13483 {
13484 if (p_cfg->niParamT408.custom_gop_params.pic_param[i].poc_offset != (i+1))
13485 {
13486 if (p_src->low_delay_mode)
13487 ni_strncpy(p_param_err, max_err_len, "Custom GOP must not include backward prediction when lowDelay is enabled", max_err_len - 1);
13488 else
13489 ni_strncpy(p_param_err, max_err_len, "Custom GOP must not include backward prediction when picSkip is enabled", max_err_len - 1);
13490 param_ret = NI_RETCODE_INVALID_PARAM;
13491 LRETURN;
13492 }
13493 }
13494 } else if (1 != p_cfg->ui8gopSize && !p_cfg->ui8gopLowdelay &&
13495 p_cfg->niParamT408.intra_period != 1 &&
13497 {
13498 if (p_src->low_delay_mode)
13499 {
13500 if (p_cfg->ui8spatialLayersMinusOne == 0)
13501 {
13502 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);
13504 LRETURN;
13505 }
13506 }
13507 else
13508 {
13509 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);
13511 LRETURN;
13512 }
13513 } else if ((p_cfg->ui8LookAheadDepth != 0) && (!p_cfg->ui8useLowDelayPocType))
13514 {
13515 if (p_src->low_delay_mode)
13516 ni_strncpy(p_param_err, max_err_len, "lookAheadDepth must be 0 when lowDelay is enabled", max_err_len - 1);
13517 else
13518 ni_strncpy(p_param_err, max_err_len, "lookAheadDepth must be 0 when picSkip is enabled", max_err_len - 1);
13519 param_ret = NI_RETCODE_INVALID_PARAM;
13520 LRETURN;
13521 }
13522
13523 if (p_cfg->ui8multicoreJointMode)
13524 {
13525 if (p_src->low_delay_mode)
13526 ni_strncpy(p_param_err, max_err_len,
13527 "Cannot use multicoreJointMode when lowDelay is enabled",
13528 max_err_len - 1);
13529 else
13530 ni_strncpy(p_param_err, max_err_len,
13531 "Cannot use multicoreJointMode when picSkip is enabled",
13532 max_err_len - 1);
13533 param_ret = NI_RETCODE_INVALID_PARAM;
13534 LRETURN;
13535 }
13536
13537 if (p_src->minFramesDelay)
13538 {
13539 if (p_src->low_delay_mode)
13540 ni_strncpy(p_param_err, max_err_len,
13541 "Cannot enable minFramesDelay when lowDelay is enabled",
13542 max_err_len - 1);
13543 else
13544 ni_strncpy(p_param_err, max_err_len,
13545 "Cannot enable minFramesDelay when picSkip is enabled",
13546 max_err_len - 1);
13547 param_ret = NI_RETCODE_INVALID_PARAM;
13548 LRETURN;
13549 }
13550 }
13551
13552 if (p_cfg->ui8spatialLayersMinusOne > 0)
13553 {
13554 int intra_period_in_frames = p_cfg->niParamT408.intra_period * (p_cfg->ui8spatialLayersMinusOne+1);
13555 p_cfg->niParamT408.intra_period = p_cfg->niParamT408.avcIdrPeriod = intra_period_in_frames;
13556 }
13557
13558 if (p_cfg->ui8useLowDelayPocType)
13559 {
13561 {
13562 ni_strncpy(p_param_err, max_err_len, "Custom GOP size must be 1 when useLowDelayPocType is enabled", max_err_len - 1);
13563 param_ret = NI_RETCODE_INVALID_PARAM;
13564 LRETURN;
13565 } else if (1 != p_cfg->ui8gopSize && !p_cfg->ui8gopLowdelay &&
13566 p_cfg->niParamT408.intra_period != 1)
13567 {
13568 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);
13570 LRETURN;
13571 }
13572 }
13573
13574 if (p_src->low_delay_mode)
13575 {
13576 // minimum acceptable value of maxFrameSize is bitrate / framerate in bytes
13577 uint32_t min_maxFrameSize = p_cfg->i32bitRate / p_cfg->i32frameRateInfo * p_cfg->i32frameRateDenominator / 8;
13578
13579 if (p_cfg->ui16maxFrameSize == 0)
13580 {
13581 if (p_enc->maxFrameSizeRatio > 0)
13582 {
13583 if (min_maxFrameSize * p_enc->maxFrameSizeRatio > NI_MAX_FRAME_SIZE)
13584 {
13585 p_cfg->ui16maxFrameSize = NI_MAX_FRAME_SIZE / 2000;
13586 } else
13587 {
13588 p_cfg->ui16maxFrameSize = min_maxFrameSize * p_enc->maxFrameSizeRatio / 2000;
13589 }
13590 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: Set maxFrameSize to %d times the "
13591 "minimum frame size %d bytes in low delay mode\n", __func__,
13592 p_enc->maxFrameSizeRatio, p_cfg->ui16maxFrameSize * 2000);
13593 } else
13594 {
13595 p_cfg->ui16maxFrameSize = ((p_src->source_width * p_src->source_height * 3 / 4) * p_ctx->bit_depth_factor) / 2000;
13596 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: maxFrameSize is not set in low delay "
13597 "mode. Set it to half of the maximum frame size %d bytes\n",
13598 __func__, p_cfg->ui16maxFrameSize*2000);
13599 }
13600 }
13601
13602 if (p_cfg->ui16maxFrameSize < min_maxFrameSize / 2000)
13603 {
13604 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: maxFrameSize %u is too small. Changed to minimum value (bitrate/framerate in byte): %u\n",
13605 __func__, p_cfg->ui16maxFrameSize*2000, min_maxFrameSize);
13606 p_cfg->ui16maxFrameSize = min_maxFrameSize / 2000;
13607 }
13608 }
13609 else
13610 {
13611 if (p_cfg->ui16maxFrameSize != 0 || p_enc->maxFrameSizeRatio > 0)
13612 {
13613 ni_strncpy(p_param_err, max_err_len, "maxFrameSize can only be used when lowDelay is enabled", max_err_len - 1);
13614 param_ret = NI_RETCODE_INVALID_PARAM;
13615 LRETURN;
13616 }
13617 }
13618 }
13619
13620 if (QUADRA)
13621 {
13622 if (p_cfg->ui16gdrDuration)
13623 {
13625 {
13626 for (i = 0; i < p_cfg->niParamT408.custom_gop_params.custom_gop_size; i++)
13627 {
13629 {
13630 ni_strncpy(p_param_err, max_err_len, "Custom GOP can not have B frames for intra refresh", max_err_len - 1);
13631 param_ret = NI_RETCODE_INVALID_PARAM;
13632 LRETURN;
13633 }
13634 }
13635 }
13636 else if (p_cfg->ui8gopSize != 1 || p_cfg->ui8gopLowdelay)
13637 {
13639 {
13640 ni_strncpy(p_param_err, max_err_len,
13641 "Must use gopPresetIdx 9 (consecutive P frame) for intra refresh",
13642 max_err_len - 1);
13643 param_ret = NI_RETCODE_INVALID_PARAM;
13644 LRETURN;
13645 }
13646 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);
13647 warning = NI_RETCODE_PARAM_WARN;
13648 p_cfg->ui8gopSize = 1;
13649 p_cfg->ui8gopLowdelay = 0;
13650 }
13651 if (p_cfg->ui16gdrDuration == 1)
13652 {
13653 ni_strncpy(p_param_err, max_err_len,
13654 "intra refresh cycle (height / intraRefreshArg MB or CTU) must > 1",
13655 max_err_len - 1);
13656 param_ret = NI_RETCODE_INVALID_PARAM;
13657 LRETURN;
13658 }
13659 if (p_cfg->ui8LookAheadDepth != 0)
13660 {
13661 ni_strncpy(p_param_err, max_err_len, "lookaheadDepth must be 0 for intra refresh", max_err_len - 1);
13662 param_ret = NI_RETCODE_INVALID_PARAM;
13663 LRETURN;
13664 }
13665 if (STD_HEVC == p_cfg->ui8bitstreamFormat ||
13666 STD_AV1 == p_cfg->ui8bitstreamFormat)
13667 {
13668 if (p_cfg->niParamT408.intra_period < p_cfg->ui16gdrDuration)
13669 {
13670 ni_strncpy(p_param_warn, max_err_len, "intraPeriod forced to match intra refersh cycle (intraPeriod must >= intra refersh cycle)", max_err_len - 1);
13671 warning = NI_RETCODE_PARAM_WARN;
13673 }
13674 }
13675 else if (STD_AVC == p_cfg->ui8bitstreamFormat)
13676 {
13677 if (p_cfg->niParamT408.avcIdrPeriod < p_cfg->ui16gdrDuration)
13678 {
13679 ni_strncpy(p_param_warn, max_err_len, "intraPeriod forced to match intra refersh cycle (intraPeriod must >= intra refersh cycle)", max_err_len - 1);
13680 warning = NI_RETCODE_PARAM_WARN;
13682 }
13683 }
13684 }
13685
13686 if (p_cfg->ui8multicoreJointMode)
13687 {
13688 if (p_cfg->ui8hrdEnable)
13689 {
13690 ni_strncpy(p_param_warn, max_err_len, "HRD conformance is not guaranteed in multicoreJointMode", max_err_len - 1);
13691 warning = NI_RETCODE_PARAM_WARN;
13692 }
13693 }
13694
13695 if (p_cfg->ui8temporalLayersEnable)
13696 {
13697 if (p_cfg->ui8hrdEnable)
13698 {
13699 (void)snprintf(p_param_err, max_err_len, "HRD conformance with multiple temporal layers is currently not supported");
13701 LRETURN;
13702 }
13703 }
13704
13705 // Capped CRF with filler enabled
13706 // keep rcEnable 0 when vbvBufferSize and vbvMinRate are both set
13707 int capped_crf_filler = 0;
13708 if (p_cfg->ui8fillerEnable &&
13709 p_cfg->i8crf >= 0 && p_cfg->i8crf <= 51)
13710 {
13713 "6t7") < 0)
13714 {
13715 ni_strncpy(p_param_err, max_err_len, "fillerEnable with crf is not supported on device with FW API version < 6t7", max_err_len - 1);
13717 LRETURN;
13718 }
13719
13720 if (p_cfg->i32vbvBufferSize != 0 && p_cfg->ui32vbvMinRate != 0)
13721 {
13722 capped_crf_filler = 1;
13723 }
13724 else
13725 {
13726 ni_strncpy(p_param_err, max_err_len,
13727 "fillerEnable with crf requires vbvBufferSize and vbvMinRate",
13728 max_err_len - 1);
13730 LRETURN;
13731 }
13732 }
13733
13734 if ((p_cfg->ui8hrdEnable) || (p_cfg->ui8fillerEnable && !capped_crf_filler))
13735 {
13736 // enable rate control
13737 if (p_cfg->ui8rcEnable == 0)
13738 {
13740 }
13741
13742 // enable hrd if it is off
13743 if (p_cfg->i32vbvBufferSize == 0)
13744 {
13745 p_cfg->i32vbvBufferSize = 3000;
13746 }
13747 }
13748
13749 // maxrate must >= bitrate
13750 if (p_cfg->ui32vbvMaxRate != 0)
13751 {
13752 if ((int)p_cfg->ui32vbvMaxRate < p_cfg->i32bitRate)
13753 {
13754 (void)snprintf(p_param_err, max_err_len, "vbvMaxRate %u cannot be smaller than bitrate %d",
13755 p_cfg->ui32vbvMaxRate, p_cfg->i32bitRate);
13757 LRETURN;
13758 }
13759 }
13760
13761 // minrate must <= bitrate
13762 if (p_cfg->ui32vbvMinRate != 0)
13763 {
13764 if ((int)p_cfg->ui32vbvMinRate > p_cfg->i32bitRate)
13765 {
13766 (void)snprintf(p_param_err, max_err_len, "vbvMinRate %u cannot be larger than bitrate %d",
13767 p_cfg->ui32vbvMinRate, p_cfg->i32bitRate);
13769 LRETURN;
13770 }
13771 }
13772
13773 // The supported range of vbvBufferSize are 0, or 1/framerate to 3000. If the vbvBufferSize is not 0.
13774 // The minimum vbvBufferSize in msec is 1/framerate. The actual minimum in bits is bitrate/framerate.
13775 if (p_cfg->i32vbvBufferSize != 0)
13776 {
13777 // check buffer size compatible to bitrate
13778 int32_t minVbvBufferSize = p_cfg->i32frameRateDenominator * 1000 / p_cfg->i32frameRateInfo;
13779 if (p_cfg->i32vbvBufferSize < minVbvBufferSize)
13780 {
13781 (void)snprintf(p_param_err, max_err_len, "vbvBufferSize must be greater than the average frame size. Minimum is %d msec for framerate %d fps",
13782 minVbvBufferSize, (p_cfg->i32frameRateInfo / p_cfg->i32frameRateDenominator));
13784 LRETURN;
13785 }
13786
13787 // check buffer size compatible to maxrate
13788 if (p_cfg->ui32vbvMaxRate != 0)
13789 {
13790 int32_t maxRateMinVbvBufferSize = (int32_t)(((int64_t)p_cfg->i32frameRateDenominator * 1000 / p_cfg->i32frameRateInfo) * p_cfg->ui32vbvMaxRate / p_cfg->i32bitRate);
13791 if (p_cfg->i32vbvBufferSize < maxRateMinVbvBufferSize)
13792 {
13793 (void)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",
13794 maxRateMinVbvBufferSize, p_cfg->i32bitRate, p_cfg->ui32vbvMaxRate, (p_cfg->i32frameRateInfo / p_cfg->i32frameRateDenominator));
13795 warning = NI_RETCODE_PARAM_WARN;
13796 p_cfg->i32vbvBufferSize = maxRateMinVbvBufferSize;
13797 }
13798 }
13799 // check buffer size compatible to minrate (capped CRF may set minrate without maxrate)
13800 else if (p_cfg->ui32vbvMinRate != 0)
13801 {
13802 int32_t minRateMinVbvBufferSize = (int32_t)(((int64_t)p_cfg->i32frameRateDenominator * 1000 / p_cfg->i32frameRateInfo) * p_cfg->ui32vbvMinRate / p_cfg->i32bitRate);
13803 if (p_cfg->i32vbvBufferSize < minRateMinVbvBufferSize)
13804 {
13805 (void)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",
13806 minRateMinVbvBufferSize, p_cfg->i32bitRate, p_cfg->ui32vbvMinRate, (p_cfg->i32frameRateInfo / p_cfg->i32frameRateDenominator));
13807 warning = NI_RETCODE_PARAM_WARN;
13808 p_cfg->i32vbvBufferSize = minRateMinVbvBufferSize;
13809 }
13810 }
13811 }
13812 else
13813 {
13814 // check buffer size compatible to maxrate and/or minrate
13815 if ( p_cfg->ui32vbvMaxRate != 0 || p_cfg->ui32vbvMinRate != 0 )
13816 {
13817 (void)snprintf(p_param_warn, max_err_len, "vbvMaxRate %u vbvMinRate %u does not take effect when vbvBufferSize is 0, force vbvMaxRate vbvMinRate to 0",
13818 p_cfg->ui32vbvMaxRate, p_cfg->ui32vbvMinRate);
13819 warning = NI_RETCODE_PARAM_WARN;
13820 p_cfg->ui32vbvMaxRate = 0;
13821 p_cfg->ui32vbvMinRate = 0;
13822 }
13823 }
13824
13825 if (p_cfg->ui32ltrRefInterval || p_cfg->niParamT408.useLongTerm)
13826 {
13827 if (p_cfg->ui32ltrRefInterval && p_cfg->niParamT408.useLongTerm)
13828 {
13829 ni_strncpy(p_param_err, max_err_len,
13830 "Can't enable ltrRefInterval and longTermReferenceEnable "
13831 "at same time",
13832 max_err_len - 1);
13833 param_ret = NI_RETCODE_INVALID_PARAM;
13834 LRETURN;
13835 }
13836
13838 {
13840 {
13841 ni_strncpy(p_param_err, max_err_len, "Custom GOP size can not be > 1 for long term reference", max_err_len - 1);
13842 param_ret = NI_RETCODE_INVALID_PARAM;
13843 LRETURN;
13844 }
13845 } else if ((p_cfg->ui8gopSize != 1) && (p_cfg->ui8gopLowdelay == 0) &&
13846 (p_cfg->niParamT408.intra_period != 1))
13847 {
13849 {
13850 ni_strncpy(p_param_err, max_err_len,
13851 "Must use low delay GOP (gopPresetIdx 1,3,7,9) for long term reference",
13852 max_err_len - 1);
13853 param_ret = NI_RETCODE_INVALID_PARAM;
13854 LRETURN;
13855 }
13856 ni_strncpy(p_param_warn, max_err_len, "GOP size forced to 1 for long term reference", max_err_len - 1);
13857 warning = NI_RETCODE_PARAM_WARN;
13858 p_cfg->ui8gopSize = 1;
13859 }
13860
13861 if (p_cfg->ui8LookAheadDepth != 0)
13862 {
13863 ni_strncpy(p_param_err, max_err_len, "lookaheadDepth must be 0 for long term reference", max_err_len - 1);
13864 param_ret = NI_RETCODE_INVALID_PARAM;
13865 LRETURN;
13866 }
13867 if (p_cfg->i8crf >= 0)
13868 {
13869 ni_strncpy(p_param_err, max_err_len, "crf must < 0 for long term reference", max_err_len - 1);
13870 param_ret = NI_RETCODE_INVALID_PARAM;
13871 LRETURN;
13872 }
13873 }
13874
13875 if (p_cfg->ui32setLongTermInterval && (p_cfg->niParamT408.useLongTerm == 0))
13876 {
13877 ni_strncpy(
13878 p_param_err, max_err_len,
13879 "Must set longTermReferenceEnable for longTermReferenceInterval",
13880 max_err_len - 1);
13881 param_ret = NI_RETCODE_INVALID_PARAM;
13882 LRETURN;
13883 }
13884
13885 if (p_cfg->ui8av1ErrResilientMode)
13886 {
13887 if (STD_AV1 != p_cfg->ui8bitstreamFormat)
13888 {
13889 ni_strncpy(p_param_warn, max_err_len, "AV1 err resilient mode forced to 0 when using other codecs", max_err_len - 1);
13890 warning = NI_RETCODE_PARAM_WARN;
13891 p_cfg->ui8av1ErrResilientMode = 0;
13892 }
13893 }
13894
13895 if (p_cfg->ui8motionConstrainedMode)
13896 {
13897 if (STD_HEVC != p_cfg->ui8bitstreamFormat)
13898 {
13899 ni_strncpy(p_param_warn, max_err_len, "Motion Constrained mode force disabled for codecs other than HEVC", max_err_len - 1);
13900 warning = NI_RETCODE_PARAM_WARN;
13901 p_cfg->ui8motionConstrainedMode = 0;
13902 }
13903 else
13904 {
13905 if (p_cfg->ui8motionConstrainedMode >=
13907 {
13910 "6t3") < 0)
13911 {
13912 (void)snprintf(
13913 p_param_err, max_err_len,
13914 "motionConstrainedMode 3 is not supported on device with FW API version < 6t3");
13916 LRETURN;
13917 }
13918 }
13919
13920 if (p_cfg->ui8rdoLevel != 1)
13921 {
13922 ni_strncpy(
13923 p_param_err, max_err_len,
13924 "rdoLevel must be 1 for Motion Constrained mode 1, 2, or 3",
13925 max_err_len - 1);
13926 param_ret = NI_RETCODE_INVALID_PARAM;
13927 LRETURN;
13928 }
13929
13931 {
13932 if (p_cfg->ui8multicoreJointMode)
13933 {
13934 ni_strncpy(
13935 p_param_err, max_err_len,
13936 "multicoreJointMode must be 0 for Motion Constrained mode 2 or 3",
13937 max_err_len - 1);
13938 param_ret = NI_RETCODE_INVALID_PARAM;
13939 LRETURN;
13940 }
13941 if (p_src->source_width % 64 || p_src->source_height % 64)
13942 {
13943 if (!p_cfg->ui32cropWidth || !p_cfg->ui32cropHeight ||
13944 p_cfg->ui32cropWidth % 64 || p_cfg->ui32cropHeight % 64)
13945 {
13946 ni_strncpy(
13947 p_param_err, max_err_len,
13948 "input resolution (or cropping window) must be 64x64 aligned "
13949 "for Motion Constrained mode 2 or 3",
13950 max_err_len - 1);
13951 param_ret = NI_RETCODE_INVALID_PARAM;
13952 LRETURN;
13953 }
13954 }
13955 }
13956 }
13957 }
13958
13959 if (p_cfg->ui8avccHvcc)
13960 {
13961 if ((STD_AVC != p_cfg->ui8bitstreamFormat) && (STD_HEVC != p_cfg->ui8bitstreamFormat))
13962 {
13963 ni_strncpy(p_param_warn, max_err_len, "AVCC HVCC forced to 0 for codecs other than AVC HEVC", max_err_len - 1);
13964 warning = NI_RETCODE_PARAM_WARN;
13965 p_cfg->ui8avccHvcc = 0;
13966 }
13967 }
13968
13969 if (p_enc->getBitstreamFeatures)
13970 {
13971 if(1 != p_cfg->niParamT408.gop_preset_index &&
13972 3 != p_cfg->niParamT408.gop_preset_index &&
13973 7 != p_cfg->niParamT408.gop_preset_index &&
13974 9 != p_cfg->niParamT408.gop_preset_index)
13975 {
13976 ni_strncpy(p_param_err, max_err_len,
13977 "getBitstreamFeatures is only supported for gopPresetIndex 1, 3, 7, 9",
13978 max_err_len - 1);
13980 LRETURN;
13981 }
13982
13983 if (p_cfg->ui32cropWidth || p_cfg->ui32cropHeight)
13984 {
13985 ni_strncpy(p_param_err, max_err_len,
13986 "getBitstreamFeatures is not supported when Crop Width > 0 || Crop Height > 0",
13987 max_err_len - 1);
13988 param_ret = NI_RETCODE_INVALID_PARAM;
13989 LRETURN;
13990 }
13991
13994 "6sM") < 0)
13995 {
13996 ni_strncpy(p_param_err, max_err_len,
13997 "getBitstreamFeatures is not supported in FW API version < 6sM\n",
13998 max_err_len - 1);
13999 param_ret = NI_RETCODE_INVALID_PARAM;
14000 LRETURN;
14001 }
14002 }
14003 }
14004
14005 if (p_cfg->niParamT408.cu_size_mode < 0 ||
14006 p_cfg->niParamT408.cu_size_mode > 7)
14007 {
14008 ni_strncpy(p_param_err, max_err_len, "Invalid cu_size_mode: out of range", max_err_len - 1);
14010 LRETURN;
14011 }
14012
14013
14014
14015 if (p_cfg->niParamT408.use_recommend_enc_params < 0 ||
14017 {
14018 ni_strncpy(p_param_err, max_err_len, "Invalid use_recommend_enc_params: out of range", max_err_len - 1);
14020 LRETURN;
14021 }
14022
14024 {
14025 case 0:
14026 case 2:
14027 case 3:
14028 {
14029 if (p_cfg->niParamT408.use_recommend_enc_params != 3)
14030 {
14031 // in FAST mode (recommendEncParam==3), max_num_merge value will be
14032 // decided in FW
14033 if (p_cfg->niParamT408.max_num_merge < 0 ||
14034 p_cfg->niParamT408.max_num_merge > 3)
14035 {
14036 ni_strncpy(p_param_err, max_err_len, "Invalid max_num_merge: out of range", max_err_len - 1);
14038 LRETURN;
14039 }
14040 }
14041 break;
14042 }
14043
14044 default: break;
14045 }
14046
14047 if ( p_cfg->niParamT408.intra_qp < -1 ||
14048 p_cfg->niParamT408.intra_qp > 51 )
14049 {
14050 ni_strncpy(p_param_err, max_err_len, "Invalid intra_qp: out of range", max_err_len - 1);
14052 LRETURN;
14053 }
14054
14055 if (QUADRA)
14056 {
14057 if (p_cfg->i8crf >= 0 && p_cfg->i8crf <= 51)
14058 {
14059 if (p_cfg->ui8LookAheadDepth < 4 || p_cfg->ui8LookAheadDepth > 40)
14060 {
14062 "6X") < 0)
14063 {
14064 ni_strncpy(p_param_err, max_err_len, "CRF requres LookAheadDepth <[4-40]>", max_err_len - 1);
14066 LRETURN;
14067 }
14068 else
14069 {
14070 p_cfg->ui8LookAheadDepth = 1;
14071 p_cfg->ui8noMbtree = 1;
14072 ni_strncpy(p_param_warn, max_err_len, "enable lookahead of current frame", max_err_len - 1);
14073 warning = NI_RETCODE_PARAM_WARN;
14074 }
14075 }
14076
14077 if (p_cfg->ui8rcEnable == 1)
14078 {
14079 ni_strncpy(p_param_err, max_err_len, "CRF requires RcEnable 0", max_err_len - 1);
14081 LRETURN;
14082 }
14083 #if 0
14084 if (p_cfg->ui8ctbRcMode > 0)
14085 {
14086 ni_strncpy(p_param_warn, sizeof(p_param_warn), "Lookahead with cuLevelRCEnable or hvsQPEnable may degrade quality", max_err_len - 1);
14087 warning = NI_RETCODE_PARAM_WARN;
14088 //LRETURN;
14089 }
14090 #endif
14091 }
14092
14094 {
14095 if (p_cfg->ui8LookAheadDepth == 0)
14096 {
14097 ni_strncpy(p_param_err, max_err_len, "tuneBframeVisual level 1 (medium) requires lookahead or crf encode", max_err_len - 1);
14099 LRETURN;
14100 }
14101 }
14102 }
14103
14104 if ( p_cfg->niParamT408.enable_mb_level_rc != 1 &&
14105 p_cfg->niParamT408.enable_mb_level_rc != 0 )
14106 {
14107 ni_strncpy(p_param_err, max_err_len, "Invalid enable_mb_level_rc: out of range", max_err_len - 1);
14109 LRETURN;
14110 }
14111
14112 {
14113 if ( p_cfg->niParamT408.minQpI < 0 ||
14114 p_cfg->niParamT408.minQpI > 51 )
14115 {
14116 ni_strncpy(p_param_err, max_err_len, "Invalid min_qp: out of range", max_err_len - 1);
14117 param_ret = NI_RETCODE_PARAM_ERROR_MN_QP;
14118 LRETURN;
14119 }
14120
14121 if ( p_cfg->niParamT408.maxQpI < 0 ||
14122 p_cfg->niParamT408.maxQpI > 51 )
14123 {
14124 ni_strncpy(p_param_err, max_err_len, "Invalid max_qp: out of range", max_err_len - 1);
14125 param_ret = NI_RETCODE_PARAM_ERROR_MX_QP;
14126 LRETURN;
14127 }
14128
14129 if ( p_cfg->niParamT408.enable_cu_level_rate_control != 1 &&
14131 {
14132 ni_strncpy(p_param_err, max_err_len, "Invalid enable_cu_level_rate_control: out of range", max_err_len - 1);
14134 LRETURN;
14135 }
14136
14137 //if (p_cfg->niParamT408.enable_cu_level_rate_control == 1)
14138 {
14139 if ( p_cfg->niParamT408.enable_hvs_qp != 1 &&
14140 p_cfg->niParamT408.enable_hvs_qp != 0 )
14141 {
14142 ni_strncpy(p_param_err, max_err_len, "Invalid enable_hvs_qp: out of range", max_err_len - 1);
14144 LRETURN;
14145 }
14146
14147 if (p_cfg->niParamT408.enable_hvs_qp)
14148 {
14149 if ( p_cfg->niParamT408.max_delta_qp < 0 ||
14150 p_cfg->niParamT408.max_delta_qp > 51 )
14151 {
14152 ni_strncpy(p_param_err, max_err_len, "Invalid max_delta_qp: out of range", max_err_len - 1);
14154 LRETURN;
14155 }
14156 }
14157 }
14158 // hrd is off when i32vbvBufferSize is 0
14159 if ((p_cfg->i32vbvBufferSize < 10 && p_cfg->i32vbvBufferSize != 0) || p_cfg->i32vbvBufferSize > 3000)
14160 {
14161 ni_strncpy(p_param_err, max_err_len, "Invalid i32vbvBufferSize: out of range", max_err_len - 1);
14163 LRETURN;
14164 }
14165 }
14166
14167 // check valid for common param
14168 param_ret = ni_check_common_params(&p_cfg->niParamT408, p_src, p_param_err, max_err_len - 1);
14169 if (param_ret != NI_RETCODE_SUCCESS)
14170 {
14171 LRETURN;
14172 }
14173
14174 // check valid for RC param
14175 param_ret = ni_check_ratecontrol_params(p_cfg, p_param_err, max_err_len - 1);
14176 if (param_ret != NI_RETCODE_SUCCESS)
14177 {
14178 LRETURN;
14179 }
14180
14181 if (warning == NI_RETCODE_PARAM_WARN && param_ret == NI_RETCODE_SUCCESS)
14182 {
14183 param_ret = NI_RETCODE_PARAM_WARN;
14184 ni_strncpy(p_param_err, max_err_len, p_param_warn, max_err_len - 1);
14185 }
14186
14187END:
14188 free(p_param_warn);
14189 return param_ret;
14190}
14191
14193 ni_xcoder_params_t *p_src,
14194 char *p_param_err, uint32_t max_err_len)
14195{
14197 int32_t low_delay = 0;
14198 int32_t intra_period_gop_step_size;
14199 int32_t i, j;
14200
14201 if (!p_param || !p_src || !p_param_err)
14202 {
14203 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
14204 __func__);
14206 LRETURN;
14207 }
14208
14209 //Zero out the error buffer
14210 memset(p_param_err, 0, max_err_len - 1);
14211
14212 // check low-delay gop structure
14213 if (!QUADRA)
14214 {
14215 if (0 == p_param->gop_preset_index) // common gop
14216 {
14217 if (p_param->custom_gop_params.custom_gop_size > 1)
14218 {
14219 int minVal = p_param->custom_gop_params.pic_param[0].poc_offset;
14220 low_delay = 1;
14221 for (i = 1; i < p_param->custom_gop_params.custom_gop_size; i++)
14222 {
14223 if (minVal > p_param->custom_gop_params.pic_param[i].poc_offset)
14224 {
14225 low_delay = 0;
14226 break;
14227 } else
14228 {
14229 minVal = p_param->custom_gop_params.pic_param[i].poc_offset;
14230 }
14231 }
14232 }
14233 }
14234 else if (p_param->gop_preset_index == 2 ||
14235 p_param->gop_preset_index == 3 ||
14236 p_param->gop_preset_index == 6 ||
14237 p_param->gop_preset_index == 7) // low-delay case (IPPP, IBBB)
14238 {
14239 low_delay = 1;
14240 }
14241
14242 if (low_delay)
14243 {
14244 intra_period_gop_step_size = 1;
14245 }
14246 else
14247 {
14249 {
14250 intra_period_gop_step_size = p_param->custom_gop_params.custom_gop_size;
14251 }
14252 else
14253 {
14254 intra_period_gop_step_size = (int32_t)presetGopSize[p_param->gop_preset_index];
14255 }
14256 }
14257
14258 if (((p_param->intra_period != 0) && ((p_param->intra_period < intra_period_gop_step_size+1) == 1)) ||
14259 ((p_param->avcIdrPeriod != 0) && ((p_param->avcIdrPeriod < intra_period_gop_step_size+1) == 1)))
14260 {
14261 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);
14263 LRETURN;
14264 }
14265
14266 if (((!low_delay) && (p_param->intra_period != 0) && ((p_param->intra_period % intra_period_gop_step_size) != 0)) ||
14267 ((!low_delay) && (p_param->avcIdrPeriod != 0) && ((p_param->avcIdrPeriod % intra_period_gop_step_size) != 0)))
14268 {
14269 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);
14271 LRETURN;
14272 }
14273
14275 {
14276 int temp_poc[NI_MAX_GOP_NUM];
14277 int min_poc = p_param->custom_gop_params.pic_param[0].poc_offset;
14278 for (i = 0; i < p_param->custom_gop_params.custom_gop_size; i++)
14279 {
14281 {
14282 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: temporal_id larger than 7", max_err_len - 1);
14284 LRETURN;
14285 }
14286
14287 if (p_param->custom_gop_params.pic_param[i].temporal_id < 0)
14288 {
14289 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: temporal_id is zero or negative", max_err_len - 1);
14291 LRETURN;
14292 }
14293 temp_poc[i] = p_param->custom_gop_params.pic_param[i].poc_offset;
14294 if (min_poc > temp_poc[i])
14295 {
14296 min_poc = temp_poc[i];
14297 }
14298 }
14299 int count_pos = 0;
14300 for (i = 0; i < p_param->custom_gop_params.custom_gop_size; i++)
14301 {
14302 for (j = 0; j < p_param->custom_gop_params.custom_gop_size; j++)
14303 {
14304 if (temp_poc[j] == min_poc)
14305 {
14306 count_pos++;
14307 min_poc++;
14308 }
14309 }
14310 }
14311 if (count_pos != p_param->custom_gop_params.custom_gop_size)
14312 {
14313 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: poc_offset is invalid", max_err_len - 1);
14315 LRETURN;
14316 }
14317 }
14318 }
14319 else // QUADRA
14320 {
14322 {
14323 int temp_poc[NI_MAX_GOP_NUM];
14324 int min_poc = p_param->custom_gop_params.pic_param[0].poc_offset;
14325 for (i = 0; i < p_param->custom_gop_params.custom_gop_size; i++)
14326 {
14328 {
14329 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: temporal_id larger than 7", max_err_len - 1);
14331 LRETURN;
14332 }
14333
14334 if (p_param->custom_gop_params.pic_param[i].temporal_id < 0)
14335 {
14336 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: temporal_id is negative", max_err_len - 1);
14338 LRETURN;
14339 }
14340
14341 for (j = 0; j < p_param->custom_gop_params.pic_param[i].num_ref_pics; j++)
14342 {
14343 if (p_param->custom_gop_params.pic_param[i].rps[j].ref_pic == 0)
14344 {
14345 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: ref pic delta cannot be 0", max_err_len - 1);
14347 LRETURN;
14348 }
14349 }
14350
14351 for (j = 0; j < NI_MAX_REF_PIC; j++)
14352 {
14353 if (p_param->custom_gop_params.pic_param[i].rps[j].ref_pic != 0 &&
14354 p_param->custom_gop_params.pic_param[i].rps[j].ref_pic_used == -1)
14355 {
14356 ni_log(NI_LOG_ERROR,"g%drefPic%d specified without g%drefPic%dUsed specified!\n", i, j, i, j);
14358 LRETURN;
14359 }
14360 }
14361
14362 temp_poc[i] = p_param->custom_gop_params.pic_param[i].poc_offset;
14363 if (min_poc > temp_poc[i])
14364 {
14365 min_poc = temp_poc[i];
14366 }
14367 }
14368 int count_pos = 0;
14369 for (i = 0; i < p_param->custom_gop_params.custom_gop_size; i++)
14370 {
14371 for (j = 0; j < p_param->custom_gop_params.custom_gop_size; j++)
14372 {
14373 if (temp_poc[j] == min_poc)
14374 {
14375 count_pos++;
14376 min_poc++;
14377 }
14378 }
14379 }
14380 if (count_pos != p_param->custom_gop_params.custom_gop_size)
14381 {
14382 ni_strncpy(p_param_err, max_err_len, "Invalid custom gop parameters: poc_offset is invalid", max_err_len - 1);
14384 LRETURN;
14385 }
14386 }
14387 }
14388
14389 if (0 == p_param->use_recommend_enc_params)
14390 {
14391 // RDO
14392 {
14393 int align_32_width_flag = p_src->source_width % 32;
14394 int align_16_width_flag = p_src->source_width % 16;
14395 int align_8_width_flag = p_src->source_width % 8;
14396 int align_32_height_flag = p_src->source_height % 32;
14397 int align_16_height_flag = p_src->source_height % 16;
14398 int align_8_height_flag = p_src->source_height % 8;
14399
14400 if (((p_param->cu_size_mode & 0x1) == 0) && ((align_8_width_flag != 0) || (align_8_height_flag != 0)))
14401 {
14402 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);
14404 LRETURN;
14405 }
14406 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)))
14407 {
14408 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);
14410 LRETURN;
14411 }
14412 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)))
14413 {
14414 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);
14416 LRETURN;
14417 }
14418 }
14419 }
14420
14421 if ((p_param->conf_win_top < 0) || (p_param->conf_win_top > 8192))
14422 {
14423 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_top: out of range", max_err_len - 1);
14425 LRETURN;
14426 }
14427 if (p_param->conf_win_top % 2)
14428 {
14429 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_top: not multiple of 2", max_err_len - 1);
14431 LRETURN;
14432 }
14433
14434 if ((p_param->conf_win_bottom < 0) || (p_param->conf_win_bottom > 8192))
14435 {
14436 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_bottom: out of range", max_err_len - 1);
14438 LRETURN;
14439 }
14440 if (p_param->conf_win_bottom % 2)
14441 {
14442 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_bottom: not multiple of 2", max_err_len - 1);
14444 LRETURN;
14445 }
14446
14447 if ((p_param->conf_win_left < 0) || (p_param->conf_win_left > 8192))
14448 {
14449 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_left: out of range", max_err_len - 1);
14451 LRETURN;
14452 }
14453 if (p_param->conf_win_left % 2)
14454 {
14455 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_left: not multiple of 2", max_err_len - 1);
14457 LRETURN;
14458 }
14459
14460 if (p_param->conf_win_right < 0 || p_param->conf_win_right > 8192)
14461 {
14462 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_right: out of range", max_err_len - 1);
14464 LRETURN;
14465 }
14466 if (p_param->conf_win_right % 2)
14467 {
14468 ni_strncpy(p_param_err, max_err_len, "Invalid conf_win_right: not multiple of 2", max_err_len - 1);
14470 }
14471
14472END:
14473
14474 return ret;
14475}
14476
14477ni_retcode_t ni_check_ratecontrol_params(ni_encoder_config_t* p_cfg, char* p_param_err, uint32_t max_err_len)
14478{
14480 ni_t408_config_t* p_param = NULL;
14481
14482 if( (!p_cfg) || (!p_param_err) )
14483 {
14484 ni_log(NI_LOG_ERROR, "ERROR: %s() Null pointer parameters passed\n",
14485 __func__);
14487 LRETURN;
14488 }
14489 p_param = &p_cfg->niParamT408;
14490
14491 //Zero out the error buffer
14492 memset(p_param_err, 0, max_err_len - 1);
14493
14494 if (p_param->roiEnable != 0 && p_param->roiEnable != 1)
14495 {
14496 ni_strncpy(p_param_err, max_err_len, "Invalid roiEnable: out of range", max_err_len - 1);
14498 LRETURN;
14499 }
14500
14501 if (p_param->roiEnable && p_param->enable_hvs_qp)
14502 {
14503 ni_strncpy(p_param_err, max_err_len, "hvsQPEnable and roiEnable: not mutually exclusive", max_err_len - 1);
14505 LRETURN;
14506 }
14507
14508 if (p_cfg->ui8rcEnable == 1)
14509 {
14510 if (p_param->minQpP > p_param->maxQpP || p_param->minQpB > p_param->maxQpB)
14511 {
14512 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);
14514 LRETURN;
14515 }
14516 }
14517
14518END:
14519
14520 return ret;
14521}
14522
14523
14524/*!******************************************************************************
14525 * \brief Print xcoder user configurations
14526 *
14527 * \param
14528 *
14529 * \return
14530 *******************************************************************************/
14531void ni_params_print(ni_xcoder_params_t *const p_encoder_params)
14532{
14533 if (!p_encoder_params)
14534 {
14535 return;
14536 }
14537
14538 ni_encoder_cfg_params_t *p_enc = &p_encoder_params->cfg_enc_params;
14539
14540 ni_log(NI_LOG_DEBUG, "XCoder Params:\n");
14541
14542 ni_log(NI_LOG_DEBUG, "preset=%d\n", p_encoder_params->preset);
14543 ni_log(NI_LOG_DEBUG, "fps_number / fps_denominator=%u / %u\n",
14544 p_encoder_params->fps_number,
14545 p_encoder_params->fps_denominator);
14546
14547 ni_log(NI_LOG_DEBUG, "source_width x source_height=%dx%d\n", p_encoder_params->source_width, p_encoder_params->source_height);
14548 ni_log(NI_LOG_DEBUG, "bitrate=%d\n", p_encoder_params->bitrate);
14549
14550 ni_log(NI_LOG_DEBUG, "profile=%d\n", p_enc->profile);
14551 ni_log(NI_LOG_DEBUG, "level_idc=%d\n", p_enc->level_idc);
14552 ni_log(NI_LOG_DEBUG, "high_tier=%d\n", p_enc->high_tier);
14553
14554 ni_log(NI_LOG_DEBUG, "frame_rate=%d\n", p_enc->frame_rate);
14555
14556 ni_log(NI_LOG_DEBUG, "use_recommend_enc_params=%d\n", p_enc->use_recommend_enc_params);
14557 ni_log(NI_LOG_DEBUG, "cu_size_mode=%d\n", p_enc->cu_size_mode);
14558 ni_log(NI_LOG_DEBUG, "max_num_merge=%d\n", p_enc->max_num_merge);
14559 ni_log(NI_LOG_DEBUG, "enable_dynamic_8x8_merge=%d\n", p_enc->enable_dynamic_8x8_merge);
14560 ni_log(NI_LOG_DEBUG, "enable_dynamic_16x16_merge=%d\n", p_enc->enable_dynamic_16x16_merge);
14561 ni_log(NI_LOG_DEBUG, "enable_dynamic_32x32_merge=%d\n", p_enc->enable_dynamic_32x32_merge);
14562 // trans_rate not available in Rev B
14563 ni_log(NI_LOG_DEBUG, "enable_rate_control=%d\n", p_enc->rc.enable_rate_control);
14564 ni_log(NI_LOG_DEBUG, "enable_cu_level_rate_control=%d\n", p_enc->rc.enable_cu_level_rate_control);
14565 ni_log(NI_LOG_DEBUG, "enable_hvs_qp=%d\n", p_enc->rc.enable_hvs_qp);
14566 ni_log(NI_LOG_DEBUG, "enable_hvs_qp_scale=%d\n", p_enc->rc.enable_hvs_qp_scale);
14567 ni_log(NI_LOG_DEBUG, "hvs_qp_scale=%d\n", p_enc->rc.hvs_qp_scale);
14568 ni_log(NI_LOG_DEBUG, "min_qp=%d\n", p_enc->rc.min_qp);
14569 ni_log(NI_LOG_DEBUG, "max_qp=%d\n", p_enc->rc.max_qp);
14570 ni_log(NI_LOG_DEBUG, "max_delta_qp=%d\n", p_enc->rc.max_delta_qp);
14571 ni_log(NI_LOG_DEBUG, "vbv_buffer_size=%d\n", p_enc->rc.vbv_buffer_size);
14572 ni_log(NI_LOG_DEBUG, "enable_filler=%d\n", p_enc->rc.enable_filler);
14573 ni_log(NI_LOG_DEBUG, "enable_pic_skip=%d\n", p_enc->rc.enable_pic_skip);
14574
14575 ni_log(NI_LOG_DEBUG, "forcedHeaderEnable=%d\n", p_enc->forced_header_enable);
14576 ni_log(NI_LOG_DEBUG, "roi_enable=%d\n", p_enc->roi_enable);
14577 ni_log(NI_LOG_DEBUG, "long_term_ref_enable=%d\n", p_enc->long_term_ref_enable);
14578 ni_log(NI_LOG_DEBUG, "long_term_ref_interval=%d\n", p_enc->long_term_ref_interval);
14579 ni_log(NI_LOG_DEBUG, "long_term_ref_count=%d\n", p_enc->long_term_ref_count);
14580 ni_log(NI_LOG_DEBUG, "conf_win_top=%d\n", p_enc->conf_win_top);
14581 ni_log(NI_LOG_DEBUG, "conf_win_bottom=%d\n", p_enc->conf_win_bottom);
14582 ni_log(NI_LOG_DEBUG, "conf_win_left=%d\n", p_enc->conf_win_left);
14583 ni_log(NI_LOG_DEBUG, "conf_win_right=%d\n", p_enc->conf_win_right);
14584
14585 ni_log(NI_LOG_DEBUG, "intra_qp=%d\n", p_enc->rc.intra_qp);
14586 ni_log(NI_LOG_DEBUG, "enable_mb_level_rc=%d\n", p_enc->rc.enable_mb_level_rc);
14587
14588 ni_log(NI_LOG_DEBUG, "intra_period=%d\n", p_enc->intra_period);
14589 ni_log(NI_LOG_DEBUG, "decoding_refresh_type=%d\n", p_enc->decoding_refresh_type);
14590
14591 // Rev. B: H.264 only or HEVC-shared parameters, in ni_t408_config_t
14592 ni_log(NI_LOG_DEBUG, "enable_transform_8x8=%d\n", p_enc->enable_transform_8x8);
14593 ni_log(NI_LOG_DEBUG, "slice_mode=%d\n", p_enc->slice_mode);
14594 ni_log(NI_LOG_DEBUG, "slice_arg=%d\n", p_enc->slice_arg);
14595 ni_log(NI_LOG_DEBUG, "entropy_coding_mode=%d\n", p_enc->entropy_coding_mode);
14596 ni_log(NI_LOG_DEBUG, "intra_mb_refresh_mode=%d\n", p_enc->intra_mb_refresh_mode);
14597 ni_log(NI_LOG_DEBUG, "intra_mb_refresh_arg=%d\n", p_enc->intra_mb_refresh_arg);
14598 ni_log(NI_LOG_DEBUG, "intra_reset_refresh=%d\n", p_enc->intra_reset_refresh);
14599
14600 ni_log(NI_LOG_DEBUG, "gop_preset_index=%d\n", p_enc->gop_preset_index);
14601#ifndef QUADRA
14602 if (!QUADRA)
14603 {
14605 {
14606 int i;
14607 ni_log(NI_LOG_DEBUG, "custom_gop_params.custom_gop_size=%d\n", p_enc->custom_gop_params.custom_gop_size);
14608 for (i = 0; i < p_enc->custom_gop_params.custom_gop_size; i++)
14609 {
14610 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);
14611 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);
14612 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);
14613 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);
14614 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);
14615 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);
14616 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);
14617 }
14618 }
14619 }
14620 else // QUADRA
14621#endif
14622 {
14624 {
14625 int i, j;
14626 ni_log(NI_LOG_DEBUG, "custom_gop_params.custom_gop_size=%d\n", p_enc->custom_gop_params.custom_gop_size);
14627 for (i = 0; i < NI_MAX_GOP_NUM; i++)
14628 {
14629 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);
14630 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);
14631 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);
14632 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);
14633 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);
14634 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);
14635 for (j = 0; j < NI_MAX_REF_PIC; j++)
14636 {
14637 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);
14638 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);
14639 }
14640 }
14641 }
14642 }
14643
14644 return;
14645}
14646
14647/*!******************************************************************************
14648 * \brief decoder keep alive thread function triggers every 1 second
14649 *
14650 * \param void thread args
14651 *
14652 * \return void
14653 *******************************************************************************/
14654void *ni_session_keep_alive_thread(void *arguments)
14655{
14658 ni_session_stats_t inst_info = {0};
14659 ni_session_context_t *session_ctx = NULL;
14660 uint64_t endtime = ni_gettime_ns();
14661 uint64_t current_time;
14662 ni_pthread_mutex_t *p_mutex;
14663 //interval(nanoseconds) is equals to ctx.keep_alive_timeout/3(330,000,000ns approximately equal to 1/3 second).
14664 uint64_t interval = args->keep_alive_timeout * 330000000LL;
14665#ifndef _ANDROID
14666#ifdef __linux__
14667 struct sched_param sched_param;
14668
14669 // Linux has a wide variety of signals, Windows has a few.
14670 // A large number of signals will interrupt the thread, which will cause heartbeat command interval more than 1 second.
14671 // So just mask the unuseful signals in Linux
14672 sigset_t signal;
14673 sigfillset(&signal);
14674 ni_pthread_sigmask(SIG_BLOCK, &signal, NULL);
14675
14676 /* set up schedule priority
14677 * first try to run with RR mode.
14678 * if fails, try to set nice value.
14679 * if fails either, ignore it and run with default priority.
14680 * Note: Scheduling requires root permission. App is probably exectued
14681 * without root so the priority for this thread might just end up
14682 * being default.
14683 */
14684 sched_param.sched_priority = sched_get_priority_max(SCHED_RR);
14685 if ((sched_param.sched_priority == -1) ||
14686 sched_setscheduler((int)syscall(SYS_gettid), SCHED_RR, &sched_param) < 0)
14687 {
14688 char errmsg[NI_ERRNO_LEN] = {0};
14690 ni_log(NI_LOG_DEBUG, "%s cannot set scheduler: %s\n", __func__,
14691 errmsg);
14692 if (setpriority(PRIO_PROCESS, 0, -20) != 0)
14693 {
14695 ni_log(NI_LOG_DEBUG, "%s cannot set nice value: %s\n", __func__,
14696 errmsg);
14697 }
14698 }
14699
14700#elif defined(_WIN32)
14701 /* set up schedule priority.
14702 * try to set the current thread to time critical level which is the highest prioriy
14703 * level.
14704 */
14705 if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) ==
14706 0)
14707 {
14708 ni_log(NI_LOG_DEBUG, "%s cannot set priority: %d.\n", __func__,
14709 GetLastError());
14710 }
14711#endif
14712#endif
14713#ifndef _WIN32
14714 // Set thread name, name is KAT + hw_id + session_id
14715 // hw_id need at most 2 bytes, session_id at most 4 bytes.
14716 char name[16] = {0};
14717 (void)snprintf(name, sizeof(name), "%s%.2x%.4x", "KAT", args->hw_id, args->session_id);
14718#if __linux__
14719 prctl(PR_SET_NAME, name);
14720#elif __APPLE__
14721 pthread_setname_np(name);
14722#endif
14723#endif
14724 // Initializes the session context variables that keep alive command and query status command need.
14726 if (!session_ctx)
14727 {
14729 LRETURN;
14730 }
14731 session_ctx->last_access_time = endtime;
14732 session_ctx->hw_id = args->hw_id;
14733 session_ctx->session_id = args->session_id;
14734 session_ctx->session_timestamp = args->session_timestamp;
14735 session_ctx->device_type = args->device_type;
14736 session_ctx->blk_io_handle = args->device_handle;
14737 session_ctx->event_handle = args->thread_event_handle;
14738 session_ctx->p_all_zero_buf = args->p_buffer;
14739 session_ctx->keep_alive_timeout = args->keep_alive_timeout;
14740 volatile uint64_t * plast_access_time = args->plast_access_time;
14741 if((session_ctx->last_access_time - *plast_access_time) >=
14742 (uint64_t)(session_ctx->keep_alive_timeout * 1000000000LL))
14743 {
14745 "%s creation timeout. session_id=0x%X requested timeout: %" PRIu64
14746 "ns, ping time delta: %" PRIu64 "ns\n ",
14747 __func__, session_ctx->session_id,
14748 (uint64_t)session_ctx->keep_alive_timeout * 1000000000LL,
14749 session_ctx->last_access_time - *plast_access_time);
14750 }
14751 ni_log(NI_LOG_DEBUG, "%s ctx.keep_alive_timeout: %us.\n", __func__,
14752 session_ctx->keep_alive_timeout);
14753 p_mutex = args->p_mutex;
14754
14755 for (;;)
14756 {
14757 ni_pthread_mutex_lock(p_mutex);
14758
14759 retval =
14761 session_ctx->blk_io_handle,
14762 session_ctx->event_handle,
14763 session_ctx->p_all_zero_buf);
14764
14765 retval = ni_query_session_stats(session_ctx,
14766 session_ctx->device_type,
14767 &inst_info,
14768 retval,
14770
14771 if (NI_RETCODE_SUCCESS == retval)
14772 {
14775 session_ctx->device_type,
14776 session_ctx->hw_id,
14777 &(session_ctx->session_id));
14778 }
14779
14780 ni_pthread_mutex_unlock(p_mutex);
14781
14782 if(retval)
14783 {
14784 uint32_t error_status = inst_info.ui32LastTransactionCompletionStatus;
14785 if(error_status == NI_RETCODE_SUCCESS)
14786 {
14787 /* QDFWSH-971: Error is sometimes captured by keep_alive_thread
14788 but LastTransactionCompletionStatus may be overwrited and cause
14789 incorrect log. In this case, check LastErrorStatus.*/
14790 ni_log(NI_LOG_ERROR, "session_no 0x%x inst_err_no may be overwrited!\n",
14791 session_ctx->session_id);
14794 session_ctx->device_type,
14795 session_ctx->hw_id,
14796 &(session_ctx->session_id));
14797 error_status = inst_info.ui32LastErrorStatus;
14798 }
14800 "Persistent failures detected, %s() line-%d: session_no 0x%x sess_err_no %u "
14801 "inst_err_no %u\n",
14802 __func__, __LINE__, session_ctx->session_id, inst_info.ui16ErrorCount, error_status);
14803 LRETURN;
14804 }
14806 /*If the interval between two heartbeats is greater then expected(interval) or
14807 acceptable(timeout) then the thread might have been blocked.*/
14808 if ((current_time - session_ctx->last_access_time) >= (2 * interval) || //*2 is for safety
14809 (current_time - session_ctx->last_access_time) >=
14810 (uint64_t)(args->keep_alive_timeout * 1000000000LL))
14811 {
14812 ni_log(
14814 "%s was possibly blocked. session_id=0x%X requested timeout: %" PRIu64
14815 "ns, ping time delta: %" PRIu64 "ns\n ",
14816 __func__, session_ctx->session_id,
14817 (uint64_t)session_ctx->keep_alive_timeout * 1000000000LL,
14818 current_time - session_ctx->last_access_time);
14819 }
14820 *plast_access_time = session_ctx->last_access_time = current_time;
14821 if (session_ctx->session_id == NI_INVALID_SESSION_ID)
14822 {
14824 }
14825
14826 // 1. If received failure, set the close_thread flag to TRUE, and exit,
14827 // then main thread will check this flag and return failure directly;
14828 // 2. skip checking VPU recovery.
14829 // If keep_alive thread detect the VPU RECOVERY before main thread,
14830 // the close_thread flag may damage the vpu recovery handling process.
14831 if ((NI_RETCODE_SUCCESS != retval) &&
14833 {
14834 LRETURN;
14835 }
14836 endtime += interval;
14837 while (ni_gettime_ns() < endtime)
14838 {
14839 if (args->close_thread)
14840 {
14841 LRETURN;
14842 }
14843 ni_usleep(10000); // 10ms per loop
14844 }
14845 }
14846
14847END:
14848
14849 if (NI_RETCODE_SUCCESS != retval)
14850 {
14851 ni_log(NI_LOG_ERROR, "%s abnormal closed:%d\n", __func__, retval);
14852 // changing the value to be True here means the thread has been closed.
14853 args->close_thread = true;
14854 }
14855
14856 ni_device_session_context_free(session_ctx);
14857
14858 ni_log(NI_LOG_DEBUG, "%s(): exit\n", __func__);
14859
14860 return NULL;
14861}
14862
14863/*!******************************************************************************
14864* \brief Open a xcoder upload instance
14865*
14866* \param p_ctx - pointer to caller allocated uploader session context
14867*
14868* \return
14869* On success
14870* NI_RETCODE_SUCCESS
14871*
14872* On failure
14873* NI_RETCODE_INVALID_PARAM
14874* NI_RETCODE_ERROR_MEM_ALOC
14875* NI_RETCODE_ERROR_INVALID_SESSION
14876* NI_RETCODE_FAILURE
14877*******************************************************************************/
14879{
14881 void * p_buffer = NULL;
14882 uint32_t ui32LBA = 0;
14883 uint32_t modelled_load;
14884
14885 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
14886
14887 if (!p_ctx)
14888 {
14889 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n",
14890 __func__);
14891 retval = NI_RETCODE_INVALID_PARAM;
14892 LRETURN;
14893 }
14894
14895 //Create the session if the create session flag is set
14896 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
14897 {
14899 p_ctx->pts_table = NULL;
14900 p_ctx->dts_queue = NULL;
14901 p_ctx->p_leftover = NULL;
14902 p_ctx->buffer_pool = NULL;
14903 p_ctx->prev_size = 0;
14904 p_ctx->sent_size = 0;
14905 p_ctx->status = 0;
14906 p_ctx->key_frame_type = 0;
14907 p_ctx->ready_to_close = 0;
14908 p_ctx->rc_error_count = 0;
14909 p_ctx->frame_num = 0;
14910 p_ctx->pkt_num = 0;
14911 p_ctx->pkt_index = 0;
14912 if (!p_ctx->max_retry_count)
14914
14915 //malloc zero data buffer
14916 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
14918 {
14919 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc all zero buffer failed\n",
14920 NI_ERRNO, __func__);
14922 LRETURN;
14923 }
14924 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
14925
14926 //malloc data buffer
14927 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
14928 {
14929 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
14930 NI_ERRNO, __func__);
14932 LRETURN;
14933 }
14934 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
14935
14936 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
14937 //In case we can open sesison, the session id would become valid.
14938 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
14939 (uint16_t)NI_INVALID_SESSION_ID;
14940
14941 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
14942 ui32LBA = OPEN_SESSION_CODEC(NI_DEVICE_TYPE_ENCODER, ni_htonl(p_ctx->codec_format), 1/*1 for uploadMode*/);
14943 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
14944 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
14945 if (retval != NI_RETCODE_SUCCESS)
14946 {
14947 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR ni_nvme_send_read_cmd\n");
14948 LRETURN;
14949 }
14950 //Open will return a session status structure with a valid session id if it worked.
14951 //Otherwise the invalid session id set before the open command will stay
14952 p_ctx->session_id = ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
14953 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
14954 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
14955 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
14956 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
14957 {
14958 ni_log2(p_ctx, NI_LOG_ERROR,
14959 "ERROR %s(): p_ctx->device_handle=%" PRIx64
14960 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
14961 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
14962 p_ctx->session_id);
14963 ni_encoder_session_close(p_ctx, 0);
14965 LRETURN;
14966 }
14967 ni_log2(p_ctx, NI_LOG_DEBUG,
14968 "Uploader open session ID:0x%x,timestamp:%" PRIu64 "\n",
14969 p_ctx->session_id, p_ctx->session_timestamp);
14970
14971 //Send keep alive timeout Info
14972 uint64_t keep_alive_timeout =
14973 (uint64_t)p_ctx->keep_alive_timeout * 1000000; //send us to FW
14974 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
14975 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
14976 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
14977 keep_alive_timeout);
14979 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
14980 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
14981 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
14982 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
14983 CHECK_VPU_RECOVERY(retval);
14984
14985 if (NI_RETCODE_SUCCESS != retval)
14986 {
14987 ni_log2(p_ctx, NI_LOG_ERROR,
14988 "ERROR %s(): nvme write keep_alive_timeout command "
14989 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
14990 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
14992 LRETURN;
14993 }
14994
14995 // only update firmware with pixel rate if firmware >= 6rf
14997 (char *) &p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rf") >= 0)
14998 {
14999 /* Add the modelled load of the hwuploader */
15000 if (p_ctx->framerate.framerate_denom == 0)
15001 {
15002 // unknown or variable frame rate. Assume 25 fps
15003 modelled_load = (p_ctx->active_video_width * p_ctx->active_video_height) * 25;
15004 }
15005 else
15006 {
15007 modelled_load = (p_ctx->active_video_width * p_ctx->active_video_height *
15009 }
15010
15011 // modelled_load can overflow a 4-byte value so we will downscale it to
15012 // kilopixels per sec by shifting the modelled load down by 10 bits.
15013 modelled_load >>= 10;
15014
15016
15017 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
15018 memcpy(p_buffer, &modelled_load, 4);
15019
15020 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
15021 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
15022
15023 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
15024 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15025 CHECK_VPU_RECOVERY(retval);
15026
15027 if (NI_RETCODE_SUCCESS != retval)
15028 {
15030 LRETURN;
15031 }
15032 }
15033
15034 ni_log2(p_ctx, NI_LOG_DEBUG, "Open session completed\n");
15035 }
15036
15037 // init for frame pts calculation
15038 p_ctx->is_first_frame = 1;
15039 p_ctx->last_pts = 0;
15040 p_ctx->last_dts = 0;
15041
15042 ni_timestamp_init(p_ctx, &p_ctx->pts_table, "dec_pts");
15043 ni_timestamp_init(p_ctx, &p_ctx->dts_queue, "dec_dts");
15044
15045 //p_ctx->active_video_width = 0;
15046 //p_ctx->active_video_height = 0;
15047
15048 ni_log2(p_ctx, NI_LOG_DEBUG,
15049 "%s(): p_ctx->device_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
15050 "p_ctx->session_id=%d\n",
15051 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
15052 p_ctx->session_id);
15053
15054 p_ctx->hw_action = NI_CODEC_HW_NONE;
15055#if !defined(_WIN32) && !defined(__APPLE__) && !defined(__OPEN_HARMONY__) && !defined(_ANDROID)
15056 // If this is a P2P upload session, open the Netint kernel driver
15057 if (p_ctx->isP2P)
15058 {
15059 retval = p2p_fill_pcie_address(p_ctx);
15060 if(retval != NI_RETCODE_SUCCESS)
15061 {
15062 LRETURN;
15063 }
15064 }
15065#endif
15066
15067END:
15068
15069 ni_aligned_free(p_buffer);
15070 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
15071 return retval;
15072}
15073
15074/*!******************************************************************************
15075* \brief Copy a xcoder decoder worker thread info
15076*
15077* \param
15078*
15079* \return
15080*******************************************************************************/
15082{
15083 if (!src_p_ctx || !dst_p_ctx)
15084 {
15085 ni_log(NI_LOG_ERROR, "ERROR %s(): passed parameters are null!, return\n", __func__);
15087 }
15088
15089 dst_p_ctx->pext_mutex = src_p_ctx->pext_mutex; //for hwdl
15090 dst_p_ctx->max_nvme_io_size = src_p_ctx->max_nvme_io_size;
15091 dst_p_ctx->device_handle = src_p_ctx->device_handle;
15092 dst_p_ctx->blk_io_handle = src_p_ctx->blk_io_handle;
15093 dst_p_ctx->hw_id = src_p_ctx->hw_id;
15094 dst_p_ctx->session_timestamp = src_p_ctx->session_timestamp;
15095 memcpy(dst_p_ctx->fw_rev, src_p_ctx->fw_rev, sizeof(src_p_ctx->fw_rev));
15096 if (src_p_ctx->isP2P)
15097 {
15098 dst_p_ctx->isP2P = src_p_ctx->isP2P;
15099 dst_p_ctx->ddr_config = src_p_ctx->ddr_config;
15100 dst_p_ctx->domain = src_p_ctx->domain;
15101 dst_p_ctx->bus = src_p_ctx->bus;
15102 dst_p_ctx->dev = src_p_ctx->dev;
15103 dst_p_ctx->fn = src_p_ctx->fn;
15104 dst_p_ctx->netint_fd = src_p_ctx->netint_fd;
15105 }
15106
15107 return NI_RETCODE_SUCCESS;
15108}
15109
15110
15111/*!******************************************************************************
15112 * \brief Query and acquire buffer from xcoder scaler instance
15113 *
15114 * \param[in] p_ctx pointer to scaler session context
15115 *
15116 * \return NI_RETCODE_INVALID_PARAM
15117 * NI_RETCODE_ERROR_INVALID_SESSION
15118 * NI_RETCODE_ERROR_MEM_ALOC
15119 * NI_RETCODE_ERROR_NVME_CMD_FAILED
15120 * NI_RETCODE_FAILURE
15121 *******************************************************************************/
15123{
15125 ni_instance_buf_info_t sInstanceBuf = {0};
15126 int query_retry = 0;
15127
15128 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
15129 {
15130 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
15131 __func__);
15133 }
15134
15135 if (p_ctx->buffered_frame_index > 0)
15136 {
15137 ni_log2(p_ctx, NI_LOG_ERROR,
15138 "Session=0x%x: %s buffered_frame_index=%d return %d\n",
15139 p_ctx->session_id,
15140 __func__,
15141 p_ctx->buffered_frame_index,
15142 retval);
15143 return retval;
15144 }
15145
15146 for (;;)
15147 {
15148 query_sleep(p_ctx);
15149 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: query by ni_query_instance_buf_info INST_BUF_INFO_RW_UPLOAD\n", __func__);
15151 NI_DEVICE_TYPE_SCALER, &sInstanceBuf);
15152
15153 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15154 p_ctx->device_type, p_ctx->hw_id,
15155 &(p_ctx->session_id), OPT_3);
15156
15157 /* A frame index of zero is invalid, the memory acquisition failed */
15158 if (NI_RETCODE_SUCCESS != retval || (sInstanceBuf.hw_inst_ind.frame_index == 0 && query_retry >= p_ctx->max_retry_count))
15159 {
15160 if (query_retry >= p_ctx->max_retry_count)
15161 {
15162 ni_log2(p_ctx, NI_LOG_DEBUG,
15163 "scaler write exceeded max query retries. rc=%d try=%d\n",
15164 retval, query_retry);
15165 }
15167 LRETURN;
15168 }
15169 if (sInstanceBuf.hw_inst_ind.frame_index == 0 && query_retry < p_ctx->max_retry_count)
15170 {
15171 query_retry++;
15173 ni_usleep(100);
15175 }
15176 else
15177 {
15178 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: FID %d\n", __func__,
15179 sInstanceBuf.hw_inst_ind.frame_index);
15180 p_ctx->buffered_frame_index = sInstanceBuf.hw_inst_ind.frame_index;
15181 break;
15182 }
15183 }
15184
15185 ni_log2(p_ctx, NI_LOG_DEBUG,
15186 "Session=0x%x: %s got FrameIndex=%u buffered_frame_index=%d\n",
15187 p_ctx->session_id,
15188 __func__,
15189 sInstanceBuf.hw_inst_ind.frame_index,p_ctx->buffered_frame_index);
15190
15191END:
15192
15193 if (NI_RETCODE_SUCCESS != retval)
15194 {
15195 ni_log2(p_ctx, NI_LOG_DEBUG,
15196 "%s Warning scalar read hwdesc fail rc %d or ind !\n",
15197 __func__, retval);
15198 }
15199 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
15200
15201 return retval;
15202}
15203
15204
15205/*!******************************************************************************
15206* \brief Query and acquire buffer from xcoder upload instance
15207*
15208* \param p_ctx pointer to uploader session context
15209*
15210* \return NI_RETCODE_SUCCESS
15211* NI_RETCODE_ERROR_INVALID_SESSION
15212* NI_RETCODE_ERROR_MEM_ALOC
15213*******************************************************************************/
15215{
15217 //uint32_t metadata_size = NI_APP_ENC_FRAME_META_DATA_SIZE;
15218 uint32_t frame_size_bytes = 0;
15219 int retry_count = 0;
15220 ni_instance_buf_info_t buf_info = { 0 };
15221
15222 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
15223
15224 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
15225 {
15226 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
15227 __func__);
15229 LRETURN;
15230 }
15231
15232//#ifdef MEASURE_LATENCY
15233#if 0
15234 if ((p_frame->pts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
15235 {
15236 uint64_t abs_time_ns = ni_gettime_ns();
15238 abs_time_ns, p_frame->pts);
15239 }
15240#endif
15241
15242 //p_ctx->status = 0;
15243
15244 if (p_ctx->buffered_frame_index > 0)
15245 return retval;
15246
15247 for (;;)
15248 {
15249 query_sleep(p_ctx);
15250
15252 NI_DEVICE_TYPE_ENCODER, &buf_info);
15253 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15254 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15255 if (NI_RETCODE_SUCCESS != retval ||
15256 (buf_info.hw_inst_ind.buffer_avail == 0 && retry_count >= p_ctx->max_retry_count))
15257 {
15258 if (retry_count >= p_ctx->max_retry_count)
15259 {
15260 ni_log2(p_ctx, NI_LOG_DEBUG,
15261 "hwupload write exceeded max query retries. rc=%d try=%d"
15262 "\n",
15263 retval, retry_count);
15264 }
15266 //p_ctx->status = NI_RETCODE_NVME_SC_WRITE_BUFFER_FULL;
15267 LRETURN;
15268 }
15269 if (buf_info.hw_inst_ind.buffer_avail == 0 && retry_count < p_ctx->max_retry_count)
15270 {
15271 retry_count++;
15273 ni_usleep(100);
15275 }
15276 else
15277 {
15278 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: avail %d, FID %d\n", __func__,
15279 buf_info.hw_inst_ind.buffer_avail,
15280 buf_info.hw_inst_ind.frame_index);
15281
15283 break;
15284 }
15285 }
15286 ni_log2(p_ctx, NI_LOG_DEBUG, "Info hwupload write query success, available buf "
15287 "size %u >= frame size %u , retry %u\n",
15288 buf_info.buf_avail_size, frame_size_bytes, retry_count);
15289
15290//#ifdef MEASURE_LATENCY
15291#if 0
15292 if ((p_frame->pts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
15293 {
15294 uint64_t abs_time_ns = ni_gettime_ns();
15296 ni_log(NI_LOG_INFO, "PTS:%" PRId64 ",DELTA:%" PRId64 ",uLAT:%" PRIu64 ";\n",
15297 p_frame->pts, abs_time_ns - q->last_benchmark_time,
15298 ni_lat_meas_q_check_latency(q, abs_time_ns, p_frame->pts));
15299 q->last_benchmark_time = abs_time_ns;
15300 }
15301#endif
15302
15303 //retval = size;
15304
15305END:
15306
15307 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
15308 return retval;
15309}
15310
15311
15312/*!******************************************************************************
15313* \brief Send a YUV p_frame to upload session
15314*
15315* \param
15316*
15317* \return
15318*******************************************************************************/
15320 niFrameSurface1_t *hwdesc)
15321{
15322 int retval = 0;
15323 uint32_t size = 0;
15324 //uint32_t metadata_size = NI_APP_ENC_FRAME_META_DATA_SIZE;
15325 uint32_t i = 0;
15326 uint32_t sent_size = 0;
15327 uint32_t frame_size_bytes = 0;
15328 int retry_count = 0;
15329 ni_instance_buf_info_t buf_info = { 0 };
15330
15331 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
15332 //niFrameSurface1_t* p_data3 = (niFrameSurface1_t*)((uint8_t*)p_frame->p_data[3]);
15334 //ni_log2(p_ctx, NI_LOG_DEBUG, "%s:mar16 HW=%d ui16FrameIdx=%d i8InstID=%d device_handle=%d\n",
15335 // ishwframe, p_data3->ui16FrameIdx, p_data3->i8InstID, p_data3->device_handle);
15336
15337 if (!p_ctx || !p_frame)
15338 {
15339 ni_log(NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
15340 __func__);
15341 retval = NI_RETCODE_INVALID_PARAM;
15342 LRETURN;
15343 }
15344
15345 uint8_t separate_metadata = p_frame->separate_metadata;
15346 uint8_t separate_start = (p_frame->separate_start && p_frame->total_start_len) ? 1 : 0;
15347
15348 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
15349 {
15350 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
15351 __func__);
15353 LRETURN;
15354 }
15355
15356#ifdef MEASURE_LATENCY
15357 if ((p_frame->pts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
15358 {
15359 uint64_t abs_time_ns = ni_gettime_ns();
15361 abs_time_ns, p_frame->pts);
15362 }
15363#endif
15364
15365 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;
15366 ni_log2(p_ctx, NI_LOG_DEBUG, "frame size bytes =%u %d is metadata!\n", frame_size_bytes,
15367 0);
15368 p_ctx->status = 0;
15369
15370 if (p_frame->end_of_stream)
15371 {
15372 retval = NI_RETCODE_SUCCESS;
15373 LRETURN;
15374 }
15375
15376 if (p_ctx->buffered_frame_index > 0)
15377 {
15379 p_ctx->buffered_frame_index = 0;
15380 }
15381 else
15382 {
15383 for (;;)
15384 {
15385 query_sleep(p_ctx);
15386
15388 NI_DEVICE_TYPE_ENCODER, &buf_info);
15389 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15390 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15391 if (NI_RETCODE_SUCCESS != retval ||
15392 (buf_info.hw_inst_ind.buffer_avail == 0 && retry_count >= p_ctx->max_retry_count))
15393 {
15394 if (retry_count >= p_ctx->max_retry_count)
15395 {
15396 ni_log2(p_ctx, NI_LOG_DEBUG,
15397 "hwupload write exceeded max query retries. rc=%d try=%d"
15398 "\n",
15399 retval, retry_count);
15400 }
15403 LRETURN;
15404 }
15405 if (buf_info.hw_inst_ind.buffer_avail == 0 && retry_count < p_ctx->max_retry_count)
15406 {
15407 retry_count++;
15409 ni_usleep(100);
15411 } else //available
15412 {
15413 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: avail %d, FID %d\n", __func__,
15414 buf_info.hw_inst_ind.buffer_avail,
15415 buf_info.hw_inst_ind.frame_index);
15416 break;
15417 }
15418 }
15419 ni_log2(p_ctx, NI_LOG_DEBUG, "Info hwupload write query success, available buf "
15420 "size %u >= frame size %u , retry %u\n",
15421 buf_info.buf_avail_size, frame_size_bytes, retry_count);
15422 }
15423
15424 {
15425#ifdef XCODER_TIMESTAMP_DTS_ENABLED
15426 retval = ni_timestamp_register(p_ctx->buffer_pool, p_ctx->dts_queue,
15427 p_frame->dts, 0);
15428 if (NI_RETCODE_SUCCESS != retval)
15429 {
15430 ni_log2(p_ctx, NI_LOG_ERROR,
15431 "ERROR %s(): ni_timestamp_register() for dts "
15432 "returned: %d\n",
15433 __func__, retval);
15434 }
15435#endif
15436
15437 //Apply write configuration here
15438 retval = ni_config_session_rw(p_ctx, SESSION_WRITE_CONFIG, 1,
15441 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15442 CHECK_VPU_RECOVERY(retval);
15443
15444 if (separate_metadata)
15445 {
15447 "6S") < 0)
15448 {
15449 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): uploader separated metadata not supported on device with FW api version < 6.S\n",
15450 __func__);
15452 LRETURN;
15453 }
15454
15455 if (!p_frame->p_metadata_buffer)
15456 {
15457 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_metadata_buffer is NULL, allocation failed?\n",
15458 __func__);
15460 LRETURN;
15461 }
15462
15463 // fill in metadata
15465 p_meta = (ni_metadata_enc_frame_t *)p_frame->p_metadata_buffer;
15466
15467 if (separate_start)
15468 {
15469 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
15470 p_meta->start_len[i] = p_frame->start_len[i];
15471 }
15472 else
15473 {
15474 memset(p_meta->start_len, 0, sizeof(p_meta->start_len));
15475 }
15477
15478 ni_log(
15480 "%s(): %d.%u p_ctx->frame_num=%" PRIu64 ", "
15481 "p_frame->video_width=%u, p_frame->video_height=%u, "
15482 "start_len [%u,%u,%u] inconsecutive_transfer %u\n",
15483 __func__, p_ctx->hw_id, p_ctx->session_id, p_ctx->frame_num,
15484 p_frame->video_width, p_frame->video_height,
15485 p_meta->start_len[0], p_meta->start_len[1], p_meta->start_len[2],
15486 p_meta->inconsecutive_transfer);
15487
15488 uint32_t ui32LBA_metadata =
15490 ni_log2(p_ctx, NI_LOG_DEBUG,
15491 "%s: p_metadata_buffer = %p, metadata_buffer_size "
15492 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
15493 __func__, p_frame->p_metadata_buffer,
15494 p_frame->metadata_buffer_size, p_ctx->frame_num,
15495 ui32LBA_metadata);
15496
15497 sent_size =
15499
15500 retval = ni_nvme_send_write_cmd(
15501 p_ctx->blk_io_handle, p_ctx->event_handle,
15502 p_frame->p_metadata_buffer, sent_size,
15503 ui32LBA_metadata);
15504 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
15505 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15506 CHECK_VPU_RECOVERY(retval);
15507 if (retval < 0)
15508 {
15509 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n",
15510 __func__);
15512 LRETURN;
15513 }
15514 }
15515
15516 if (separate_start)
15517 {
15518 if (!p_frame->p_start_buffer)
15519 {
15520 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_start_buffer is NULL, allocation failed?\n",
15521 __func__);
15523 LRETURN;
15524 }
15525
15526 uint32_t ui32LBA =
15528 ni_log2(p_ctx, NI_LOG_DEBUG,
15529 "%s: p_start_buffer = %p, p_frame->start_buffer_size "
15530 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
15531 __func__, p_frame->p_start_buffer, p_frame->start_buffer_size, p_ctx->frame_num,
15532 ui32LBA);
15533
15534 sent_size =
15536
15537 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
15538 p_frame->p_start_buffer, sent_size, ui32LBA);
15539 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
15540 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15541 CHECK_VPU_RECOVERY(retval);
15542 if (retval < 0)
15543 {
15544 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
15546 LRETURN;
15547 }
15548 }
15549
15550 if (p_frame->inconsecutive_transfer)
15551 {
15552 uint32_t ui32LBA =
15554
15555 for (i = 0; i < NI_MAX_NUM_SW_FRAME_DATA_POINTERS; i++)
15556 {
15557 ni_log2(p_ctx, NI_LOG_DEBUG,
15558 "%s: p_data = %p, p_frame->buffer_size "
15559 "= %u, p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
15560 __func__, p_frame->p_data, p_frame->buffer_size, p_ctx->frame_num,
15561 ui32LBA);
15562
15563 if (p_frame->data_len[i])
15564 {
15565 sent_size = p_frame->data_len[i];
15566 if (separate_start)
15567 sent_size -= p_frame->start_len[i];
15568
15569 sent_size =
15571
15572 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
15573 p_frame->p_data[i]+p_frame->start_len[i], sent_size, ui32LBA);
15574 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
15575 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15576 CHECK_VPU_RECOVERY(retval);
15577 if (retval < 0)
15578 {
15579 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
15581 LRETURN;
15582 }
15583 }
15584 }
15585 }
15586 else
15587 {
15588 uint32_t ui32LBA =
15590 ni_log2(p_ctx, NI_LOG_DEBUG,
15591 "%s: p_data = %p, p_frame->buffer_size = %u, "
15592 "p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
15593 __func__, p_frame->p_data, p_frame->buffer_size, p_ctx->frame_num,
15594 ui32LBA);
15595
15596 sent_size = frame_size_bytes;
15597 if (separate_start)
15598 sent_size -= p_frame->total_start_len;
15599
15600 sent_size =
15602
15603 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
15604 p_frame->p_buffer+p_frame->total_start_len, sent_size, ui32LBA);
15605 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
15606 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15607 CHECK_VPU_RECOVERY(retval);
15608 if (retval < 0)
15609 {
15610 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
15612 LRETURN;
15613 }
15614 }
15615
15616 hwdesc->ui16FrameIdx = buf_info.hw_inst_ind.frame_index;
15617 hwdesc->ui16session_ID = p_ctx->session_id;
15618 hwdesc->device_handle =
15619 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
15620 hwdesc->bit_depth = (int8_t)p_ctx->bit_depth_factor;
15621 hwdesc->src_cpu = (uint8_t)NI_DEVICE_TYPE_ENCODER;
15622 hwdesc->output_idx = (int8_t)(hwdesc->ui32nodeAddress = 0);
15623
15624 p_ctx->frame_num++;
15625 size = frame_size_bytes;
15626
15627#ifdef XCODER_DUMP_DATA
15628 char dump_file[256];
15629 (void)snprintf(dump_file, sizeof(dump_file), "%ld-%u-hwup-fme/fme-%04ld.yuv",
15630 (long)getpid(), p_ctx->session_id, (long)p_ctx->frame_num);
15631
15632 FILE *f = NULL;
15633 ni_fopen(&f, dump_file, "wb");
15634 (void)fwrite(p_frame->p_buffer,
15635 p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2],
15636 1, f);
15637 (void)fflush(f);
15638 (void)fclose(f);
15639#endif
15640 }
15641
15642#ifdef MEASURE_LATENCY
15643 if ((p_frame->pts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
15644 {
15645 uint64_t abs_time_ns = ni_gettime_ns();
15647 ni_log(NI_LOG_INFO, "PTS:%" PRId64 ",DELTA:%" PRId64 ",uLAT:%" PRIu64 ";\n",
15648 p_frame->pts, abs_time_ns - q->last_benchmark_time,
15649 ni_lat_meas_q_check_latency(q, abs_time_ns, p_frame->pts));
15650 q->last_benchmark_time = abs_time_ns;
15651 }
15652#endif
15653
15654 retval = (int)size;
15655
15656END:
15657
15658 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
15659 return retval;
15660}
15661
15662/*!******************************************************************************
15663* \brief Retrieve a HW descriptor of uploaded frame
15664*
15665* \param p_ctx pointer to uploader session context
15666* hwdesc pointer to hw descriptor
15667*
15668* \return
15669* On success
15670* NI_RETCODE_SUCCESS
15671* On failure
15672* NI_RETCODE_INVALID_PARAM
15673* NI_RETCODE_ERROR_INVALID_SESSION
15674* NI_RETCODE_FAILURE
15675*******************************************************************************/
15677 niFrameSurface1_t *hwdesc)
15678{
15679 int retval = 0;
15680 ni_instance_buf_info_t hwdesc_info = { 0 };
15681 int query_retry = 0;
15682
15683 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
15684
15685 if (!p_ctx || !hwdesc)
15686 {
15687 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
15688 __func__);
15689 retval = NI_RETCODE_INVALID_PARAM;
15690 LRETURN;
15691 }
15692
15693 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
15694 {
15695 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
15696 __func__);
15698 LRETURN;
15699 }
15700
15701 for (;;)
15702 {
15703 query_sleep(p_ctx);
15704
15705 query_retry++;
15706#ifndef _WIN32
15708 NI_DEVICE_TYPE_ENCODER, &hwdesc_info);
15709#else
15711 NI_DEVICE_TYPE_ENCODER, &hwdesc_info);
15712#endif
15713 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15714 p_ctx->device_type, p_ctx->hw_id,
15715 &(p_ctx->session_id), OPT_1);
15716
15717 if (NI_RETCODE_SUCCESS != retval)
15718 {
15719 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning upload read hwdesc fail rc %d or ind "
15720 "!\n", retval);
15721
15722 if (query_retry >= 1000)
15723 {
15724 retval = NI_RETCODE_FAILURE;
15725 LRETURN;
15726 }
15727 ni_usleep(100);
15728 }
15729 else
15730 {
15731 ni_log2(p_ctx, NI_LOG_DEBUG, "Info hwupload read hwdesc success, "
15732 "frame_ind=%d !\n", hwdesc_info.hw_inst_ind.frame_index);
15733
15734 hwdesc->ui16FrameIdx = hwdesc_info.hw_inst_ind.frame_index;
15735 hwdesc->ui16session_ID = p_ctx->session_id;
15736 hwdesc->device_handle =
15737 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
15738 hwdesc->bit_depth = (int8_t)p_ctx->bit_depth_factor;
15739 hwdesc->src_cpu = (uint8_t)NI_DEVICE_TYPE_ENCODER;
15740 hwdesc->output_idx = 0;
15741 LRETURN;
15742 }
15743 }
15744
15745END:
15746 return retval;
15747}
15748
15749/*!*****************************************************************************
15750* \brief clear a particular xcoder instance buffer/data
15751*
15752* \param ni_session_context_t p_ctx - xcoder Context
15753* \param ni_instance_buf_info_rw_type_t rw_type
15754* \param ni_device_type_t device_type - xcoder type Encoder or Decoder
15755* \param ni_instance_buf_info_t *out - Struct preallocated from the caller
15756* where the resulting data will be placed
15757*
15758* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION,
15759* NI_RETCODE_ERROR_MEM_ALOC or NI_RETCODE_ERROR_NVME_CMD_FAILED on
15760* failure
15761******************************************************************************/
15763{
15764 void* p_buffer = NULL;
15766 uint32_t ui32LBA = 0;
15767
15768 ni_log(NI_LOG_TRACE, "%s(): enter - device_handle %d\n", __func__,
15769 surface->device_handle);
15770
15771 if ((uint16_t)NI_INVALID_SESSION_ID == surface->ui16session_ID)
15772 {
15773 ni_log(NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
15774 __func__);
15776 LRETURN;
15777 }
15778
15779 //malloc data buffer
15780 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
15781 {
15782 ni_log(NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
15783 NI_ERRNO, __func__);
15785 LRETURN;
15786 }
15787 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
15788 ni_log(NI_LOG_DEBUG, "%s(): FID = %d\n", __func__, surface->ui16FrameIdx);
15789 ui32LBA = CLEAR_INSTANCE_BUF_W(((uint16_t)surface->ui16FrameIdx));
15790 retval = ni_nvme_send_write_cmd((ni_device_handle_t)(int64_t)surface->device_handle,
15791 NI_INVALID_DEVICE_HANDLE, p_buffer,
15792 NI_DATA_BUFFER_LEN, ui32LBA);
15793 //Cannot check sessio stats here since this isn't a session command.
15794 if (retval < 0)
15795 {
15796 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__);
15798 LRETURN;
15799 }
15800
15801END:
15802
15803 ni_aligned_free(p_buffer);
15804 ni_log(NI_LOG_TRACE, "%s(): exit\n", __func__);
15805 return retval;
15806}
15807
15808/*!******************************************************************************
15809* \brief Retrieve a hw desc p_frame from decoder
15810* \param
15811*
15812* \return
15813*******************************************************************************/
15815{
15816 //Needs serious editing to support hwdesc read again, this is currently vanilla read
15817 //queue_info decoder_read_workerqueue;
15819 int rx_size = 0;
15820 uint64_t frame_offset = 0;
15821 uint32_t frame_dropped = 0;
15822 uint8_t *p_data_buffer = NULL;
15823 uint32_t i = 0;
15824 int retval = NI_RETCODE_SUCCESS;
15825 int metadata_hdr_size = NI_FW_META_DATA_SZ -
15827 int sei_size = 0;
15828 uint32_t total_bytes_to_read = 0;
15829 uint32_t total_yuv_met_size = 0;
15830 uint32_t read_size_bytes = 0;
15831 ni_instance_buf_info_t buf_info = {0};
15832 int query_retry = 0;
15833 uint32_t ui32LBA = 0;
15834 unsigned int bytes_read_so_far = 0;
15835 int query_type = INST_BUF_INFO_RW_READ;
15836 int low_delay_notify = 0;
15837 ni_session_statistic_t sessionStatistic = {0};
15838 uint32_t frames_dropped = 0;
15839 ni_xcoder_params_t *p_param;
15840 uint8_t get_first_metadata = 0;
15841 uint8_t sequence_change = 0;
15842
15843 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
15844
15845 if (!p_ctx || !p_frame)
15846 {
15847 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
15848 __func__);
15850 }
15851
15853
15854start:
15855 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
15856 {
15857 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
15858 __func__);
15860 LRETURN;
15861 }
15862
15863 p_param = (ni_xcoder_params_t *)p_ctx->p_session_config;
15864 p_data_buffer = (uint8_t *)p_frame->p_buffer;
15865
15866 // p_frame->p_data[] can be NULL before actual resolution is returned by
15867 // decoder and buffer pool is allocated, so no checking here.
15868
15869 total_bytes_to_read = p_frame->data_len[3] + metadata_hdr_size;
15870 total_yuv_met_size = p_frame->data_len[0] + p_frame->data_len[1] + p_frame->data_len[2] + metadata_hdr_size;
15871 ni_log2(p_ctx, NI_LOG_DEBUG,
15872 "Total bytes to read %u total_yuv_met_size %u, low_delay %u\n",
15873 total_bytes_to_read, total_yuv_met_size, p_ctx->decoder_low_delay);
15874 if (p_ctx->decoder_low_delay > 0 && !p_ctx->ready_to_close)
15875 {
15876 ni_log2(p_ctx, NI_LOG_DEBUG, "frame_num = %" PRIu64 ", pkt_num = %" PRIu64 "\n",
15877 p_ctx->frame_num, p_ctx->pkt_num);
15878 frames_dropped = p_ctx->session_statistic.ui32FramesDropped;
15879 if (p_ctx->force_low_delay && (p_ctx->force_low_delay_cnt < frames_dropped)) {
15880 p_ctx->force_low_delay_cnt = frames_dropped;
15881 }
15882 if (p_ctx->frame_num + p_ctx->force_low_delay_cnt
15883 >= p_ctx->pkt_num)
15884 {
15885 //nothing to query, leave
15886 retval = NI_RETCODE_SUCCESS;
15887 LRETURN;
15888 }
15889 query_type = INST_BUF_INFO_RW_READ_BUSY;
15890 }
15891 for (;;)
15892 {
15893 query_sleep(p_ctx);
15894
15895 query_retry++;
15896
15899 "6r3") >= 0)
15900 {
15902 &sessionStatistic);
15903 CHECK_ERR_RC(p_ctx, retval, &sessionStatistic,
15905 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
15906 CHECK_VPU_RECOVERY(retval);
15907
15908 buf_info.buf_avail_size = sessionStatistic.ui32RdBufAvailSize;
15909 } else
15910 {
15911 retval = ni_query_instance_buf_info(p_ctx, query_type,
15912 NI_DEVICE_TYPE_DECODER, &buf_info);
15913 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15914 p_ctx->device_type, p_ctx->hw_id,
15915 &(p_ctx->session_id), OPT_1);
15916 CHECK_VPU_RECOVERY(retval);
15917 }
15918
15919 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read desc query buf_info.size = %u\n",
15920 buf_info.buf_avail_size);
15921
15922 if (NI_RETCODE_SUCCESS != retval)
15923 {
15924 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read desc failed. Retry %d\n", query_retry);
15925
15926 if (query_retry >= 1000)
15927 {
15928 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: dec read desc failed %d retries. rc=%d"
15929 "\n", query_retry, retval);
15930 p_ctx->max_retry_fail_count[1]++;
15931 low_delay_notify = 1;
15933 LRETURN;
15934 }
15938 } else if (buf_info.buf_avail_size == DP_IPC_PASSTHRU)
15939 {
15940 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Bad available buffer size %u\n", __FUNCTION__, buf_info.buf_avail_size);
15941 retval = NI_RETCODE_FAILURE;
15942 LRETURN;
15943 } else if (buf_info.buf_avail_size == metadata_hdr_size)
15944 {
15945 ni_log2(p_ctx, NI_LOG_DEBUG,
15946 "Dec read desc only hdr metadata is available. Seq change may "
15947 "have occured.\n");
15948 total_bytes_to_read = metadata_hdr_size;
15949 sequence_change = 1;
15950 break;
15951 } else if (buf_info.buf_avail_size < total_yuv_met_size)
15952 {
15953 ni_log2(p_ctx, NI_LOG_TRACE, "Dec read desc buf_size < frame_size. Retry %d\n", query_retry);
15954
15955 // query to see if it is eos now, if we have sent it
15956 if (p_ctx->ready_to_close)
15957 {
15958 ni_log2(p_ctx, NI_LOG_TRACE,
15959 "Dec read desc query, ready_to_close %u, query eos\n",
15960 p_ctx->ready_to_close);
15961 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_DECODER, &data);
15962 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
15963 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
15964 CHECK_VPU_RECOVERY(retval);
15965
15966 if (data.is_flushed ||
15967 query_retry >=
15969 {
15970 if (query_retry >=
15972 {
15973 ni_log2(p_ctx, NI_LOG_ERROR,
15974 "WARNING: Dec read desc query eos reached but exceeded max "
15975 "retries. is_flushed=%u try=%d.\n",
15976 data.is_flushed, query_retry);
15977 } else
15978 {
15979 ni_log2(p_ctx, NI_LOG_DEBUG,
15980 "Dec read desc query eos reached. is_flushed=%u try=%d"
15981 "\n",
15982 data.is_flushed, query_retry);
15983 }
15984 p_frame->end_of_stream = 1;
15985 low_delay_notify = 1;
15986 retval = NI_RETCODE_SUCCESS;
15987 LRETURN;
15988 }
15989 else
15990 {
15991 ni_log2(p_ctx, NI_LOG_TRACE,
15992 "Dec read desc available buf size == %d, query try %d, "
15993 "retrying...\n",
15994 buf_info.buf_avail_size, query_retry);
15998 continue;
15999 }
16000 }
16001
16003 (p_ctx->decoder_low_delay > 0 &&
16004 ((p_ctx->frame_num + p_ctx->force_low_delay_cnt)
16005 < p_ctx->pkt_num))) &&
16006 query_retry < 1000 / 2)
16007 {
16008 if (p_ctx->decoder_low_delay && p_ctx->force_low_delay) {
16009 if (p_ctx->session_statistic.ui32FramesDropped > frames_dropped) {
16010 // last pkt sent to decoder marked as dropped, no output,
16011 // so just stop query and return
16012 p_ctx->force_low_delay_cnt++;
16013 low_delay_signal(p_ctx);
16014 retval = NI_RETCODE_SUCCESS;
16015 LRETURN;
16016 }
16017 } else if (NI_RETCODE_NVME_SC_WRITE_BUFFER_FULL == p_ctx->status &&
16018 sessionStatistic.ui32WrBufAvailSize > p_ctx->required_buf_size)
16019 {
16020 ni_log2(p_ctx, NI_LOG_TRACE, "Info dec write buffer is enough, available buf "
16021 "size %u >= required size %u !\n",
16022 sessionStatistic.ui32WrBufAvailSize, p_ctx->required_buf_size);
16023 p_ctx->status = 0;
16024 p_ctx->required_buf_size = 0;
16025 retval = NI_RETCODE_SUCCESS;
16026 LRETURN;
16027 }
16031
16032 continue;
16033 } else
16034 {
16035 if (p_ctx->decoder_low_delay > 0)
16036 {
16037 if (p_ctx->force_low_delay) {
16038 p_ctx->force_low_delay_cnt++;
16039 low_delay_signal(p_ctx);
16040 } else {
16041 ni_log2(p_ctx, NI_LOG_ERROR,"Warning: low delay mode with non sequential "
16042 "input (B frames)? Just cancel the low delay mode then\n");
16043 // Here it should be the last signal to release the send thread
16044 // holding the low delay mutex.
16045 low_delay_signal(p_ctx);
16046 p_ctx->decoder_low_delay = 0;
16047 }
16048 }
16049
16050 if ((p_param->dec_input_params.min_packets_delay && p_ctx->pkt_delay_cnt))
16051 {
16052 if(p_ctx->pkt_num >= (p_ctx->frame_num + p_ctx->pkt_delay_cnt +
16054 {
16055 if(query_retry <= 2000)
16056 {
16058 ni_usleep(25);
16060 continue;
16061 } else {
16062 p_ctx->pkt_delay_cnt++;
16063 ni_log2(p_ctx, NI_LOG_ERROR,
16064 "Warning: decoder pkt_num %u frame_num %u "
16065 "timeout, increasing pkt_delay_cnt to %u\n",
16066 p_ctx->pkt_num, p_ctx->frame_num,
16067 p_ctx->pkt_delay_cnt);
16068 }
16069 }
16070 }
16071 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning: dec read desc failed %d retries. rc=%d"
16072 "\n", query_retry, retval);
16073 }
16074 retval = NI_RETCODE_SUCCESS;
16075 LRETURN;
16076 }
16077 else
16078 {
16079 // We have to ensure there are adequate number of DTS for picture
16080 // reorder delay otherwise wait for more packets to be sent to decoder.
16081 ni_timestamp_table_t *p_dts_queue = p_ctx->dts_queue;
16082 if ((int)p_dts_queue->list.count < p_ctx->pic_reorder_delay + 1 &&
16083 !p_ctx->ready_to_close &&
16085 {
16086 retval = NI_RETCODE_SUCCESS;
16087 ni_log2(p_ctx, NI_LOG_DEBUG,
16088 "At least %d packets should be sent before reading the "
16089 "first frame!\n",
16090 p_ctx->pic_reorder_delay + 1);
16091 LRETURN;
16092 }
16093 p_ctx->max_retry_fail_count[1] = 0;
16094
16095 // get actual YUV transfer size if this is the stream's very first read
16096 if (0 == p_ctx->active_video_width || 0 == p_ctx->active_video_height)
16097 {
16098 retval = ni_query_stream_info(p_ctx, NI_DEVICE_TYPE_DECODER, &data);
16099 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
16100 p_ctx->device_type, p_ctx->hw_id,
16101 &(p_ctx->session_id), OPT_1);
16102 CHECK_VPU_RECOVERY(retval);
16103
16104 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec YUV query, pic size %ux%u xfer frame size "
16105 "%ux%u frame-rate %u is_flushed %u\n",
16106 data.picture_width, data.picture_height,
16108 data.frame_rate, data.is_flushed);
16111 p_ctx->actual_video_width = data.picture_width;
16112 p_ctx->pixel_format = data.pix_format;
16114 //p_ctx->bit_depth_factor = data.transfer_frame_stride / data.picture_width;
16115 p_ctx->is_first_frame = 1;
16116 p_ctx->pixel_format_changed = 0;
16117
16118 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec YUV, adjust frame size from %ux%u to "
16119 "%ux%u\n", p_frame->video_width, p_frame->video_height,
16121
16122 retval = ni_frame_buffer_alloc(
16123 p_frame, (int)p_ctx->actual_video_width, (int)p_ctx->active_video_height,
16125 p_ctx->bit_depth_factor,
16126 3, // Alloc space for write to data[3] and metadata
16127 1);
16128
16129 if (NI_RETCODE_SUCCESS != retval)
16130 {
16131 LRETURN;
16132 }
16133 total_bytes_to_read = p_frame->data_len[3] + metadata_hdr_size;
16134 p_data_buffer = (uint8_t*)p_frame->p_buffer;
16135 // make sure we don't read more than available
16136 ni_log2(p_ctx, NI_LOG_DEBUG, "Info dec buf size: %u YUV frame + meta-hdr size: %u "
16137 "available: %u\n", p_frame->buffer_size,
16138 total_bytes_to_read, buf_info.buf_avail_size);
16139 }
16140 break;
16141 }
16142 }// end while1 query retry
16143
16144 ni_log2(p_ctx, NI_LOG_DEBUG, "total_bytes_to_read %u max_nvme_io_size %u ylen %u cr len "
16145 "%u cb len %u hdr %d\n",
16146 total_bytes_to_read, p_ctx->max_nvme_io_size,
16147 p_frame->data_len[0], p_frame->data_len[1],
16148 p_frame->data_len[2], metadata_hdr_size);
16149
16150 ni_log2(p_ctx, NI_LOG_DEBUG, "p_frame->data_len[3] = %u\n", p_frame->data_len[3]);
16151 if (buf_info.buf_avail_size < total_bytes_to_read)
16152 {
16154
16155 ni_log2(p_ctx, NI_LOG_ERROR,
16156 "ERROR %s() avaliable size(%u) less than "
16157 "needed (%u)\n",
16158 __func__, buf_info.buf_avail_size, total_bytes_to_read);
16159 abort();
16160 } else if (total_bytes_to_read == metadata_hdr_size && !p_ctx->frame_num)
16161 {
16164 "6rE") >= 0)
16165 {
16166 // allocate p_data_buffer to read the first metadata
16167 void *p_metadata_buffer = NULL;
16168 int buffer_size = ((metadata_hdr_size + (NI_MEM_PAGE_ALIGNMENT - 1)) /
16170 if (ni_posix_memalign(&p_metadata_buffer, sysconf(_SC_PAGESIZE), buffer_size))
16171 {
16172 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate metadata buffer.\n",
16173 NI_ERRNO, __func__);
16175 LRETURN;
16176 }
16177 p_data_buffer = (uint8_t *)p_metadata_buffer;
16178 get_first_metadata = 1;
16179 sequence_change = 0;
16180 }
16181 }
16182
16183 //Apply read configuration here
16184 retval = ni_config_session_rw(p_ctx, SESSION_READ_CONFIG, 1,
16186 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, p_ctx->device_type,
16187 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
16188 CHECK_VPU_RECOVERY(retval);
16189
16190 read_size_bytes = total_bytes_to_read;
16192 if (read_size_bytes % NI_MEM_PAGE_ALIGNMENT)
16193 {
16194 read_size_bytes = ( (read_size_bytes / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
16195 }
16196
16197 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
16198 p_data_buffer, read_size_bytes, ui32LBA);
16199 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
16200 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
16201 CHECK_VPU_RECOVERY(retval);
16202 if (retval < 0)
16203 {
16204 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
16206 LRETURN;
16207 } else if (get_first_metadata) {
16208 // got first metadata alone
16209 ni_metadata_dec_frame_t *p_meta =
16210 (ni_metadata_dec_frame_t *)((uint8_t *)p_data_buffer);
16211 ni_log2(p_ctx, NI_LOG_DEBUG, "Got first pkt_delay_cnt %u\n",
16213 if (p_ctx->pkt_delay_cnt < p_meta->metadata_common.pkt_delay_cnt)
16215 get_first_metadata = 0;
16216 ni_aligned_free(p_data_buffer);
16217 goto start;
16218 } else
16219 {
16220 // command issued successfully, now exit
16222 p_meta =
16223 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
16224 p_frame->data_len[0] +
16225 p_frame->data_len[1] +
16226 p_frame->data_len[2] +
16227 p_frame->data_len[3]);
16228
16229 if (buf_info.buf_avail_size != metadata_hdr_size)
16230 {
16231 low_delay_notify = 1;
16232 // shift metadata to end of triple output
16233#ifdef _WIN32
16234 p_data_buffer = (uint8_t *)p_frame->p_buffer +
16236 memcpy(p_meta, p_data_buffer, metadata_hdr_size);
16237#else
16238 memcpy(p_meta,
16239 p_frame->p_buffer +
16241 metadata_hdr_size);
16242#endif
16243 sei_size = p_meta->sei_size;
16244 niFrameSurface1_t *p_data3 =
16245 (niFrameSurface1_t *)((uint8_t *)p_frame->p_buffer +
16246 p_frame->data_len[0] +
16247 p_frame->data_len[1] +
16248 p_frame->data_len[2]);
16249
16250 niFrameSurface1_t *p_data3_1 =
16251 (niFrameSurface1_t *)((uint8_t *)p_frame->p_buffer +
16252 sizeof(niFrameSurface1_t));
16253 niFrameSurface1_t *p_data3_2 =
16254 (niFrameSurface1_t *)((uint8_t *)p_frame->p_buffer +
16255 2 * sizeof(niFrameSurface1_t));
16256 // Libxcoder knows the handle so overwrite here
16257 p_data3->device_handle =
16258 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
16259 p_data3_1->device_handle =
16260 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
16261 p_data3_2->device_handle =
16262 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
16263 p_data3->ui16session_ID = p_data3_1->ui16session_ID =
16264 p_data3_2->ui16session_ID = (uint16_t)p_ctx->session_id;
16265 p_data3->src_cpu = p_data3_1->src_cpu = p_data3_2->src_cpu =
16266 (uint8_t)NI_DEVICE_TYPE_DECODER;
16267
16268 p_data3->output_idx = 0;
16269 p_data3_1->output_idx = 1;
16270 p_data3_2->output_idx = 2;
16271
16272 ni_log2(p_ctx, NI_LOG_DEBUG,
16273 "p_data3_1:sei_size=%d device_handle=%d == hw_id=%d ses_id=%d\n",
16274 sei_size, p_data3_1->device_handle, p_ctx->hw_id,
16275 p_data3_1->ui16session_ID);
16276 ni_log2(p_ctx, NI_LOG_DEBUG,
16277 "p_data3_1: ui16FrameIdx=%d NodeAddre=0x%x planar=%d bd=%d\n",
16278 p_data3_1->ui16FrameIdx, p_data3_1->ui32nodeAddress,
16279 p_data3_1->encoding_type, p_data3_1->bit_depth);
16280 ni_log2(p_ctx,
16282 "p_data3_2:sei_size=%d device_handle=%d == hw_id=%d ses_id=%d\n",
16283 sei_size, p_data3_2->device_handle, p_ctx->hw_id,
16284 p_data3_2->ui16session_ID);
16285 ni_log2(p_ctx, NI_LOG_DEBUG,
16286 "p_data3_2: ui16FrameIdx=%d NodeAddre=0x%x planar=%d bd=%d\n",
16287 p_data3_2->ui16FrameIdx, p_data3_2->ui32nodeAddress,
16288 p_data3_2->encoding_type, p_data3_2->bit_depth);
16289
16290 ni_log2(p_ctx, NI_LOG_DEBUG,
16291 "%s:sei_size=%d device_handle=%d == hw_id=%d "
16292 "ses_id=%d\n",
16293 __func__, sei_size, p_data3->device_handle, p_ctx->hw_id,
16294 p_data3->ui16session_ID);
16295 ni_log2(p_ctx, NI_LOG_DEBUG,
16296 "%s: session=0x%x ui16FrameIdx=%u NodeAddress=0x%x, "
16297 "planar=%d bd=%d\n",
16298 __func__, p_ctx->session_id, p_data3->ui16FrameIdx, p_data3->ui32nodeAddress,
16299 p_data3->encoding_type, p_data3->bit_depth);
16300 } else if (ni_cmp_fw_api_ver(
16302 "6rE") >= 0)
16303 {
16304 p_meta =
16305 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer);
16306 ni_log2(p_ctx, NI_LOG_DEBUG, "Got pkt_delay_cnt %u\n",
16308 if (p_ctx->pkt_delay_cnt < p_meta->metadata_common.pkt_delay_cnt)
16310 }
16311
16312 total_bytes_to_read = total_bytes_to_read + sei_size;
16313 ni_log2(p_ctx, NI_LOG_DEBUG,
16314 "%s decoder read desc success, retval %d "
16315 "total_bytes_to_read include sei %u sei_size %d\n",
16316 __func__, retval, total_bytes_to_read, sei_size);
16317
16318 if (total_bytes_to_read > NI_MEM_PAGE_ALIGNMENT)
16319 {
16320 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Oversized metadata!\n", __func__);
16322 LRETURN;
16323 }
16324 }
16325
16326 //bytes_read_so_far = total_bytes_to_read;
16327 // Note: session status is NOT reset but tracked between send
16328 // and recv to catch and recover from a loop condition
16329 //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
16330 bytes_read_so_far = total_bytes_to_read;
16331 //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
16333 "6sP") >= 0)
16334 {
16335 rx_size = ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, &frame_dropped, true);
16336 }
16337 else
16338 {
16339 rx_size = ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, 0, true);
16340 }
16341 p_ctx->frame_pkt_offset = frame_offset;
16342 if (p_ctx->decoder_low_delay > 0 && buf_info.buf_avail_size == metadata_hdr_size &&
16344 {
16345 ni_log2(p_ctx, NI_LOG_TRACE, "Low delay mode amd check header if has b frame\n");
16346
16347 ni_metadata_dec_frame_t *p_meta =
16348 (ni_metadata_dec_frame_t *)((uint8_t *)p_frame->p_buffer +
16349 p_frame->data_len[0] +
16350 p_frame->data_len[1] +
16351 p_frame->data_len[2]);
16352 if (p_meta->metadata_common.has_b_frame == 1)
16353 {
16354 ni_log2(p_ctx, NI_LOG_ERROR,"Warning: session 0x%x decoder lowDelay mode "
16355 "is cancelled due to has_b_frames, frame_num %u\n",
16356 p_ctx->session_id, p_ctx->frame_num);
16357 p_ctx->decoder_low_delay = 0;
16358 }
16359 }
16360
16361 if (rx_size > 0)
16362 {
16363 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): s-state %d first_frame %d\n", __func__,
16364 p_ctx->session_run_state, p_ctx->is_first_frame);
16365
16366 int64_t tmp_dts, prev_dts = INT64_MIN, ts_diff = 0;
16367 int nb_diff = 0;
16368
16370 "6sP") >= 0)
16371 {
16372 if(p_ctx->last_frame_dropped + frame_dropped != p_ctx->session_statistic.ui32FramesDropped)
16373 {
16374 ni_log2(p_ctx, NI_LOG_DEBUG,
16375 "### %s(): Warning: ui32FramesDropped %u should be %u + %u\n",
16376 __func__, p_ctx->session_statistic.ui32FramesDropped,
16377 p_ctx->last_frame_dropped, frame_dropped);
16378
16379 p_ctx->session_statistic.ui32FramesDropped = p_ctx->last_frame_dropped + frame_dropped;
16380 }
16381
16383 }
16384
16385 if (p_ctx->is_first_frame)
16386 {
16387 ni_log2(p_ctx, NI_LOG_DEBUG,
16388 "%s(): First frame : session_id 0x%x, pic_reorder_delay: %d "
16389 "total frames input:%u buffered: %u completed: %u output: %u "
16390 "dropped: %u (%u %u) error: %u\n",
16391 __func__, p_ctx->session_id, p_ctx->pic_reorder_delay,
16397 p_ctx->last_frame_dropped, frame_dropped,
16399
16400 if (p_ctx->session_statistic.ui32FramesDropped > 0)
16401 {
16402 for (i = 0; i < p_ctx->session_statistic.ui32FramesDropped; i++)
16403 {
16405 p_ctx->dts_queue, 0, &tmp_dts,
16408 {
16409 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): FramesDropped pop "
16410 "decoder dts queue %d %ld failed !\n",
16411 __func__, i, tmp_dts);
16412 break;
16413 } else
16414 {
16415 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop "
16416 "decoder dts queue %d %ld success !\n",
16417 __func__, i, tmp_dts);
16418 if (prev_dts != INT64_MIN) {
16419 ts_diff += llabs(tmp_dts - prev_dts);
16420 nb_diff++;
16421 }
16422 prev_dts = tmp_dts;
16423 }
16424 }
16425 if (nb_diff > 1)
16426 {
16427 ts_diff = ts_diff / nb_diff;
16428 }
16430 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop dts "
16431 "average diff: %ld\n", __func__, ts_diff);
16432 }
16433 }
16434 else
16435 {
16437 {
16438 for(i = p_ctx->decoder_last_drop_frame_num; i < p_ctx->session_statistic.ui32FramesDropped; i++)
16439 {
16441 p_ctx->dts_queue, 0, &tmp_dts,
16444 {
16445 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): FramesDropped pop "
16446 "decoder dts queue %d %ld failed !\n",
16447 __func__, i, tmp_dts);
16448 break;
16449 }
16450 }
16452 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): FramesDropped pop dts %d\n", __func__, p_ctx->decoder_last_drop_frame_num);
16453 }
16454 }
16455
16457 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
16460 {
16461 if (p_ctx->last_dts != NI_NOPTS_VALUE && !p_ctx->ready_to_close)
16462 {
16463 p_ctx->pic_reorder_delay++;
16464 p_frame->dts = p_ctx->last_dts + p_ctx->last_dts_interval;
16465 ni_log2(p_ctx, NI_LOG_DEBUG, "Padding DTS: %" PRId64 "\n", p_frame->dts);
16466 } else
16467 {
16468 p_frame->dts = NI_NOPTS_VALUE;
16469 }
16470 }
16471
16472 if (p_ctx->is_first_frame)
16473 {
16474 for (i = 0; (int)i < p_ctx->pic_reorder_delay; i++)
16475 {
16476 if (p_ctx->last_pts == NI_NOPTS_VALUE &&
16477 p_ctx->last_dts == NI_NOPTS_VALUE)
16478 {
16479 // If the p_frame->pts is unknown in the very beginning we assume
16480 // p_frame->pts == 0 as well as DTS less than PTS by 1000 * 1/timebase
16481 if (p_frame->pts >= p_frame->dts &&
16482 p_frame->pts - p_frame->dts < 1000)
16483 {
16484 break;
16485 }
16486 }
16487
16489 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
16491 p_ctx->frame_num % 500 == 0,
16493 {
16494 p_frame->dts = NI_NOPTS_VALUE;
16495 } else
16496 {
16497 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): pic_reorder_delay pop "
16498 "decoder dts queue %d %ld success !\n",
16499 __func__, i, p_frame->dts);
16500 }
16501 }
16502 // Reset for DTS padding counting
16503 p_ctx->pic_reorder_delay = 0;
16504 }
16505 if (p_ctx->codec_format == NI_CODEC_FORMAT_JPEG)//fw won't save frameoffset when decoding jpeg.
16506 {
16507 if (p_ctx->is_first_frame)
16508 {
16509 p_ctx->is_first_frame = 0;
16510 }
16511 p_frame->pts = p_ctx->pts_offsets[p_ctx->frame_num % NI_FIFO_SZ];
16512 p_frame->flags = p_ctx->flags_array[p_ctx->frame_num % NI_FIFO_SZ];
16513 p_frame->pkt_pos = p_ctx->pkt_pos[p_ctx->frame_num % NI_FIFO_SZ];
16514 ni_log2(p_ctx, NI_LOG_DEBUG, "p_frame->pts = %u, frame_num = %d, p_frame->dts = %u\n",
16515 p_frame->pts, p_ctx->frame_num, p_frame->dts);
16516 }
16517 else
16518 {
16519 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: frame_offset %" PRIu64 "\n", __func__,
16520 frame_offset);
16521
16522 // search for the pkt_offsets of received frame according to frame_offset.
16523 // 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)
16524 // i = -1 if not found
16525 int j = 0;
16526 j = rotated_array_binary_search(p_ctx->pkt_offsets_index_min,
16528 frame_offset);
16529 if (j >= 0)
16530 {
16531 p_frame->pts = p_ctx->pts_offsets[j];
16532 p_frame->flags = p_ctx->flags_array[j];
16533 p_frame->pkt_pos = p_ctx->pkt_pos[j];
16534 ni_log2(p_ctx, NI_LOG_DEBUG,
16535 "%s: (found pts) dts %" PRId64 " pts "
16536 "%" PRId64 " frame_offset %" PRIu64 " j %d "
16537 "pkt_offsets_index_min %" PRIu64 " "
16538 "pkt_offsets_index %" PRIu64 " pkt_pos %" PRIu64 "\n",
16539 __func__, p_frame->dts, p_frame->pts, frame_offset, j,
16540 p_ctx->pkt_offsets_index_min[j],
16541 p_ctx->pkt_offsets_index[j],
16542 p_ctx->pkt_pos[j]);
16543
16544 if (p_ctx->is_first_frame)
16545 {
16546 // if the first frame is I frame and there are dropped frames,
16547 // find the dts closest to its pts using the average of dts diff
16548 if (p_frame->dts != NI_NOPTS_VALUE &&
16549 p_frame->pts != NI_NOPTS_VALUE &&
16550 PIC_TYPE_I == p_frame->ni_pict_type &&
16552 ts_diff > 0)
16553 {
16554 while (p_frame->dts < p_frame->pts &&
16555 llabs(p_frame->pts - p_frame->dts) > ts_diff)
16556 {
16557 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: First I frame pts %ld "
16558 "dts %ld diff. %ld > ts_diff %ld\n",
16559 __func__, p_frame->pts, p_frame->dts,
16560 llabs(p_frame->pts - p_frame->dts), ts_diff);
16561
16563 p_ctx->dts_queue, 0, (int64_t *)&p_frame->dts,
16565 {
16566 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): First I frame "
16567 "pop decoder dts queue error.\n", __func__);
16568 break;
16569 }
16570 }
16571 }
16572 }
16573
16574 p_frame->p_custom_sei_set = p_ctx->pkt_custom_sei_set[j];
16575 p_ctx->pkt_custom_sei_set[j] = NULL;
16576 } else
16577 {
16578 //backup solution pts
16579 if (p_param->dec_input_params.skip_pts_guess && p_ctx->last_pts != NI_NOPTS_VALUE)
16580 {
16581 // if skip guess_correct_pts, use pts interval to get the correct pts
16582 p_frame->pts = p_ctx->last_pts + (p_ctx->last_pts_interval > 0 ? p_ctx->last_pts_interval : 1);
16583 }
16584 else
16585 {
16586 p_frame->pts = p_ctx->last_pts + (p_frame->dts - p_ctx->last_dts);
16587 }
16588 p_frame->pkt_pos = p_ctx->last_pkt_pos + (frame_offset - p_ctx->last_frame_offset);
16589 ni_log2(p_ctx, NI_LOG_ERROR,
16590 "ERROR: Frame pts %" PRId64 " not found for offset "
16591 "%" PRIu64 "\n", p_frame->pts, frame_offset);
16592 ni_log2(p_ctx, NI_LOG_DEBUG,
16593 "%s: (not found use default) dts %" PRId64 " pts %" PRId64
16594 "\n",
16595 __func__, p_frame->dts, p_frame->pts);
16596 }
16597
16598 if (p_ctx->is_first_frame)
16599 {
16600 p_ctx->is_first_frame = 0;
16601 }
16602 }
16603
16604 p_frame->orignal_pts = p_frame->pts;
16605 p_ctx->last_pkt_pos = p_frame->pkt_pos;
16606 p_ctx->last_frame_offset = frame_offset;
16607 if (!p_param->dec_input_params.skip_pts_guess)
16608 p_frame->pts = guess_correct_pts(p_ctx, p_frame->pts, p_frame->dts);
16609 if (p_frame->pts != NI_NOPTS_VALUE && p_ctx->last_pts != NI_NOPTS_VALUE)
16610 p_ctx->last_pts_interval = p_frame->pts - p_ctx->last_pts;
16611 p_ctx->last_pts = p_frame->pts;
16612 if (p_frame->dts != NI_NOPTS_VALUE && p_ctx->last_dts != NI_NOPTS_VALUE)
16613 p_ctx->last_dts_interval = p_frame->dts - p_ctx->last_dts;
16614 p_ctx->last_dts = p_frame->dts;
16615 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: (best_effort_timestamp) pts %" PRId64 "\n",
16616 __func__, p_frame->pts);
16617 p_ctx->frame_num++;
16618
16620 if (p_frame->error_ratio > 0)
16621 {
16622 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: frame number = %d, error_ratio = %u\n",
16623 __func__, p_ctx->frame_num, p_frame->error_ratio);
16624 }
16625
16626 if (p_ctx->ppu_reconfig_pkt_pos != 0 &&
16628 {
16629 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: ppu reconfig done. ppu_reconfig_pkt_pos = %u, frame_num = %u droped = %u\n",
16630 __func__, p_ctx->ppu_reconfig_pkt_pos, p_ctx->frame_num, p_ctx->session_statistic.ui32FramesDropped);
16631 p_ctx->ppu_reconfig_pkt_pos = 0;
16632 }
16633#ifdef MEASURE_LATENCY
16634#ifndef XCODER_311
16635 ni_log2(p_ctx, NI_LOG_INFO, "DEC pkt_num %d, fme_num %d, latecy is %d\n",
16636 p_ctx->pkt_num, p_ctx->frame_num, p_ctx->pkt_num - p_ctx->frame_num);
16637#endif
16638#endif
16639
16640 }
16641
16642 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): received data: [0x%08x]\n", __func__, rx_size);
16643 ni_log2(p_ctx, NI_LOG_DEBUG,
16644 "%s(): p_frame->start_of_stream=%u, "
16645 "p_frame->end_of_stream=%u, p_frame->video_width=%u, "
16646 "p_frame->video_height=%u\n",
16647 __func__, p_frame->start_of_stream, p_frame->end_of_stream,
16648 p_frame->video_width, p_frame->video_height);
16649 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): p_frame->data_len[0/1/2]=%u/%u/%u\n", __func__,
16650 p_frame->data_len[0], p_frame->data_len[1], p_frame->data_len[2]);
16651
16652 if (p_ctx->frame_num % 500 == 0)
16653 {
16654 ni_log2(p_ctx, NI_LOG_DEBUG,
16655 "Decoder pts queue size = %d dts queue size = %d\n\n",
16656 p_ctx->pts_table->list.count, p_ctx->dts_queue->list.count);
16657 // scan and clean up
16659 p_ctx->buffer_pool);
16660 }
16661
16662#ifdef MEASURE_LATENCY
16663 if ((p_frame->dts != NI_NOPTS_VALUE) && (p_ctx->frame_time_q != NULL))
16664 {
16665 uint64_t abs_time_ns = ni_gettime_ns();
16667 ni_log2(p_ctx, NI_LOG_INFO, "DTS:%" PRId64 ",DELTA:%" PRId64 ",dLAT:%" PRIu64 ";\n",
16668 p_frame->dts, abs_time_ns - q->last_benchmark_time,
16669 ni_lat_meas_q_check_latency(q, abs_time_ns, p_frame->dts));
16670 q->last_benchmark_time = abs_time_ns;
16671 }
16672#endif
16673
16674END:
16675
16677
16678 if (get_first_metadata && p_data_buffer)
16679 ni_aligned_free(p_data_buffer);
16680 if (sequence_change && p_ctx->frame_num)
16681 {
16682 if (p_ctx->actual_video_width == p_frame->video_width &&
16683 p_ctx->active_video_height == p_frame->video_height)
16684 {
16685 p_ctx->pixel_format_changed = 1;
16686 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): format changed\n", __func__);
16687 }
16688 }
16689 if (NI_RETCODE_SUCCESS != retval)
16690 {
16691 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): bad exit, retval = %d\n", __func__, retval);
16692 if (retval == NI_RETCODE_ERROR_VPU_RECOVERY)
16693 {
16694 low_delay_signal(p_ctx);
16695 }
16696
16697 return retval;
16698 } else
16699 {
16700 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit, rx_size = %d\n", __func__, rx_size);
16701 if (low_delay_notify)
16702 {
16703 low_delay_signal(p_ctx);
16704 }
16705
16706 return rx_size;
16707 }
16708}
16709
16710/*!******************************************************************************
16711* \brief Retrieve a YUV p_frame from decoder
16712*
16713* \param
16714*
16715* \return
16716*******************************************************************************/
16718{
16719 int retval = NI_RETCODE_SUCCESS;
16720 int rx_size = 0;
16721 uint64_t frame_offset = 0;
16722 uint8_t *p_data_buffer;
16723 int metadata_hdr_size = NI_FW_META_DATA_SZ -
16725 uint32_t total_bytes_to_read = 0;
16726 uint32_t read_size_bytes = 0;
16727 uint32_t ui32LBA = 0;
16728
16729 //ni_log2(p_ctx, NI_LOG_DEBUG, "hwcontext.c:ni_hwdl_frame() hwdesc %d %d %d\n",
16730 // hwdesc->ui16FrameIdx,
16731 // hwdesc->i8InstID,
16732 // hwdesc->ui16session_ID);
16733
16734 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
16735
16736 if ((!p_ctx) || (!p_frame))
16737 {
16738 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
16739 __func__);
16741 }
16742
16743 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
16744 {
16745 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
16746 __func__);
16748 LRETURN;
16749 }
16750
16751 p_data_buffer = (uint8_t *)p_frame->p_buffer;
16752
16753 if (!p_frame->p_data[0] || !p_data_buffer)
16754 {
16755 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): No receive buffer allocated.\n",
16756 __func__);
16757 retval = NI_RETCODE_INVALID_PARAM;
16758 LRETURN;
16759 }
16760
16761 if (0 == p_frame->data_len[0])
16762 {
16763 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): p_frame->data_len[0] = 0!.\n",
16764 __func__);
16765 retval = NI_RETCODE_INVALID_PARAM;
16766 LRETURN;
16767 }
16768
16770 {
16771 p_frame->data_len[2] = 0;
16772 } else if (hwdesc->encoding_type == NI_PIXEL_PLANAR_FORMAT_TILED4X4)
16773 {
16774 ni_log2(p_ctx, NI_LOG_ERROR,
16775 "ERROR %s(): NI_PIXEL_PLANAR_FORMAT_TILED4X4 not supported in download.\n",
16776 __func__);
16777 retval = NI_RETCODE_INVALID_PARAM;
16778 LRETURN;
16779 }
16780 total_bytes_to_read = p_frame->data_len[0] + p_frame->data_len[1] +
16781 p_frame->data_len[2];// +metadata_hdr_size;
16782 unsigned int bytes_read_so_far = 0;
16783 uint32_t output_chunk_offset = hwdesc->ui32nodeAddress / FRAME_CHUNK_INDEX_SIZE; //for reading output1 or output2
16784 uint32_t output_minor_offset = hwdesc->ui32nodeAddress - output_chunk_offset * FRAME_CHUNK_INDEX_SIZE;
16785 ni_log2(p_ctx, NI_LOG_DEBUG, "Total bytes to download %u, start offset = %u, chunkOffset "
16786 "%u, minorOffset %u\n",
16787 total_bytes_to_read, hwdesc->ui32nodeAddress,
16788 output_chunk_offset, output_minor_offset);
16789
16790 ni_log2(p_ctx, NI_LOG_DEBUG, "total_bytes_to_read %u max_nvme_io_size %u ylen %u cr len "
16791 "%u cb len %u hdr %d\n",
16792 total_bytes_to_read, p_ctx->max_nvme_io_size,
16793 p_frame->data_len[0], p_frame->data_len[1],
16794 p_frame->data_len[2], metadata_hdr_size);
16795
16796 //Apply read configuration here
16797 retval =
16799 (output_minor_offset << NI_CODEC_HW_PAYLOAD_OFFSET) |
16801 hwdesc->ui16FrameIdx);
16802 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, hwdesc->src_cpu,
16803 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
16804 CHECK_VPU_RECOVERY(retval);
16805 if (retval < 0)
16806 {
16807 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
16809 LRETURN;
16810 } else
16811 {
16812 ni_log2(p_ctx, NI_LOG_DEBUG,
16813 "Config HW download read desc success, retval %d total_bytes_to_read %u\n",
16814 retval, total_bytes_to_read);
16815 }
16816
16817 read_size_bytes = total_bytes_to_read;
16818 ui32LBA = READ_INSTANCE_R(p_ctx->session_id, hwdesc->src_cpu);
16819 ui32LBA += output_chunk_offset;
16820 if (read_size_bytes % NI_MEM_PAGE_ALIGNMENT)
16821 {
16822 read_size_bytes = ( (read_size_bytes / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
16823 }
16824
16825 retval = ni_nvme_send_read_cmd(
16826 (ni_device_handle_t)(int64_t)hwdesc->device_handle,
16827 NI_INVALID_DEVICE_HANDLE, p_data_buffer, read_size_bytes, ui32LBA);
16828 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, hwdesc->src_cpu,
16829 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
16830 CHECK_VPU_RECOVERY(retval);
16831 if (retval < 0)
16832 {
16833 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
16835 LRETURN;
16836 } else
16837 {
16838 ni_log2(p_ctx, NI_LOG_DEBUG,
16839 "HW download read desc success, retval %d total_bytes_to_read %u\n",
16840 retval, total_bytes_to_read);
16841 }
16842
16843 //Unset applied read configuration here
16844 retval = ni_config_session_rw(p_ctx, SESSION_READ_CONFIG, 0, 0, 0);
16845 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config, hwdesc->src_cpu,
16846 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
16847 CHECK_VPU_RECOVERY(retval);
16848
16849 if (retval < 0)
16850 {
16851 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
16853 LRETURN;
16854 } else
16855 {
16856 ni_log2(p_ctx, NI_LOG_DEBUG,
16857 "Unconfig HW download read desc success, retval %d total_bytes_to_read %u\n",
16858 retval, total_bytes_to_read);
16859 }
16860
16861 bytes_read_so_far = total_bytes_to_read;
16862 // Note: session status is NOT reset but tracked between send
16863 // and recv to catch and recover from a loop condition
16864
16865 if (p_ctx->is_auto_dl)
16866 rx_size = (int)bytes_read_so_far;
16867 else
16868 {
16869 rx_size =
16870 ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, 0, false);
16871 p_ctx->frame_pkt_offset = frame_offset;
16872 }
16873
16874 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): received data: [0x%08x]\n",
16875 __func__, rx_size);
16876 ni_log2(p_ctx, NI_LOG_DEBUG,
16877 "%s(): p_frame->start_of_stream=%u, "
16878 "p_frame->end_of_stream=%u, p_frame->video_width=%u, "
16879 "p_frame->video_height=%u\n",
16880 __func__, p_frame->start_of_stream, p_frame->end_of_stream,
16881 p_frame->video_width, p_frame->video_height);
16882 ni_log2(p_ctx, NI_LOG_DEBUG,
16883 "%s(): p_ctx->frame_num %" PRIu64 ", "
16884 "p_frame->data_len[0/1/2]=%u/%u/%u\n",
16885 __func__, p_ctx->frame_num, p_frame->data_len[0], p_frame->data_len[1],
16886 p_frame->data_len[2]);
16887
16888 //if (decq_count % 500 == 0)
16889 //{
16890 // ni_log2(p_ctx, NI_LOG_DEBUG, "Decoder pts queue size = %d dts queue size = %d\n\n",
16891 // p_ctx->pts_table->list.count, p_ctx->dts_queue)->list.count);
16892 // // scan and clean up
16893 // ni_timestamp_scan_cleanup(p_ctx->pts_table, p_ctx->dts_queue, p_ctx->buffer_pool);
16894 //}
16895
16896END:
16897
16898 if (NI_RETCODE_SUCCESS != retval)
16899 {
16900 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): bad exit, retval = %d\n", __func__, retval);
16901 return retval;
16902 } else
16903 {
16904 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit, rx_size = %d\n", __func__, rx_size);
16905 return rx_size;
16906 }
16907}
16908
16909int ni_hwdownload_by_frame_idx(niFrameSurface1_t* hwdesc, ni_frame_t* p_frame, int is_auto_dl)
16910{
16911 int retval = NI_RETCODE_SUCCESS;
16912 int rx_size = 0;
16913 uint64_t frame_offset = 0;
16914 uint8_t *p_data_buffer;
16915 int metadata_hdr_size = NI_FW_META_DATA_SZ -
16917 uint32_t total_bytes_to_read = 0;
16918 uint32_t read_size_bytes = 0;
16919 uint32_t ui32LBA = 0;
16920 ni_global_session_stats_t *global_state;
16921 const char *error_flag = "NetintQuadraErr";
16922
16923 ni_log(NI_LOG_TRACE, "%s(): enter\n", __func__);
16924
16925 p_data_buffer = (uint8_t *)p_frame->p_buffer;
16926
16927 if (!p_frame->p_data[0] || !p_data_buffer || 0 == p_frame->data_len[0])
16928 {
16929 ni_log(NI_LOG_ERROR, "ERROR %s(): passed parameters are null or p_frame->data_len is 0.\n",
16930 __func__);
16931 retval = NI_RETCODE_INVALID_PARAM;
16932 LRETURN;
16933 }
16934
16936 {
16937 p_frame->data_len[2] = 0;
16938 } else if (hwdesc->encoding_type >= NI_PIXEL_PLANAR_FORMAT_TILED4X4)
16939 {
16941 "ERROR %s(): Unsupported format %d for hw download.\n",
16942 __func__, hwdesc->encoding_type);
16943 retval = NI_RETCODE_INVALID_PARAM;
16944 LRETURN;
16945 }
16946 total_bytes_to_read = p_frame->data_len[0] + p_frame->data_len[1] +
16947 p_frame->data_len[2];// +metadata_hdr_size;
16948 unsigned int bytes_read_so_far = 0;
16949 uint32_t output_chunk_offset = hwdesc->ui32nodeAddress / FRAME_CHUNK_INDEX_SIZE; //for reading output1 or output2
16950 uint32_t output_minor_offset = hwdesc->ui32nodeAddress - output_chunk_offset * FRAME_CHUNK_INDEX_SIZE;
16951
16952 ni_log(NI_LOG_DEBUG, "total_bytes_to_read %u ylen %u cr len "
16953 "%u cb len %u hdr %d\n",
16954 total_bytes_to_read,
16955 p_frame->data_len[0], p_frame->data_len[1],
16956 p_frame->data_len[2], metadata_hdr_size);
16957
16958 // preset content of buffer, if not refresh means download fail
16959 memset(p_data_buffer, 0, NI_DATA_BUFFER_LEN);
16960 global_state = (ni_global_session_stats_t *)p_data_buffer;
16961 memcpy(global_state->error_flag, error_flag, strlen(error_flag)+1);
16962 global_state->check_flag[0] = global_state->check_flag[2] = 0x0;
16963 global_state->check_flag[1] = global_state->check_flag[3] = 0xFF;
16964
16965 read_size_bytes = total_bytes_to_read;
16966 ui32LBA = DOWNLOAD_FRAMEIDX_R(hwdesc->ui16FrameIdx);
16967 ui32LBA += output_chunk_offset;
16968 if (read_size_bytes % NI_MEM_PAGE_ALIGNMENT)
16969 {
16970 read_size_bytes = ( (read_size_bytes / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT) + NI_MEM_PAGE_ALIGNMENT;
16971 }
16972 ni_log(NI_LOG_DEBUG, "Total bytes to download %u, start offset = %u, chunkOffset "
16973 "%u, minorOffset %u hwdesc->ui16FrameIdx %d ui32LBA 0x%x\n",
16974 total_bytes_to_read, hwdesc->ui32nodeAddress,
16975 output_chunk_offset, output_minor_offset, hwdesc->ui16FrameIdx, ui32LBA);
16976
16977 retval = ni_nvme_send_read_cmd(
16978 (ni_device_handle_t)(int64_t)hwdesc->device_handle,
16979 NI_INVALID_DEVICE_HANDLE, p_data_buffer, read_size_bytes, ui32LBA);
16980
16981 if (retval < 0)
16982 {
16983 ni_log(NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
16985 LRETURN;
16986 }
16987 global_state = (ni_global_session_stats_t *)p_data_buffer;
16988 if (!strcmp(global_state->error_flag, error_flag) &&
16989 global_state->check_flag[0] == 0x0 && global_state->check_flag[1] == 0xFF &&
16990 global_state->check_flag[2] == 0x0 && global_state->check_flag[3] == 0xFF) {
16991 ni_log(NI_LOG_ERROR, "ERROR %s(): nvme download failed, invalid frameidx %u or "
16992 "size %u + offset %u out of range\n",
16993 __func__, hwdesc->ui16FrameIdx, read_size_bytes, output_chunk_offset);
16994 retval = NI_RETCODE_INVALID_PARAM;
16995 LRETURN;
16996 }
16997
16998 bytes_read_so_far = total_bytes_to_read;
16999 // Note: session status is NOT reset but tracked between send
17000 // and recv to catch and recover from a loop condition
17001
17002 if (is_auto_dl)
17003 rx_size = (int)bytes_read_so_far;
17004 else
17005 {
17006 rx_size =
17007 ni_create_frame(p_frame, bytes_read_so_far, &frame_offset, 0, false);
17008 }
17009
17011 "HW download read desc success, retval %d total_bytes_to_read %u\n",
17012 retval, total_bytes_to_read);
17013
17014END:
17015
17016 if (NI_RETCODE_SUCCESS != retval)
17017 {
17018 ni_log(NI_LOG_ERROR, "%s(): bad exit, retval = %d\n", __func__, retval);
17019 return retval;
17020 } else
17021 {
17022 ni_log(NI_LOG_TRACE, "%s(): exit, rx_size = %d\n", __func__, rx_size);
17023 return rx_size;
17024 }
17025}
17026
17028 ni_frameclone_desc_t *p_frameclone_desc)
17029{
17030 int retval = NI_RETCODE_SUCCESS;
17031 uint8_t *p_data = NULL;
17032 uint32_t dataLen;
17033 uint32_t ui32LBA = 0;
17034
17035 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
17036
17037 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
17038 {
17039 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17040 __func__);
17042 LRETURN;
17043 }
17044
17045 dataLen = (sizeof(ni_frameclone_desc_t) + NI_MEM_PAGE_ALIGNMENT - 1) &
17046 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17047 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
17048 {
17049 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
17050 NI_ERRNO, __func__);
17052 LRETURN;
17053 }
17054 memset(p_data, 0, dataLen);
17055 memcpy(p_data, p_frameclone_desc, sizeof(ni_frameclone_desc_t));
17056 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): ui16DstIdx %u, ui16SrcIdx %u, size %u, offset %u\n", __func__,
17057 p_frameclone_desc->ui16DstIdx, p_frameclone_desc->ui16SrcIdx,
17058 p_frameclone_desc->ui32Size, p_frameclone_desc->ui32Offset);
17059
17060 ui32LBA = CONFIG_SESSION_FRAME_COPY_W(p_ctx->session_id);
17061 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, NI_INVALID_EVENT_HANDLE,
17062 p_data, dataLen, ui32LBA);
17064 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
17065 OPT_1);
17066 CHECK_VPU_RECOVERY(retval);
17067 if (NI_RETCODE_SUCCESS != retval)
17068 {
17069 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n",
17070 __func__);
17072 LRETURN;
17073 }
17074
17075END:
17076 ni_aligned_free(p_data);
17077 if (NI_RETCODE_SUCCESS != retval)
17078 {
17079 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): bad exit, retval = %d\n", __func__, retval);
17080 }
17081 return retval;
17082}
17083
17084/*!******************************************************************************
17085* \brief Close an xcoder upload instance
17086*
17087* \param p_ctx pointer to uploader session context
17088*
17089* \return NI_RETCODE_SUCCESS
17090*******************************************************************************/
17092{
17093#ifndef _WIN32
17094 if (p_ctx->isP2P)
17095 {
17096 if (p_ctx->netint_fd)
17097 {
17098 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: close driver fd %d\n", __func__,
17099 p_ctx->netint_fd);
17100 close(p_ctx->netint_fd);
17101 }
17102 }
17103#endif
17104 return NI_RETCODE_SUCCESS;
17105}
17106
17107/*!******************************************************************************
17108* \brief Send a p_config command to configure uploading parameters.
17109*
17110* \param ni_session_context_t p_ctx - xcoder Context
17111* \param[in] pool_size pool size to create
17112* \param[in] pool 0 = normal pool, 1 = P2P pool
17113*
17114* \return - NI_RETCODE_SUCCESS on success,
17115* NI_RETCODE_ERROR_INVALID_SESSION
17116* NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
17117*******************************************************************************/
17119 uint32_t pool_size,
17120 uint32_t pool)
17121{
17122 void* p_uploader_config = NULL;
17123 ni_uploader_config_t* p_cfg = NULL;
17124 uint32_t buffer_size = sizeof(ni_encoder_config_t);
17126 uint32_t ui32LBA = 0;
17127 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
17128
17129 if (!p_ctx)
17130 {
17131 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
17132 __func__);
17133 retval = NI_RETCODE_INVALID_PARAM;
17134 LRETURN;
17135 }
17136
17137 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
17138 {
17139 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17140 __func__);
17142 LRETURN;
17143 }
17144
17145 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
17146 if (ni_posix_memalign(&p_uploader_config, sysconf(_SC_PAGESIZE),
17147 buffer_size))
17148 {
17149 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
17150 NI_ERRNO, __func__);
17152 LRETURN;
17153 }
17154 memset(p_uploader_config, 0, buffer_size);//
17155
17156 p_cfg = (ni_uploader_config_t*)p_uploader_config;
17157 p_cfg->ui16picWidth = p_ctx->active_video_width;
17158 p_cfg->ui16picHeight = p_ctx->active_video_height;
17159 p_cfg->ui8poolSize = pool_size;
17160 p_cfg->ui8PixelFormat = p_ctx->pixel_format;
17161 p_cfg->ui8Pool = pool;
17162 p_cfg->ui32lumaLinesize = 0; // cannot support config linesize yet because ni_frames_init is called when filter graph is created (no frame linesize info)
17163 p_cfg->ui32chromaLinesize = 0;
17164 bool isrgb = ((NI_PIX_FMT_RGBA == p_cfg->ui8PixelFormat) || (NI_PIX_FMT_BGRA == p_cfg->ui8PixelFormat) ||
17165 (NI_PIX_FMT_ARGB == p_cfg->ui8PixelFormat) || (NI_PIX_FMT_ABGR == p_cfg->ui8PixelFormat) ||
17166 (NI_PIX_FMT_BGR0 == p_cfg->ui8PixelFormat));
17170 {
17171 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);
17172 retval = NI_RETCODE_INVALID_PARAM;
17173 LRETURN;
17174 }
17175
17176 ni_log2(p_ctx, NI_LOG_DEBUG, "ni_config_instance_set_uploader_params():%d x %d x Format %d with %d framepool\n",
17177 p_cfg->ui16picWidth, p_cfg->ui16picHeight, p_cfg->ui8PixelFormat, p_cfg->ui8poolSize);
17178
17179 //configure the session here
17180 ui32LBA =
17182
17183 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17184 p_uploader_config, buffer_size, ui32LBA);
17186 p_ctx->device_type, p_ctx->hw_id,
17187 &(p_ctx->session_id), OPT_1);
17188 if (NI_RETCODE_SUCCESS != retval)
17189 {
17190 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);
17191 //Close the session since we can't configure it
17192 retval = ni_encoder_session_close(p_ctx, 0);
17193 if (NI_RETCODE_SUCCESS != retval)
17194 {
17195 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);
17196 }
17197
17199 }
17200 else
17201 {
17203 }
17204
17205END:
17206
17207 ni_aligned_free(p_uploader_config);
17208 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
17209
17210 return retval;
17211}
17212
17213/*!******************************************************************************
17214* \brief Send a p_config command to configure decoding parameters.
17215*
17216* \param ni_session_context_t p_ctx - xcoder Context
17217* \param uint32_t max_pkt_size - overwrite maximum packet size if nonzero
17218*
17219* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
17220*******************************************************************************/
17222{
17223 void* p_decoder_config = NULL;
17224 uint32_t buffer_size = sizeof(ni_decoder_config_t);
17226 uint32_t ui32LBA = 0;
17227 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
17228
17229 if (!p_ctx)
17230 {
17231 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
17232 __func__);
17233 retval = NI_RETCODE_INVALID_PARAM;
17234 LRETURN;
17235 }
17236
17237 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
17238 {
17239 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17240 __func__);
17242 LRETURN;
17243 }
17244
17245 if (ni_cmp_fw_api_ver((char*)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rT") < 0)
17246 {
17247 ni_log2(p_ctx, NI_LOG_INFO, "%s() FW rev %s < 6rT-- load balancing might be affected\n", __func__,
17249 }
17250
17251 buffer_size = ((buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
17252 if (ni_posix_memalign(&p_decoder_config, sysconf(_SC_PAGESIZE), buffer_size))
17253 {
17254 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate p_decoder_config buffer\n",
17255 NI_ERRNO, __func__);
17257 LRETURN;
17258 }
17259 memset(p_decoder_config, 0, buffer_size);
17260
17261 ni_set_custom_dec_template(p_ctx, p_decoder_config, p_ctx->p_session_config, max_pkt_size);
17262 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));
17263 if (NI_RETCODE_PARAM_WARN == retval)
17264 {
17265 ni_log2(p_ctx, NI_LOG_INFO, "WARNING: %s . %s\n", __func__, p_ctx->param_err_msg);
17266 (void)fflush(stdout);
17267 }
17268 else if (NI_RETCODE_SUCCESS != retval)
17269 {
17270 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s failed. %s\n", __func__,
17271 p_ctx->param_err_msg);
17272 (void)fflush(stdout);
17273 retval = NI_RETCODE_INVALID_PARAM;
17274 LRETURN;
17275 }
17276
17277 // configure the session here
17279
17280 //Flip the bytes!!
17281 //p_cfg = (ni_decoder_config_t*)p_decoder_config;
17282 //p_cfg->i32picWidth = ni_htonl(p_cfg->i32picWidth);
17283 //p_cfg->i32picHeight = ni_htonl(p_cfg->i32picHeight);
17284 //p_cfg->i32meBlkMode = ni_htonl(p_cfg->i32meBlkMode);
17285 //p_cfg->i32frameRateInfo = ni_htonl(p_cfg->i32frameRateInfo);
17286 //p_cfg->i32vbvBufferSize = ni_htonl(p_cfg->i32vbvBufferSize);
17287 //p_cfg->i32userQpMax = ni_htonl(p_cfg->i32userQpMax);
17288 //p_cfg->i32maxIntraSize = ni_htonl(p_cfg->i32maxIntraSize);
17289 //p_cfg->i32userMaxDeltaQp = ni_htonl(p_cfg->i32userMaxDeltaQp);
17290 //p_cfg->i32userMinDeltaQp = ni_htonl(p_cfg->i32userMinDeltaQp);
17291 //p_cfg->i32userQpMin = ni_htonl(p_cfg->i32userQpMin);
17292 //p_cfg->i32bitRate = ni_htonl(p_cfg->i32bitRate);
17293 //p_cfg->i32bitRateBL = ni_htonl(p_cfg->i32bitRateBL);
17294 //p_cfg->i32srcBitDepth = ni_htonl(p_cfg->i32srcBitDepth);
17295 //p_cfg->hdrEnableVUI = ni_htonl(p_cfg->hdrEnableVUI);
17296 //p_cfg->ui32VuiDataSizeBits = ni_htonl(p_cfg->ui32VuiDataSizeBits);
17297 //p_cfg->ui32VuiDataSizeBytes = ni_htonl(p_cfg->ui32VuiDataSizeBytes);
17298 //p_cfg->i32hwframes = ni_htonl(p_cfg->i32hwframes);
17299 // flip the 16 bytes of the reserved field using 32 bits pointers
17300 //for (i = 0; i < (16 >> 2); i++)
17301 //{
17302 // ((uint32_t*)p_cfg->ui8Reserved)[i] = ni_htonl(((uint32_t*)p_cfg->ui8Reserved)[i]);
17303 //}
17305 //for (i = 0; i < (NI_MAX_VUI_SIZE >> 2); i++) // apply on 32 bits
17306 //{
17307 // ((uint32_t*)p_cfg->ui8VuiRbsp)[i] = ni_htonl(((uint32_t*)p_cfg->ui8VuiRbsp)[i]);
17308 //}
17309
17310 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: ui32LBA = 0x%x\n", __func__, ui32LBA);
17311 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17312 p_decoder_config, buffer_size, ui32LBA);
17314 p_ctx->device_type, p_ctx->hw_id,
17315 &(p_ctx->session_id), OPT_1);
17316 if (NI_RETCODE_SUCCESS != retval)
17317 {
17318 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);
17319 //Close the session since we can't configure it
17320 retval = ni_decoder_session_close(p_ctx, 0);
17321 if (NI_RETCODE_SUCCESS != retval)
17322 {
17323 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);
17324 }
17325
17327 }
17328
17329END:
17330
17331 ni_aligned_free(p_decoder_config);
17332 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
17333 return retval;
17334}
17335
17336/*!******************************************************************************
17337* \brief Send a p_config command to configure decoding parameters.
17338*
17339* \param ni_session_context_t p_ctx - xcoder Context
17340* \param uint32_t max_pkt_size - overwrite maximum packet size if nonzero
17341*
17342* \return - NI_RETCODE_SUCCESS on success, NI_RETCODE_ERROR_INVALID_SESSION, NI_RETCODE_ERROR_NVME_CMD_FAILED on failure
17343*******************************************************************************/
17345 void *p_dec_ppu_config, int buffer_size)
17346{
17347 void* p_ppu_config = NULL;
17348 // uint32_t buffer_size = sizeof(ni_decoder_output_picture_size);
17349 uint32_t tmp_buffer_size = buffer_size;
17351 uint32_t ui32LBA = 0;
17352
17353 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
17354
17355 if (!p_ctx || !p_dec_ppu_config)
17356 {
17357 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
17358 __func__);
17359 retval = NI_RETCODE_INVALID_PARAM;
17360 LRETURN;
17361 }
17362
17363 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
17364 {
17365 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17366 __func__);
17368 LRETURN;
17369 }
17370
17372
17373 if (ni_cmp_fw_api_ver((char*)&p_ctx->fw_rev[NI_XCODER_REVISION_API_MAJOR_VER_IDX], "6rT") < 0)
17374 {
17375 ni_log2(p_ctx, NI_LOG_INFO, "%s() FW rev %s < 6rT-- load balancing might be affected\n", __func__,
17377 }
17378
17379 tmp_buffer_size = ((tmp_buffer_size + (NI_MEM_PAGE_ALIGNMENT - 1)) / NI_MEM_PAGE_ALIGNMENT) * NI_MEM_PAGE_ALIGNMENT;
17380 if (ni_posix_memalign(&p_ppu_config, sysconf(_SC_PAGESIZE), tmp_buffer_size))
17381 {
17382 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate memory\n",
17383 NI_ERRNO, __func__);
17385 LRETURN;
17386 }
17387 memset(p_ppu_config, 0, tmp_buffer_size);
17388
17389 memcpy(p_ppu_config, p_dec_ppu_config, buffer_size);
17390 // configure the session here
17392
17393 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17394 p_ppu_config, tmp_buffer_size, ui32LBA);
17396 p_ctx->device_type, p_ctx->hw_id,
17397 &(p_ctx->session_id), OPT_1);
17398 if (NI_RETCODE_SUCCESS != retval)
17399 {
17400 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);
17402 //Close the session since we can't configure it
17403 retval = ni_decoder_session_close(p_ctx, 0);
17404 if (NI_RETCODE_SUCCESS != retval)
17405 {
17406 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);
17407 }
17410 }
17411
17412END:
17413
17415 ni_aligned_free(p_ppu_config);
17416 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
17417 return retval;
17418}
17419
17420/*!******************************************************************************
17421 * \brief read a hardware descriptor from a scaler session
17422 *
17423 * \param[in] p_ctx pointer to session context
17424 * \param[out] p_frame pointer to frame to write hw descriptor
17425 *
17426 * \return NI_RETCODE_INVALID_PARAM
17427 * NI_RETCODE_ERROR_INVALID_SESSION
17428 * NI_RETCODE_ERROR_MEM_ALOC
17429 * NI_RETCODE_ERROR_NVME_CMD_FAILED
17430 * NI_RETCODE_FAILURE
17431 *******************************************************************************/
17433 ni_session_context_t *p_ctx,
17434 ni_frame_t *p_frame)
17435{
17436 ni_retcode_t retval;
17437 ni_instance_buf_info_t sInstanceBuf = {0};
17438 niFrameSurface1_t *pFrameSurface;
17439 int query_retry = 0;
17440
17441 if (!p_ctx || !p_frame || !p_frame->p_data[3])
17442 {
17443 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
17444 __func__);
17446 }
17447
17448 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
17449 {
17450 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17451 __func__);
17453 }
17454
17455 if (p_ctx->buffered_frame_index)
17456 {
17457 pFrameSurface = (niFrameSurface1_t *) p_frame->p_data[3];
17458 pFrameSurface->ui16FrameIdx = p_ctx->buffered_frame_index;
17459 pFrameSurface->ui16session_ID = p_ctx->session_id;
17460 pFrameSurface->device_handle =
17461 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
17462 pFrameSurface->src_cpu = (uint8_t) NI_DEVICE_TYPE_SCALER;
17463 pFrameSurface->output_idx = 0;
17464
17465 p_ctx->buffered_frame_index = 0;
17466 return NI_RETCODE_SUCCESS;
17467 }
17468
17470
17471 for (;;)
17472 {
17473 query_retry++;
17474
17475 ni_log2(p_ctx, NI_LOG_DEBUG, "%s: query by ni_query_instance_buf_info INST_BUF_INFO_RW_UPLOAD\n",
17476 __func__);
17478 NI_DEVICE_TYPE_SCALER, &sInstanceBuf);
17479
17480 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
17481 p_ctx->device_type, p_ctx->hw_id,
17482 &(p_ctx->session_id), OPT_3);
17483
17485 {
17486 if (query_retry >= 1000)
17487 {
17488 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning hwdesc read fail rc %d\n", retval);
17489 LRETURN;
17490 }
17491 }
17492 else if (retval != NI_RETCODE_SUCCESS)
17493 {
17494 LRETURN;
17495 }
17496 else
17497 {
17498 pFrameSurface = (niFrameSurface1_t *) p_frame->p_data[3];
17499 pFrameSurface->ui16FrameIdx = sInstanceBuf.hw_inst_ind.frame_index;
17500 pFrameSurface->ui16session_ID = p_ctx->session_id;
17501 pFrameSurface->device_handle =
17502 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
17503 pFrameSurface->src_cpu = (uint8_t) NI_DEVICE_TYPE_SCALER;
17504 pFrameSurface->output_idx = 0;
17505
17506 /* A frame index of zero is invalid, the memory acquisition failed */
17507 if (pFrameSurface->ui16FrameIdx == 0)
17508 {
17509 if (query_retry >= 1000)
17510 {
17511 ni_log2(p_ctx, NI_LOG_ERROR, "Error: 2D could not acquire frame\n");
17512 retval = NI_RETCODE_FAILURE;
17513 LRETURN;
17514 }
17515 ni_usleep(100);
17516 continue;
17517 }
17518
17519 ni_log2(p_ctx, NI_LOG_DEBUG,
17520 "Session=0x%x: %s got FrameIndex=%u\n",
17521 p_ctx->session_id,
17522 __func__,
17523 pFrameSurface->ui16FrameIdx);
17524
17525 LRETURN;
17526 }
17527 }
17528
17529END:
17530
17532
17533 if (NI_RETCODE_SUCCESS != retval)
17534 {
17535 ni_log2(p_ctx, NI_LOG_DEBUG,
17536 "%s Warning scalar read hwdesc fail rc %d or ind !\n",
17537 __func__, retval);
17538 retval = NI_RETCODE_FAILURE;
17539 }
17540
17541 return retval;
17542}
17543
17544/*!******************************************************************************
17545* \brief Grab bitdepth factor from NI_PIX_FMT
17546*
17547* \param[in] pix_fmt ni_pix_fmt_t
17548*
17549* \return 1 or 2 for success, -1 for error
17550*******************************************************************************/
17552{
17553 switch (pix_fmt)
17554 {
17555 case NI_PIX_FMT_YUV420P:
17556 case NI_PIX_FMT_NV12:
17558 return 1;
17560 case NI_PIX_FMT_P010LE:
17562 return 2;
17563 default:
17564 {
17565 ni_log(NI_LOG_ERROR, "ERROR: %s() non applicable format %d\n", __func__,
17566 pix_fmt);
17567 break;
17568 }
17569 }
17570 return -1;
17571}
17572
17573/*!******************************************************************************
17574* \brief Grab planar info from NI_PIX_FMT
17575*
17576* \param[in] pix_fmt ni_pix_fmt_t
17577*
17578* \return 0 or 1 for success, -1 for error
17579*******************************************************************************/
17581{
17582 switch (pix_fmt)
17583 {
17584 case NI_PIX_FMT_YUV420P:
17586 case NI_PIX_FMT_ABGR:
17587 case NI_PIX_FMT_ARGB:
17588 case NI_PIX_FMT_RGBA:
17589 case NI_PIX_FMT_BGRA:
17590 return 1;
17591 break;
17592 case NI_PIX_FMT_NV12:
17593 case NI_PIX_FMT_P010LE:
17594 return 0;
17595 break;
17596 default:
17597 {
17598 ni_log(NI_LOG_ERROR, "ERROR: %s() non applicable format %d\n", __func__,
17599 pix_fmt);
17600 break;
17601 }
17602 }
17603 return -1;
17604}
17605
17606#ifndef _WIN32
17607/*!*****************************************************************************
17608 * \brief Get an address offset from a hw descriptor
17609 *
17610 * \param[in] p_ctx ni_session_context_t to be referenced
17611 * \param[in] hwdesc Pointer to caller allocated niFrameSurface1_t
17612 * \param[out] p_offset Value of offset
17613 *
17614 * \return On success NI_RETCODE_SUCCESS
17615 * On failure NI_RETCODE_INVALID_PARAM
17616 ******************************************************************************/
17618 uint32_t *p_offset)
17619{
17620 if (!hwdesc)
17621 {
17622 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed null parameter\n", __func__);
17624 }
17625
17626 if (hwdesc->ui16FrameIdx <= NI_GET_MIN_HWDESC_P2P_BUF_ID(p_ctx->ddr_config) ||
17628 {
17629 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() pass invalid data. "
17630 "FrameIdx %d OOR (%d,%d]. DDR config %d \n", __func__, hwdesc->ui16FrameIdx,
17632 p_ctx->ddr_config);
17634 }
17635
17636 *p_offset = (hwdesc->ui16FrameIdx - NI_GET_MIN_HWDESC_P2P_BUF_ID(p_ctx->ddr_config)) *
17638
17639 return NI_RETCODE_SUCCESS;
17640}
17641#endif
17642
17643/* AI functions */
17645 void *nb_data, uint32_t nb_size)
17646{
17647 void *p_ai_config = NULL;
17648 void *p_nb_data = NULL;
17649 uint32_t buffer_size;
17650 // uint8_t *p_data;
17651 // uint32_t transferred, this_size;
17653 uint32_t ui32LBA = 0;
17654 uint32_t config_size;
17655 void *p_buffer = NULL;
17656 uint32_t dataLen;
17657 ni_instance_buf_info_t buf_info = {0};
17658 int retry_count = 0;
17659
17660 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
17661
17662 if (!p_ctx)
17663 {
17664 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
17665 __func__);
17667 }
17668
17669 if (!nb_data || nb_size == 0) {
17670 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() invalid nb_data %p nb_size %u\n",
17671 __func__, nb_data, nb_size);
17673 }
17674
17676
17677 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
17678 {
17679 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17680 __func__);
17682 LRETURN;
17683 }
17684
17685 config_size = (sizeof(ni_ai_config_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
17686 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17687 if (ni_posix_memalign(&p_ai_config, sysconf(_SC_PAGESIZE), config_size))
17688 {
17689 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate ai config buffer.\n");
17691 LRETURN;
17692 }
17693
17694 ((ni_ai_config_t *)p_ai_config)->ui32NetworkBinarySize = nb_size;
17695 ni_calculate_sha256(nb_data, nb_size,
17696 ((ni_ai_config_t *)p_ai_config)->ui8Sha256);
17697
17698 buffer_size =
17699 (nb_size + (NI_MEM_PAGE_ALIGNMENT - 1)) & ~(NI_MEM_PAGE_ALIGNMENT - 1);
17700 if (ni_posix_memalign(&p_nb_data, sysconf(_SC_PAGESIZE), buffer_size))
17701 {
17702 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate encConf buffer.\n");
17704 LRETURN;
17705 }
17706
17707 memcpy(p_nb_data, nb_data, nb_size);
17708
17709 /* configure network binary size to be written */
17711 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): LBA 0x%x, nb_size %u\n", __func__, ui32LBA,
17712 ((ni_ai_config_t *)p_ai_config)->ui32NetworkBinarySize);
17713
17714 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17715 p_ai_config, config_size, ui32LBA);
17717 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17718 if (NI_RETCODE_SUCCESS != retval)
17719 {
17720 ni_log2(p_ctx, NI_LOG_ERROR,
17721 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
17722 ", hw_id, %u, xcoder_inst_id: %d\n",
17723 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17724 //Close the session since we can't configure it
17725 retval = ni_ai_session_close(p_ctx, 0);
17726 if (NI_RETCODE_SUCCESS != retval)
17727 {
17728 ni_log2(p_ctx, NI_LOG_ERROR,
17729 "ERROR: ni_ai_session_close failed: blk_io_handle: %" PRIx64
17730 ", hw_id, %u, xcoder_inst_id: %d\n",
17731 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
17732 p_ctx->session_id);
17733 }
17734
17736 LRETURN;
17737 }
17738
17739 dataLen = (sizeof(ni_network_layer_info_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
17740 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17741 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
17742 {
17743 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate buffer.\n");
17745 LRETURN;
17746 }
17747
17748 for (;;)
17749 {
17750 /* test if the model is already exist. if not, then continue to write binary data */
17751 memset(p_buffer, 0, dataLen);
17753 "6J") >= 0)
17754 {
17755 ui32LBA = QUERY_INSTANCE_NL_SIZE_V2_R(p_ctx->session_id,
17757 } else
17758 {
17759 ui32LBA =
17761 }
17762 retval =
17764 p_buffer, dataLen, ui32LBA);
17765 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
17766 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17767 if (retval != NI_RETCODE_SUCCESS)
17768 {
17769 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
17771 LRETURN;
17772 }
17773 if (((ni_instance_buf_info_t *)p_buffer)->buf_avail_size > 0)
17774 {
17775 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): network binary registered\n", __func__);
17776 LRETURN;
17777 }
17778
17779 /* if this model is not ready, try to require nbuffer to write */
17781 NI_DEVICE_TYPE_AI, &buf_info);
17782 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
17783 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17784 if (retval != NI_RETCODE_SUCCESS)
17785 {
17786 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Query Write buffer Failed\n", __func__);
17787 LRETURN;
17788 }
17789 if (buf_info.buf_avail_size < nb_size)
17790 {
17791 /*
17792 * Cannot aquire the write access to nbuffer because someone else on the go,
17793 * Retry to see if model is ready.
17794 */
17795 ni_log2(p_ctx, NI_LOG_TRACE,
17796 "AI write query failed or buf_size %u < "
17797 "frame_size %u.\n", buf_info.buf_avail_size, nb_size);
17798 } else
17799 {
17800 /* Grant write access to nbuffer */
17801 ni_log2(p_ctx, NI_LOG_DEBUG,
17802 "Info ai write query success, available buf "
17803 "size %u >= frame size %u !\n",
17804 buf_info.buf_avail_size, nb_size);
17805 break;
17806 }
17807 retry_count++;
17808 /* Wait for at least 30s */
17810 {
17812 ni_usleep(100);
17814 } else
17815 {
17816 ni_log2(p_ctx, NI_LOG_DEBUG, "AI network binary configuration polling timeout\n");
17818 LRETURN;
17819 }
17820 }
17821
17822#if 1
17823 /* write network binary data */
17825 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): write nb LBA 0x%x\n", __func__, ui32LBA);
17826 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17827 p_nb_data, buffer_size, ui32LBA);
17828 ni_log2(p_ctx, NI_LOG_DEBUG, "write complete retval %d\n", retval);
17829 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
17830 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17831 if (NI_RETCODE_SUCCESS != retval)
17832 {
17833 ni_log2(p_ctx, NI_LOG_ERROR,
17834 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
17835 ", hw_id, %u, xcoder_inst_id: %d\n",
17836 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17837 //Close the session since we can't configure it
17838 retval = ni_ai_session_close(p_ctx, 0);
17839 if (NI_RETCODE_SUCCESS != retval)
17840 {
17841 ni_log2(p_ctx, NI_LOG_ERROR,
17842 "ERROR: ni_ai_session_close failed: blk_io_handle: %" PRIx64
17843 ", hw_id, %u, xcoder_inst_id: %d\n",
17844 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
17845 p_ctx->session_id);
17846 }
17847
17849 LRETURN;
17850 }
17851
17852#else
17853 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): write nb buffer_size %u\n", __func__,
17854 buffer_size);
17855 for (transferred = 0; transferred < buffer_size; transferred += this_size)
17856 {
17857 this_size = p_ctx->max_nvme_io_size < (buffer_size - transferred) ?
17858 p_ctx->max_nvme_io_size :
17859 (buffer_size - transferred);
17860
17861 if (this_size & (4096 - 1))
17862 {
17863 this_size = (this_size + (4096 - 1)) & ~(4096 - 1);
17864 }
17865 /* write network binary data */
17866 ui32LBA = WRITE_INSTANCE_W(p_ctx->session_id, NI_DEVICE_TYPE_AI) +
17867 (transferred >> 12);
17868 ni_log2(p_ctx, NI_LOG_DEBUG,
17869 "%s(): write nb LBA 0x%x, this_size %u, page_offset %u\n",
17870 __func__, ui32LBA, this_size, (transferred >> 12));
17871 p_data = (uint8_t *)p_nb_data + transferred;
17872 retval = ni_nvme_send_write_cmd(
17873 p_ctx->blk_io_handle, p_ctx->event_handle,
17874 (uint8_t *)p_nb_data + transferred, this_size, ui32LBA);
17875 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): write retval %d\n", __func__, retval);
17876 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
17877 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17878 if (NI_RETCODE_SUCCESS != retval)
17879 {
17880 ni_log(
17882 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
17883 ", hw_id, %u, xcoder_inst_id: %d\n",
17884 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
17885 //Close the session since we can't configure it
17886 retval = ni_ai_session_close(p_ctx, 0);
17887 if (NI_RETCODE_SUCCESS != retval)
17888 {
17889 ni_log(
17891 "ERROR: ni_ai_session_close failed: blk_io_handle: %" PRIx64
17892 ", hw_id, %u, xcoder_inst_id: %d\n",
17893 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
17894 p_ctx->session_id);
17895 }
17896
17898 LRETURN;
17899 }
17900 }
17901
17902#endif
17903
17904END:
17906
17907 ni_aligned_free(p_ai_config);
17908 ni_aligned_free(p_nb_data);
17909 ni_aligned_free(p_buffer);
17910
17911 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
17912
17913 return retval;
17914}
17915
17917{
17918 void *p_stream_info = NULL;
17919 void *p_ai_config = NULL;
17920 void *p_nb_data = NULL;
17922 uint32_t ui32LBA = 0;
17923 uint32_t config_size;
17924
17925 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
17926
17927 if (!p_ctx)
17928 {
17929 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
17930 __func__);
17931 retval = NI_RETCODE_INVALID_PARAM;
17932 LRETURN;
17933 }
17934
17936
17937 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
17938 {
17939 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
17940 __func__);
17942 LRETURN;
17943 }
17944
17945 config_size = (sizeof(ni_instance_mgr_stream_info_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
17946 ~(NI_MEM_PAGE_ALIGNMENT - 1);
17947
17948 if (ni_posix_memalign(&p_stream_info, sysconf(_SC_PAGESIZE), config_size))
17949 {
17950 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate stream info buffer.\n");
17952 LRETURN;
17953 }
17954
17955 ((ni_instance_mgr_stream_info_t *)p_stream_info)->picture_width = p_ctx->active_video_width;
17956 ((ni_instance_mgr_stream_info_t *)p_stream_info)->picture_height = p_ctx->active_video_height;
17957 if (p_ctx->hvsplus_type == 0)
17958 {
17959 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_model_type = AI_MODEL_TYPE_HVSPLUS_FILTER;
17960 }
17961 else
17962 {
17965 "6sW") >= 0)
17966 {
17967 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_model_type = AI_MODEL_TYPE_USM_FILTER;
17968 }
17969 else
17970 {
17971 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: USM filter not support for FW version lower than 6sW\n");
17972 retval = NI_RETCODE_INVALID_PARAM;
17973 LRETURN;
17974 }
17975 }
17976 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_enhance_level = p_ctx->hvsplus_level;
17977 ((ni_instance_mgr_stream_info_t *)p_stream_info)->pix_format = p_ctx->pixel_format;
17978
17979 ni_log2(p_ctx, NI_LOG_DEBUG,
17980 "### %s: width %d %d height %d model type %d level %d pix_format %d\n", __func__,
17981 p_ctx->active_video_width, p_ctx->ori_width, p_ctx->active_video_height,
17982 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_model_type,
17983 ((ni_instance_mgr_stream_info_t *)p_stream_info)->ai_enhance_level,
17984 ((ni_instance_mgr_stream_info_t *)p_stream_info)->pix_format);
17985
17986 /* configure AI manager to load the suitable network binary */
17988 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));
17989
17990 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
17991 p_stream_info, config_size, ui32LBA);
17993 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
17994 if (NI_RETCODE_SUCCESS != retval)
17995 {
17996 ni_log2(p_ctx, NI_LOG_ERROR,
17997 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
17998 ", hw_id, %u, xcoder_inst_id: %d\n",
17999 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
18000 //Close the session since we can't configure it
18001 retval = ni_ai_session_close(p_ctx, 0);
18002 if (NI_RETCODE_SUCCESS != retval)
18003 {
18004 ni_log2(p_ctx, NI_LOG_ERROR,
18005 "ERROR: ni_ai_session_close failed: blk_io_handle: %" PRIx64
18006 ", hw_id, %u, xcoder_inst_id: %d\n",
18007 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
18008 p_ctx->session_id);
18009 }
18010
18012 LRETURN;
18013 }
18014
18015END:
18017
18018 ni_aligned_free(p_ai_config);
18019 ni_aligned_free(p_nb_data);
18020 ni_aligned_free(p_stream_info);
18021
18022 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18023
18024 return retval;
18025}
18026
18028{
18030 void *p_buffer = NULL;
18031 uint32_t ui32LBA = 0;
18032 int retry_count = 0;
18033 uint32_t dataLen = (sizeof(ni_network_layer_info_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
18034 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18035 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
18036 {
18037 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: Cannot allocate buffer.\n");
18039 LRETURN;
18040 }
18041 for(;;)
18042 {
18043 memset(p_buffer, 0, dataLen);
18044 ui32LBA =
18046 retval =
18048 p_buffer, dataLen, ui32LBA);
18049 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
18050 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18051 if (retval != NI_RETCODE_SUCCESS)
18052 {
18053 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
18054 }
18055 if (((ni_instance_buf_info_t *)p_buffer)->buf_avail_size > 0)
18056 {
18057 ni_log2(p_ctx, NI_LOG_INFO, "%s(): network binary registered\n", __func__);
18058 break;
18059 }
18060
18061 retry_count++;
18062 /* Wait for at least 30s */
18064 {
18065 ni_usleep(100);
18066 } else
18067 {
18068 ni_log2(p_ctx, NI_LOG_DEBUG, "AI network binary configuration polling timeout\n");
18070 LRETURN;
18071 }
18072 }
18073END:
18074
18075 ni_aligned_free(p_buffer);
18076 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18077
18078 return retval;
18079
18080}
18081
18083 ni_frame_t *p_frame)
18084{
18086 uint32_t ui32LBA = 0;
18087 ni_instance_buf_info_t buf_info = {0};
18088 uint32_t frame_size_bytes;
18089 uint32_t sent_size = 0;
18090 int32_t query_retry = 0;
18091 uint32_t dataLen;
18092 ni_network_buffer_info_t *buffer_info = NULL;
18093
18094 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
18095
18096 if (!p_ctx || !p_frame)
18097 {
18098 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): passed parameters is null\n",
18099 __func__);
18100 retval = NI_RETCODE_INVALID_PARAM;
18101 return retval;
18102 }
18103
18104 if (p_frame->data_len[0] == 0)
18105 {
18106 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() invalid data length\n",
18107 __func__);
18108 retval = NI_RETCODE_INVALID_PARAM;
18109 return retval;
18110 }
18111
18113
18114
18115 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
18116 {
18117 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
18118 __func__);
18120 LRETURN;
18121 }
18122
18123 frame_size_bytes = p_frame->data_len[0];
18124 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): frame_size_bytes %u\n", __func__,
18125 frame_size_bytes);
18126
18127 for (;;)
18128 {
18129 if (p_ctx->session_statistic.ui32WrBufAvailSize >= frame_size_bytes)
18130 {
18131 buf_info.buf_avail_size =
18133 ni_log2(p_ctx, NI_LOG_DEBUG,
18134 "Info ai write query success, available buf "
18135 "size %u >= frame size %u !\n",
18136 buf_info.buf_avail_size, frame_size_bytes);
18137 break;
18138 }
18139
18141 "6K") >= 0)
18142 {
18144 &p_ctx->session_statistic);
18145 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
18147 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
18148 buf_info.buf_avail_size =
18150 } else
18151 {
18153 NI_DEVICE_TYPE_AI, &buf_info);
18154 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
18155 p_ctx->device_type, p_ctx->hw_id,
18156 &(p_ctx->session_id), OPT_1);
18157 }
18158 if (NI_RETCODE_SUCCESS != retval ||
18159 buf_info.buf_avail_size < frame_size_bytes)
18160 {
18161 ni_log2(p_ctx, NI_LOG_TRACE,
18162 "AI write query failed or buf_size < frame_size. Retry %d\n",
18163 query_retry);
18164 // extend to 5000 retries for 8K encode on FPGA
18165 if (query_retry >= NI_MAX_ENCODER_QUERY_RETRIES)
18166 {
18167 ni_log2(p_ctx, NI_LOG_DEBUG,
18168 "AI write query exceeded max retries: %d\n",
18171 retval = NI_RETCODE_SUCCESS;
18172 LRETURN;
18173 }
18177 query_retry++;
18178 }
18179 }
18180
18182 < 0 || p_frame->iovec_num <= 1) {
18183 void *p_data;
18184 if (p_frame->iovec_num == 1) {
18185 if (!p_frame->iovec) {
18186 ni_log2(p_ctx, NI_LOG_ERROR, "Ai session write: invaid iovec\n");
18187 retval = NI_RETCODE_INVALID_PARAM;
18188 LRETURN;
18189 }
18190 if (!p_frame->iovec[0].ptr || p_frame->iovec[0].size == 0 ||
18191 ((int64_t)p_frame->iovec[0].ptr & (NI_MEM_PAGE_ALIGNMENT - 1))) {
18192 ni_log2(p_ctx, NI_LOG_ERROR, "Ai session write: invalid iovec ptr 0x%lx, size %u\n",
18193 (int64_t)p_frame->iovec[0].ptr, p_frame->iovec[0].size);
18194 retval = NI_RETCODE_INVALID_PARAM;
18195 LRETURN;
18196 }
18197 p_data = p_frame->iovec[0].ptr;
18198 } else {
18199 p_data = p_frame->p_buffer; //equals to p_frame->p_data[0]
18200 }
18202 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai session write: p_data = %p, p_frame->buffer_size = %u, "
18203 "p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
18204 p_data, p_frame->buffer_size, p_ctx->frame_num,
18205 ui32LBA);
18206
18207 sent_size = frame_size_bytes;
18208 if (sent_size & (NI_MEM_PAGE_ALIGNMENT - 1))
18209 {
18210 sent_size = (sent_size + NI_MEM_PAGE_ALIGNMENT - 1) &
18211 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18212 }
18213
18214 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
18215 p_data, sent_size, ui32LBA);
18217 "6K") >= 0)
18218 {
18219 if (retval != NI_RETCODE_SUCCESS)
18220 {
18221 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18223 LRETURN;
18224 }
18226 &p_ctx->session_statistic);
18227 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
18229 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
18230 } else
18231 {
18232 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
18233 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18234 if (retval < 0)
18235 {
18236 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18238 LRETURN;
18239 }
18240 }
18241 } else { //for iovec
18242 //validate iovec
18243 uint32_t i;
18244 uint32_t rel_offset = 0;
18245 int32_t iovec_index = 0;
18246 int32_t iovec_left;
18247
18248 if (!p_frame->iovec) {
18249 ni_log2(p_ctx, NI_LOG_ERROR, "Ai session write: invaid iovec\n");
18250 retval = NI_RETCODE_INVALID_PARAM;
18251 LRETURN;
18252 }
18253
18254 for (i = 0; i < p_frame->iovec_num; i++) {
18255 ni_iovec_t *this_iovec = &p_frame->iovec[i];
18256
18257 ni_log2(p_ctx, NI_LOG_DEBUG, "iovec %d, ptr %p, size %u\n", i,
18258 this_iovec->ptr, this_iovec->size);
18259 if ((this_iovec->ptr == NULL) || (this_iovec->size == 0) ||
18260 ((int64_t)this_iovec->ptr & (NI_MEM_PAGE_ALIGNMENT - 1))) {
18261 ni_log2(p_ctx, NI_LOG_ERROR, "Ai session write: invalid iovec ptr 0x%lx, size %u\n",
18262 (int64_t)this_iovec->ptr, this_iovec->size);
18263 retval = NI_RETCODE_INVALID_PARAM;
18264 LRETURN;
18265 }
18266 }
18267
18268 //1, write iovec details
18269 dataLen = (sizeof(ni_network_buffer_info_t) + NI_MEM_PAGE_ALIGNMENT - 1) &
18270 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18271 if (ni_posix_memalign((void **)&buffer_info, sysconf(_SC_PAGESIZE), dataLen))
18272 {
18273 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
18274 NI_ERRNO, __func__);
18276 }
18277 memset(buffer_info, 0x00, dataLen);
18278
18279 //2, write iovec
18280 iovec_left = (int32_t)p_frame->iovec_num;
18281 do {
18282 int iovec_batch = iovec_left < NI_MAX_SEGMENT_NUM ? iovec_left : NI_MAX_SEGMENT_NUM;
18283 uint32_t rel_lba = 0;
18284
18285 buffer_info->ui16Option = NI_AI_FLAG_IOVEC;
18286 buffer_info->ui32IovecNum = iovec_batch;
18287 buffer_info->ui32RelOffset = rel_offset;
18288 for (i = 0; (int)i < iovec_batch; i++) {
18289 ni_iovec_t *iovec = &p_frame->iovec[iovec_index + i];
18290 buffer_info->segment[i].ui32RelLba = rel_lba;
18291 buffer_info->segment[i].ui32Size = iovec->size;
18292 rel_lba += (((iovec->size + NI_MEM_PAGE_ALIGNMENT - 1) &
18293 ~(NI_MEM_PAGE_ALIGNMENT - 1)) >> LBA_BIT_OFFSET) + 1;
18294 rel_offset += iovec->size;
18295 }
18296 ni_log2(p_ctx, NI_LOG_DEBUG, "Dev alloc frame: frame_index %u\n",
18297 buffer_info->ui16FrameIdx[0]);
18298
18299 ui32LBA =
18301
18302 retval =
18304 buffer_info, dataLen, ui32LBA);
18305 //CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_config,
18306 // p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
18307 // OPT_1);
18308 if (NI_RETCODE_SUCCESS != retval)
18309 {
18310 ni_log2(p_ctx,
18312 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
18313 ", hw_id, %u, xcoder_inst_id: %d\n",
18314 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
18315 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n",
18316 __func__);
18318 LRETURN;
18319 }
18320
18321#ifdef __linux__
18322 for (i = 0; (int)i < iovec_batch; i++) {
18323 ni_iovec_t *iovec = &p_frame->iovec[iovec_index + i];
18324 ni_segment_t *segment = &buffer_info->segment[i];
18325 ui32LBA = WRITE_INSTANCE_W(p_ctx->session_id, NI_DEVICE_TYPE_AI) + segment->ui32RelLba;
18326 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai session write: data = %p, size = %u, "
18327 "p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
18328 iovec->ptr, iovec->size, p_ctx->frame_num, ui32LBA);
18329 ni_nvme_setup_aio_iocb(p_ctx->blk_io_handle, p_ctx->iocbs[i], iovec->ptr,
18330 (iovec->size + NI_MEM_PAGE_ALIGNMENT - 1) & ~(NI_MEM_PAGE_ALIGNMENT - 1),
18331 ui32LBA, 1);
18332 }
18333
18334 retval = ni_nvme_batch_cmd_aio(p_ctx->aio_context, p_ctx->iocbs, p_ctx->io_event, iovec_batch);
18335 if (retval != NI_RETCODE_SUCCESS) {
18336 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to do batch io\n", __func__);
18337 LRETURN;
18338 }
18339#else
18340 for (i = 0; (int)i < iovec_batch; i++) {
18341 ni_iovec_t *iovec = &p_frame->iovec[iovec_index + i];
18342 ui32LBA = WRITE_INSTANCE_W(p_ctx->session_id, NI_DEVICE_TYPE_AI) + rel_lba;
18343 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai session write: data = %p, size = %u, "
18344 "p_ctx->frame_num = %" PRIu64 ", LBA = 0x%x\n",
18345 iovec->ptr, iovec->size, p_ctx->frame_num,
18346 ui32LBA);
18347
18348 sent_size = (iovec->size + NI_MEM_PAGE_ALIGNMENT - 1) &
18349 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18350 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
18351 iovec->ptr, sent_size, ui32LBA);
18352 if (retval != NI_RETCODE_SUCCESS) {
18353 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18354 LRETURN;
18355 }
18356 rel_lba = (((iovec->size + NI_MEM_PAGE_ALIGNMENT - 1) &
18357 ~(NI_MEM_PAGE_ALIGNMENT - 1)) >> LBA_BIT_OFFSET) + 1;
18358 }
18359#endif
18360 iovec_index += iovec_batch;
18361 iovec_left -= iovec_batch;
18362 } while (iovec_left);
18363
18365 "6K") >= 0)
18366 {
18367 if (retval != NI_RETCODE_SUCCESS)
18368 {
18369 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18371 LRETURN;
18372 }
18374 &p_ctx->session_statistic);
18375 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
18377 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
18378 } else
18379 {
18380 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_write, p_ctx->device_type,
18381 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18382 if (retval < 0)
18383 {
18384 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18386 LRETURN;
18387 }
18388 }
18389 }
18390
18391 p_ctx->frame_num++;
18392
18393 retval = (int)frame_size_bytes; // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange) - returns byte count on success
18394
18395END:
18396
18398
18399 free(buffer_info);
18400
18401 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18402
18403 return retval;
18404}
18405
18407 ni_packet_t *p_packet)
18408{
18409 uint32_t actual_read_size = 0;
18410 int retval = NI_RETCODE_SUCCESS;
18411 uint32_t ui32LBA = 0;
18412 ni_instance_buf_info_t buf_info = {0};
18413
18414 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
18415
18416 if (!p_ctx || !p_packet || !p_packet->p_data)
18417 {
18418 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18419 __func__);
18420 retval = NI_RETCODE_INVALID_PARAM;
18421 return retval;
18422 }
18423
18425
18426 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
18427 {
18428 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
18429 __func__);
18431 LRETURN;
18432 }
18433
18434 for (;;)
18435 {
18436 if (p_ctx->session_statistic.ui32RdBufAvailSize >= p_packet->data_len)
18437 {
18438 buf_info.buf_avail_size =
18440 ni_log2(p_ctx, NI_LOG_DEBUG,
18441 "Info ai read query success, available buf "
18442 "size %u >= frame size %u !\n",
18443 buf_info.buf_avail_size, p_packet->data_len);
18444 break;
18445 }
18447 "6K") >= 0)
18448 {
18450 &p_ctx->session_statistic);
18451 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
18453 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
18454 buf_info.buf_avail_size =
18456 } else
18457 {
18459 NI_DEVICE_TYPE_AI, &buf_info);
18460 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
18461 p_ctx->device_type, p_ctx->hw_id,
18462 &(p_ctx->session_id), OPT_1);
18463 }
18464 ni_log2(p_ctx, NI_LOG_TRACE,
18465 "Info ai read query rc %d, available buf size %u, "
18466 "frame_num=%" PRIu64 ", pkt_num=%" PRIu64 "\n",
18467 retval, buf_info.buf_avail_size, p_ctx->frame_num,
18468 p_ctx->pkt_num);
18469
18470 if (NI_RETCODE_SUCCESS != retval)
18471 {
18472 ni_log2(p_ctx, NI_LOG_DEBUG, "Buffer info query failed in ai read!!!!\n");
18473 LRETURN;
18474 } else if (0 == buf_info.buf_avail_size)
18475 {
18476 ni_log2(p_ctx, NI_LOG_DEBUG, "Info ai read available buf size %u, eos %u !\n",
18477 buf_info.buf_avail_size, p_packet->end_of_stream);
18478 retval = NI_RETCODE_SUCCESS;
18479 LRETURN;
18480 }
18481 }
18482 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai read buf_avail_size %u\n", buf_info.buf_avail_size);
18483
18484 assert(buf_info.buf_avail_size >= p_packet->data_len);
18485
18486 ui32LBA = READ_INSTANCE_R(p_ctx->session_id, NI_DEVICE_TYPE_AI);
18487 actual_read_size = p_packet->data_len;
18488 if (actual_read_size & (NI_MEM_PAGE_ALIGNMENT - 1))
18489 {
18490 actual_read_size = (actual_read_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
18491 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18492 }
18493
18494 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
18495 p_packet->p_data, actual_read_size, ui32LBA);
18497 "6K") >= 0)
18498 {
18499 if (retval != NI_RETCODE_SUCCESS)
18500 {
18501 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18503 LRETURN;
18504 }
18506 &p_ctx->session_statistic);
18507 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
18509 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
18510 } else
18511 {
18512 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
18513 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18514 if (retval < 0)
18515 {
18516 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed\n", __func__);
18518 LRETURN;
18519 }
18520 }
18521
18522 retval = (int)p_packet->data_len;
18523
18524END:
18525
18527
18528 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18529
18530 return retval;
18531}
18532
18533static void ni_unreference_network_data(ni_network_data_t *network_data)
18534{
18535 if (network_data)
18536 {
18537 ni_memfree(network_data->inset);
18538 ni_memfree(network_data->linfo.in_param);
18539 }
18540}
18541
18543 ni_network_data_t *p_network)
18544{
18545 void *p_buffer = NULL;
18546 void *p_info = NULL;
18548 uint32_t ui32LBA = 0;
18549 uint32_t dataLen;
18550 int32_t query_retry = 0;
18551 uint32_t l;
18552 ni_network_layer_params_t *layer_param;
18553 uint32_t buffer_size;
18554 uint32_t this_size;
18555 ni_network_data_t *network_data = NULL;
18556 uint32_t total_io_num;
18557
18558 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
18559
18560 if (!p_ctx || !p_network)
18561 {
18562 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18563 __func__);
18564 retval = NI_RETCODE_INVALID_PARAM;
18565 LRETURN;
18566 }
18567
18568 network_data = p_ctx->network_data;
18569 if (network_data->linfo.in_param != NULL)
18570 {
18571 ni_log2(p_ctx, NI_LOG_ERROR,
18572 "ERROR: %s(): network parameters data is already initialized\n",
18573 __func__);
18574 retval = NI_RETCODE_SUCCESS;
18575 LRETURN;
18576 }
18577
18579
18580 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
18581 {
18582 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
18583 __func__);
18585 LRETURN;
18586 }
18587
18588 /* query available size can be read. */
18589 dataLen = (sizeof(ni_instance_buf_info_t) + (NI_MEM_PAGE_ALIGNMENT - 1)) &
18590 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18591 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
18592 {
18593 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
18594 NI_ERRNO, __func__);
18596 LRETURN;
18597 }
18598 memset(p_buffer, 0, dataLen);
18599
18600 for (;;)
18601 {
18603 "6J") >= 0)
18604 {
18605 ui32LBA = QUERY_INSTANCE_NL_SIZE_V2_R(p_ctx->session_id,
18607 } else
18608 {
18609 ui32LBA =
18611 }
18612 retval =
18614 p_buffer, dataLen, ui32LBA);
18615 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
18616 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18617 if (retval != NI_RETCODE_SUCCESS)
18618 {
18619 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
18621 LRETURN;
18622 }
18623
18624 if (((ni_instance_buf_info_t *)p_buffer)->buf_avail_size > 0)
18625 {
18626 break;
18627 }
18628
18629 query_retry++;
18630 if (query_retry > 50000)
18631 {
18632 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): exceeded max query retries: %d\n",
18633 __func__, query_retry - 1);
18635 LRETURN;
18636 }
18638 ni_usleep(200);
18640 continue;
18641 }
18642
18643 if (((ni_instance_buf_info_t *)p_buffer)->buf_avail_size == 0)
18644 {
18646 LRETURN;
18647 }
18648
18650 "6J") >= 0)
18651 {
18652 network_data->input_num =
18653 ((ni_instance_buf_info_t *)p_buffer)->buf_avail_size >> 16;
18654 network_data->output_num =
18655 ((ni_instance_buf_info_t *)p_buffer)->buf_avail_size & 0xFFFF;
18656 } else
18657 {
18658 network_data->input_num = 4;
18659 network_data->output_num = 4;
18660 }
18661
18662 total_io_num = network_data->input_num + network_data->output_num;
18663
18664 network_data->linfo.in_param = (ni_network_layer_params_t *)calloc(
18665 total_io_num, sizeof(ni_network_layer_params_t));
18666 if (!network_data->linfo.in_param)
18667 {
18668 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Unable to allocate network layer params\n",
18669 __func__);
18671 LRETURN;
18672 }
18673 network_data->linfo.out_param =
18674 network_data->linfo.in_param + network_data->input_num;
18675
18676 network_data->inset = (ni_network_layer_offset_t *)calloc(
18677 total_io_num, sizeof(ni_network_layer_offset_t));
18678 if (!network_data->inset)
18679 {
18680 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): Unable to allocate network offset\n",
18681 __func__);
18683 LRETURN;
18684 }
18685 network_data->outset = network_data->inset + network_data->input_num;
18686
18688 "6J") >= 0)
18689 {
18690 /* query the real network layer data */
18691 this_size = sizeof(ni_network_layer_params_t) * total_io_num;
18692 dataLen = (this_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
18693 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18694 if (ni_posix_memalign(&p_info, sysconf(_SC_PAGESIZE), dataLen))
18695 {
18696 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate info buffer\n",
18697 NI_ERRNO, __func__);
18699 LRETURN;
18700 }
18701 memset(p_info, 0, dataLen);
18702
18704 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
18705 p_info, dataLen, ui32LBA);
18706 if ((int32_t)retval < 0)
18707 {
18708 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
18710 LRETURN;
18711 }
18712 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
18713 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18714 memcpy(network_data->linfo.in_param, p_info, this_size);
18715 } else
18716 {
18717 /* query the real network layer data */
18718 this_size = sizeof(ni_network_layer_params_t) * total_io_num;
18719 dataLen = (this_size + (NI_MEM_PAGE_ALIGNMENT - 1)) &
18720 ~(NI_MEM_PAGE_ALIGNMENT - 1);
18721 if (ni_posix_memalign(&p_info, sysconf(_SC_PAGESIZE), dataLen))
18722 {
18723 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate info buffer\n",
18724 NI_ERRNO, __func__);
18726 LRETURN;
18727 }
18728 memset(p_info, 0, dataLen);
18729
18731 retval = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
18732 p_info, dataLen, ui32LBA);
18733 if ((int32_t)retval < 0)
18734 {
18735 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
18737 LRETURN;
18738 }
18739 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
18740 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18741 memcpy(network_data->linfo.in_param, p_info, this_size);
18742
18743 for (l = 0, network_data->input_num = 0; l < 4; l++)
18744 {
18745 layer_param = &network_data->linfo.in_param[l];
18746 if (layer_param->num_of_dims == 0)
18747 {
18748 break;
18749 }
18750 network_data->input_num++;
18751 }
18752
18753 for (l = 0, network_data->output_num = 0; l < 4; l++)
18754 {
18755 layer_param = &network_data->linfo.out_param[l];
18756 if (layer_param->num_of_dims == 0)
18757 {
18758 break;
18759 }
18760 network_data->output_num++;
18761 }
18762 }
18763
18764 for (l = 0, buffer_size = 0; l < network_data->input_num; l++)
18765 {
18766 layer_param = &network_data->linfo.in_param[l];
18767 this_size = ni_ai_network_layer_size(layer_param);
18768 this_size =
18769 (this_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
18770 network_data->inset[l].offset = (int32_t)buffer_size;
18771 buffer_size += this_size;
18772
18773 ni_log2(p_ctx,
18775 "%s(): network input layer %d: dims %u, %u/%u/%u/%u, f %d, q %d\n",
18776 __func__, l, layer_param->num_of_dims, layer_param->sizes[0],
18777 layer_param->sizes[1], layer_param->sizes[2], layer_param->sizes[3],
18778 layer_param->data_format, layer_param->quant_format);
18779 }
18780
18781 for (l = 0, buffer_size = 0; l < network_data->output_num; l++)
18782 {
18783 layer_param = &network_data->linfo.out_param[l];
18784 this_size = ni_ai_network_layer_size(layer_param);
18785 this_size =
18786 (this_size + NI_AI_HW_ALIGN_SIZE - 1) & ~(NI_AI_HW_ALIGN_SIZE - 1);
18787 network_data->outset[l].offset = (int32_t)buffer_size;
18788 buffer_size += this_size;
18789
18790 ni_log2(p_ctx,
18792 "%s(): network output layer %d: dims %u, %u/%u/%u/%u, f %d, q %d\n",
18793 __func__, l, layer_param->num_of_dims, layer_param->sizes[0],
18794 layer_param->sizes[1], layer_param->sizes[2], layer_param->sizes[3],
18795 layer_param->data_format, layer_param->quant_format);
18796 }
18797
18798 memcpy(p_network, network_data, sizeof(ni_network_data_t));
18799
18800 retval = NI_RETCODE_SUCCESS;
18801
18802END:
18804
18805 if (retval != NI_RETCODE_SUCCESS)
18806 {
18807 ni_unreference_network_data(network_data);
18808 }
18809 ni_aligned_free(p_buffer);
18810 ni_aligned_free(p_info);
18811 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
18812 return retval;
18813}
18814
18816{
18818 void *p_buffer = NULL;
18819 uint32_t ui32LBA = 0;
18820
18821 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
18822
18823 if (!p_ctx)
18824 {
18825 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
18826 __func__);
18827 retval = NI_RETCODE_INVALID_PARAM;
18828 LRETURN;
18829 }
18830
18831 //Check if there is an instance or we need a new one
18832 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
18833 {
18835 p_ctx->pts_table = NULL;
18836 p_ctx->dts_queue = NULL;
18837 p_ctx->buffer_pool = NULL;
18838 p_ctx->status = 0;
18839 p_ctx->key_frame_type = 0;
18840 p_ctx->keyframe_factor = 1;
18841 p_ctx->frame_num = 0;
18842 p_ctx->pkt_num = 0;
18843 p_ctx->rc_error_count = 0;
18844 p_ctx->force_frame_type = 0;
18845 p_ctx->ready_to_close = 0;
18846 //Sequence change tracking reated stuff
18847 p_ctx->active_video_width = 0;
18848 p_ctx->active_video_height = 0;
18849 p_ctx->p_all_zero_buf = NULL;
18850 p_ctx->actual_video_width = 0;
18852 memset(&(p_ctx->param_err_msg[0]), 0, sizeof(p_ctx->param_err_msg));
18853
18854 //malloc zero data buffer
18855 if (ni_posix_memalign(&p_ctx->p_all_zero_buf, sysconf(_SC_PAGESIZE),
18857 {
18858 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc all zero buffer failed\n",
18859 NI_ERRNO, __func__);
18861 LRETURN;
18862 }
18863 memset(p_ctx->p_all_zero_buf, 0, NI_DATA_BUFFER_LEN);
18864
18865 //malloc data buffer
18866 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
18868 {
18869 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
18870 NI_ERRNO, __func__);
18872 LRETURN;
18873 }
18874 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
18875
18876 //Set session ID to be invalid. In case we cannot open session, the session id wold remain invalid.
18877 //In case we can open sesison, the session id would become valid.
18878 ((ni_session_stats_t *)p_buffer)->ui16SessionId =
18879 (uint16_t)NI_INVALID_SESSION_ID;
18880
18881 // First uint32_t is either an invaild session ID or a valid session ID, depending on if session could be opened
18882 ui32LBA = OPEN_SESSION_CODEC(NI_DEVICE_TYPE_AI, 0, p_ctx->hw_action);
18883 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): LBA 0x%x, hw_action %d\n", __func__,
18884 ui32LBA, p_ctx->hw_action);
18885 retval =
18887 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
18888 if (retval != NI_RETCODE_SUCCESS)
18889 {
18890 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR ni_nvme_send_read_cmd\n");
18891 LRETURN;
18892 }
18893 //Open will return a session status structure with a valid session id if it worked.
18894 //Otherwise the invalid session id set before the open command will stay
18895 if ((uint16_t)NI_INVALID_SESSION_ID ==
18896 ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId))
18897 {
18898 ni_log2(p_ctx, NI_LOG_ERROR,
18899 "ERROR %s(): p_ctx->device_handle=%" PRIx64
18900 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
18901 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
18902 p_ctx->session_id);
18903 ni_ai_session_close(p_ctx, 0);
18905 LRETURN;
18906 }
18907 p_ctx->session_id =
18908 ni_ntohs(((ni_session_stats_t *)p_buffer)->ui16SessionId);
18909 p_ctx->session_timestamp = ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_high);
18910 p_ctx->session_timestamp = (p_ctx->session_timestamp << 32) |
18911 ni_htonl(((ni_session_stats_t *)p_buffer)->ui32Session_timestamp_low);
18912 ni_log2(p_ctx, NI_LOG_DEBUG, "Ai open session ID:0x%x,timestamp:%" PRIu64 "\n",
18913 p_ctx->session_id, p_ctx->session_timestamp);
18914
18915 ni_log2(p_ctx, NI_LOG_DEBUG, "Open session completed\n");
18916 ni_log2(p_ctx, NI_LOG_DEBUG,
18917 "%s(): p_ctx->device_handle=%" PRIx64
18918 ", p_ctx->hw_id=%d, p_ctx->session_id=%d\n",
18919 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
18920 p_ctx->session_id);
18921
18922 //Send keep alive timeout Info
18923 uint64_t keep_alive_timeout =
18924 (uint64_t)p_ctx->keep_alive_timeout * 1000000; //send us to FW
18925 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
18926 memcpy(p_buffer, &keep_alive_timeout, sizeof(keep_alive_timeout));
18927 ni_log2(p_ctx, NI_LOG_DEBUG, "%s keep_alive_timeout %" PRIx64 "\n", __func__,
18928 keep_alive_timeout);
18930 retval =
18932 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
18934 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
18935 CHECK_VPU_RECOVERY(retval);
18936
18937 if (NI_RETCODE_SUCCESS != retval)
18938 {
18939 ni_log2(p_ctx, NI_LOG_ERROR,
18940 "ERROR %s(): nvme write keep_alive_timeout command "
18941 "failed, blk_io_handle: %" PRIx64 ", hw_id, %d\n",
18942 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id);
18944 LRETURN;
18945 }
18946
18947 p_ctx->network_data =
18948 (ni_network_data_t *)calloc(1, sizeof(ni_network_data_t));
18949 if (!p_ctx->network_data)
18950 {
18951 ni_log2(p_ctx, NI_LOG_ERROR,
18952 "ERROR %s(): Unable to allocate network_data memory\n");
18954 LRETURN;
18955 }
18956 }
18957
18958 //aio
18959#ifdef __linux__
18960 if (ni_aio_setup(NI_MAX_SEGMENT_NUM, &p_ctx->aio_context) != 0) {
18961 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to setup aio context\n", __func__);
18963 LRETURN;
18964 }
18965
18966 p_ctx->iocbs = (ni_iocb_t **)malloc(sizeof(ni_iocb_t *) * NI_MAX_SEGMENT_NUM);
18967 if (!p_ctx->iocbs) {
18968 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to allocate iocbs\n", __func__);
18970 LRETURN;
18971 } else {
18972 int i;
18973 for (i = 0; i < NI_MAX_SEGMENT_NUM; i++) {
18974 p_ctx->iocbs[i] = (ni_iocb_t *)malloc(sizeof(ni_iocb_t));
18975 if (!p_ctx->iocbs[i]) {
18976 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to allocate iocb %d\n", __func__, i);
18978 LRETURN;
18979 }
18980 }
18981 }
18982
18983 p_ctx->io_event = (ni_io_event_t *)malloc(sizeof(ni_io_event_t) * NI_MAX_SEGMENT_NUM);
18984 if (!p_ctx->io_event) {
18985 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to allocate ioevent %d\n", __func__);
18987 LRETURN;
18988 }
18989#endif
18990
18991 // init for frame pts calculation
18992 p_ctx->is_first_frame = 1;
18993 p_ctx->last_pts = 0;
18994 p_ctx->last_dts = 0;
18995 p_ctx->active_video_width = 0;
18996 p_ctx->active_video_height = 0;
18997 p_ctx->actual_video_width = 0;
18998
18999END:
19000
19001 ni_aligned_free(p_buffer);
19002 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
19003 return retval;
19004}
19005
19007{
19008 (void)eos_recieved;
19010 void *p_buffer = NULL;
19011 uint32_t ui32LBA = 0;
19012
19013 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
19014
19015 if (!p_ctx)
19016 {
19017 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
19018 __func__);
19020 }
19021
19023
19024 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
19025 {
19026 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): Invalid session ID, return.\n", __func__);
19027 retval = NI_RETCODE_SUCCESS;
19028 LRETURN;
19029 }
19030
19031 //malloc data buffer
19032 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN))
19033 {
19034 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() alloc data buffer failed\n",
19035 NI_ERRNO, __func__);
19037 LRETURN;
19038 }
19039 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
19040
19041 ui32LBA = CLOSE_SESSION_R(p_ctx->session_id, NI_DEVICE_TYPE_AI);
19042
19043 int retry = 0;
19044 while (retry < NI_SESSION_CLOSE_RETRY_MAX)
19045 {
19046 ni_log2(p_ctx, NI_LOG_DEBUG,
19047 "%s(): p_ctx->blk_io_handle=%" PRIx64 ", p_ctx->hw_id=%d, "
19048 "p_ctx->session_id=%d, close_mode=1\n",
19049 __func__, (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id,
19050 p_ctx->session_id);
19051
19053 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA) < 0)
19054 {
19055 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): command failed\n", __func__);
19058 break;
19059 } else
19060 {
19061 //Close should always succeed
19062 retval = NI_RETCODE_SUCCESS;
19064 break;
19065 }
19066 /*
19067 else if(((ni_session_closed_status_t *)p_buffer)->session_closed)
19068 {
19069 retval = NI_RETCODE_SUCCESS;
19070 p_ctx->session_id = NI_INVALID_SESSION_ID;
19071 break;
19072 }
19073 else
19074 {
19075 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): wait for close\n", __func__);
19076 ni_usleep(NI_SESSION_CLOSE_RETRY_INTERVAL_US);
19077 retval = NI_RETCODE_ERROR_NVME_CMD_FAILED;
19078 }
19079 */
19080 retry++;
19081 }
19082
19083END:
19084
19085#ifdef __linux__
19086 if (p_ctx->aio_context != 0) {
19087 if (ni_aio_destroy(p_ctx->aio_context) != 0) {
19088 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): failed to destroy aio context\n", __func__);
19089 } else {
19090 p_ctx->aio_context = 0;
19091 }
19092 }
19093 if (p_ctx->iocbs) {
19094 for (int i = 0; i < NI_MAX_SEGMENT_NUM; i++) {
19095 ni_memfree(p_ctx->iocbs[i]);
19096 }
19097 free((void *)p_ctx->iocbs);
19098 p_ctx->iocbs = NULL;
19099 }
19100 ni_memfree(p_ctx->io_event);
19101#endif
19102
19103 ni_unreference_network_data(p_ctx->network_data);
19104 ni_memfree(p_ctx->network_data);
19105
19106 ni_aligned_free(p_buffer);
19108
19109 //Sequence change related stuff cleanup here
19110 p_ctx->active_video_width = 0;
19111 p_ctx->active_video_height = 0;
19112 p_ctx->actual_video_width = 0;
19113
19114 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): CTX[Card:%" PRIx64 " / HW:%d / INST:%d]\n",
19115 __func__, (int64_t)p_ctx->device_handle, p_ctx->hw_id,
19116 p_ctx->session_id);
19117 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
19118
19120
19121 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
19122
19123 return retval;
19124}
19125
19127 ni_frame_config_t p_cfg_in[],
19128 int numInCfgs,
19129 ni_frame_config_t *p_cfg_out)
19130{
19131 (void)p_cfg_out;
19133 ni_network_buffer_info_t *p_data = NULL;
19134 void *p_read_data = NULL;
19135 uint32_t dataLen;
19136 uint32_t ui32LBA = 0;
19137
19138 if (!p_ctx)
19139 {
19140 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
19141 __func__);
19143 }
19144
19145 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
19146 {
19147 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
19148 __func__);
19150 }
19152 ni_instance_buf_info_t buf_info = {0};
19153 int32_t query_retry = 0;
19154 for (;;)
19155 {
19157 {
19158 buf_info.buf_avail_size =
19160 ni_log2(p_ctx, NI_LOG_DEBUG,
19161 "Info ai write query success, available buf "
19162 "size %u !\n",
19163 buf_info.buf_avail_size);
19164 break;
19165 }
19166
19168 &p_ctx->session_statistic);
19169 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
19171 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
19172 buf_info.buf_avail_size =
19174 if (NI_RETCODE_SUCCESS != retval ||
19175 buf_info.buf_avail_size == 0)
19176 {
19177 ni_log2(p_ctx, NI_LOG_TRACE,
19178 "AI write query failed or buf_size < frame_size. Retry %d\n",
19179 query_retry);
19180 // extend to 5000 retries for 8K encode on FPGA
19181 if (query_retry >= NI_MAX_ENCODER_QUERY_RETRIES)
19182 {
19183 ni_log2(p_ctx, NI_LOG_TRACE,
19184 "AI write query exceeded max retries: %d\n",
19187 retval = NI_RETCODE_SUCCESS;
19188 LRETURN;
19189 }
19193 query_retry++;
19194 }
19195 }
19196
19197 dataLen = (sizeof(ni_network_buffer_info_t) + NI_MEM_PAGE_ALIGNMENT - 1) &
19198 ~(NI_MEM_PAGE_ALIGNMENT - 1);
19199
19200 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
19201 {
19202 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
19203 NI_ERRNO, __func__);
19205 }
19206
19207 memset(p_data, 0x00, dataLen);
19208 p_data->ui16Width = p_cfg_in[0].picture_width;
19209 p_data->ui16Height = p_cfg_in[0].picture_height;
19210 p_data->ui16Option = p_cfg_in[0].options;
19211 p_data->ui8PoolSize = p_cfg_in[0].rgba_color;
19212 p_data->ui8MultiIn = 1;
19213 for(int i = 0; i < numInCfgs; i++){
19214 p_data->ui16FrameIdx[i] = p_cfg_in[i].frame_index;
19215 ni_log2(p_ctx, NI_LOG_DEBUG, "Dev alloc frame[%d]: frame_index %u, hw=%d\n",
19216 i,p_data->ui16FrameIdx[i], p_data->ui8MultiIn);
19217 }
19218
19219
19220 ui32LBA =
19222
19223 retval =
19225 p_data, dataLen, ui32LBA);
19227 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
19228 OPT_1);
19229 if (NI_RETCODE_SUCCESS != retval)
19230 {
19231 ni_log2(p_ctx,
19233 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
19234 ", hw_id, %u, xcoder_inst_id: %d\n",
19235 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
19236 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n",
19237 __func__);
19239 LRETURN;
19240 }
19241
19242 END:
19244 ni_aligned_free(p_data);
19245 if (p_read_data != NULL)
19246 {
19247 ni_aligned_free(p_read_data);
19248 }
19249 return retval;
19250}
19251
19253 niFrameSurface1_t *p_out_surface)
19254{
19256 ni_network_buffer_info_t *p_data = NULL;
19257 void *p_read_data = NULL;
19258 uint32_t dataLen;
19259 uint32_t ui32LBA = 0;
19260
19261 if (!p_ctx)
19262 {
19263 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
19264 __func__);
19266 }
19267
19268 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
19269 {
19270 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
19271 __func__);
19273 }
19274
19277 "6rL") < 0)
19278 {
19279 ni_log2(p_ctx, NI_LOG_ERROR,
19280 "Error: %s function not supported on device with FW API version < 6rL\n",
19281 __func__);
19283 }
19284
19286
19287 int query_retry = 0;
19288 dataLen =
19290 ~(NI_MEM_PAGE_ALIGNMENT - 1);
19291 if (ni_posix_memalign(&p_read_data, sysconf(_SC_PAGESIZE), dataLen))
19292 {
19293 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
19294 NI_ERRNO, __func__);
19296 LRETURN;
19297 }
19298 memset(p_read_data, 0, dataLen);
19299
19300 for (;;)
19301 {
19304 retval =
19306 p_read_data, dataLen, ui32LBA);
19307 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read,
19308 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
19309 OPT_1);
19310 if (retval != NI_RETCODE_SUCCESS)
19311 {
19312 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
19314 LRETURN;
19315 }
19316
19317 if (((ni_instance_buf_info_t *)p_read_data)->hw_inst_ind.buffer_avail > 0)
19318 {
19319 p_out_surface->ui16FrameIdx = ((ni_instance_buf_info_t *)p_read_data)->hw_inst_ind.frame_index;
19320 p_out_surface->ui16session_ID = p_ctx->session_id;
19321 p_out_surface->device_handle =
19322 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
19323 p_out_surface->bit_depth = (int8_t)p_ctx->bit_depth_factor;
19324 p_out_surface->src_cpu = (uint8_t)NI_DEVICE_TYPE_AI;
19325 p_out_surface->output_idx = 0;
19326 break;
19327 }
19328
19329 query_retry++;
19330 if (query_retry > 2000)
19331 {
19332 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): exceeded max query retries: %d\n",
19333 __func__, query_retry - 1);
19334 retval = NI_RETCODE_EAGAIN;
19335 LRETURN;
19336 }
19338 ni_usleep(200);
19340 continue;
19341 }
19342
19343 if (((ni_instance_buf_info_t *)p_read_data)->hw_inst_ind.buffer_avail == 0)
19344 {
19346 LRETURN;
19347 }
19348END:
19350 ni_aligned_free(p_data);
19351 if (p_read_data != NULL)
19352 {
19353 ni_aligned_free(p_read_data);
19354 }
19355 return retval;
19356}
19357
19359 int height, int options, int pool_size,
19360 int frame_index)
19361{
19363 ni_network_buffer_info_t *p_data = NULL;
19364 void *p_read_data = NULL;
19365 uint32_t dataLen;
19366 uint32_t ui32LBA = 0;
19367
19368 if (!p_ctx)
19369 {
19370 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() passed parameters are null!, return\n",
19371 __func__);
19373 }
19374
19375 if (p_ctx->session_id == NI_INVALID_SESSION_ID)
19376 {
19377 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
19378 __func__);
19380 }
19381
19383
19384 if (options == NI_AI_FLAG_IO)
19385 {
19386 int query_retry = 0;
19387 dataLen =
19389 ~(NI_MEM_PAGE_ALIGNMENT - 1);
19390 if (ni_posix_memalign(&p_read_data, sysconf(_SC_PAGESIZE), dataLen))
19391 {
19392 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
19393 NI_ERRNO, __func__);
19395 LRETURN;
19396 }
19397 memset(p_read_data, 0, dataLen);
19398
19399 for (;;)
19400 {
19403 retval =
19405 p_read_data, dataLen, ui32LBA);
19406 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read,
19407 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
19408 OPT_1);
19409 if (retval != NI_RETCODE_SUCCESS)
19410 {
19411 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
19413 LRETURN;
19414 }
19415
19416 if (((ni_instance_buf_info_t *)p_read_data)->buf_avail_size > 0)
19417 {
19418 break;
19419 }
19420
19421 query_retry++;
19422 if (query_retry > 2000)
19423 {
19424 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): exceeded max query retries: %d\n",
19425 __func__, query_retry - 1);
19426 retval = NI_RETCODE_EAGAIN;
19427 LRETURN;
19428 }
19430 ni_usleep(200);
19432 continue;
19433 }
19434
19435 if (((ni_instance_buf_info_t *)p_read_data)->buf_avail_size == 0)
19436 {
19438 LRETURN;
19439 }
19440 } else
19441 {
19442 ni_instance_buf_info_t buf_info = {0};
19443 int32_t query_retry = 0;
19444 for (;;)
19445 {
19447 {
19448 buf_info.buf_avail_size =
19450 ni_log2(p_ctx, NI_LOG_DEBUG,
19451 "Info ai write query success, available buf "
19452 "size %u !\n",
19453 buf_info.buf_avail_size);
19454 break;
19455 }
19456
19458 &p_ctx->session_statistic);
19459 CHECK_ERR_RC(p_ctx, retval, &p_ctx->session_statistic,
19461 p_ctx->hw_id, &(p_ctx->session_id), OPT_2);
19462 buf_info.buf_avail_size =
19464 if (NI_RETCODE_SUCCESS != retval ||
19465 buf_info.buf_avail_size == 0)
19466 {
19467 ni_log2(p_ctx, NI_LOG_TRACE,
19468 "AI write query failed or buf_size < frame_size. Retry %d\n",
19469 query_retry);
19470 // extend to 5000 retries for 8K encode on FPGA
19471 if (query_retry >= NI_MAX_ENCODER_QUERY_RETRIES)
19472 {
19473 ni_log2(p_ctx, NI_LOG_TRACE,
19474 "AI write query exceeded max retries: %d\n",
19477 retval = NI_RETCODE_SUCCESS;
19478 LRETURN;
19479 }
19483 query_retry++;
19484 }
19485 }
19486
19487 dataLen = (sizeof(ni_network_buffer_info_t) + NI_MEM_PAGE_ALIGNMENT - 1) &
19488 ~(NI_MEM_PAGE_ALIGNMENT - 1);
19489
19490 if (ni_posix_memalign((void **)&p_data, sysconf(_SC_PAGESIZE), dataLen))
19491 {
19492 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
19493 NI_ERRNO, __func__);
19495 }
19496
19497 memset(p_data, 0x00, dataLen);
19498 p_data->ui16FrameIdx[0] = frame_index;
19499 p_data->ui16Width = width;
19500 p_data->ui16Height = height;
19501 p_data->ui16Option = options;
19502 p_data->ui8PoolSize = pool_size;
19503 p_data->ui8MultiIn = 0;
19504 ni_log2(p_ctx, NI_LOG_DEBUG, "Dev alloc frame: frame_index %u\n",
19505 p_data->ui16FrameIdx[0]);
19506
19507 ui32LBA =
19509
19510 retval =
19512 p_data, dataLen, ui32LBA);
19514 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
19515 OPT_1);
19516 if (NI_RETCODE_SUCCESS != retval)
19517 {
19518 ni_log2(p_ctx,
19520 "ERROR: ni_nvme_send_admin_cmd failed: blk_io_handle: %" PRIx64
19521 ", hw_id, %u, xcoder_inst_id: %d\n",
19522 (int64_t)p_ctx->blk_io_handle, p_ctx->hw_id, p_ctx->session_id);
19523 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): nvme command failed!\n",
19524 __func__);
19526 LRETURN;
19527 }
19528 }
19529
19530END:
19532 ni_aligned_free(p_data);
19533 if (p_read_data != NULL)
19534 {
19535 ni_aligned_free(p_read_data);
19536 }
19537 return retval;
19538}
19539
19540/*!******************************************************************************
19541 * \brief read a hardware descriptor from a scaler session
19542 *
19543 * \param[in] p_ctx pointer to session context
19544 * \param[out] p_frame pointer to frame to write hw descriptor
19545 *
19546 * \return NI_RETCODE_INVALID_PARAM
19547 * NI_RETCODE_ERROR_INVALID_SESSION
19548 * NI_RETCODE_ERROR_MEM_ALOC
19549 * NI_RETCODE_ERROR_NVME_CMD_FAILED
19550 * NI_RETCODE_FAILURE
19551 *******************************************************************************/
19553 ni_frame_t *p_frame)
19554{
19555 int retval = NI_RETCODE_SUCCESS;
19556 int retry_count = 0;
19557
19558 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
19559
19561
19562 if (NI_INVALID_SESSION_ID == p_ctx->session_id)
19563 {
19564 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %s(): Invalid session ID, return.\n",
19565 __func__);
19567 LRETURN;
19568 }
19569
19570 for (;;)
19571 {
19572 retry_count++;
19573 ni_instance_buf_info_t sInstanceBuf = {0};
19574 niFrameSurface1_t *pFrameSurface;
19576 NI_DEVICE_TYPE_AI, &sInstanceBuf);
19577 CHECK_ERR_RC(p_ctx, retval, 0, nvme_admin_cmd_xcoder_query,
19578 p_ctx->device_type, p_ctx->hw_id, &(p_ctx->session_id),
19579 OPT_3);
19580
19582 {
19583 if (retry_count >= 500)
19584 {
19585 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning hwdesc read fail rc %d\n",
19586 retval);
19587 LRETURN;
19588 }
19590 ni_usleep(100);
19592 }
19593 else if (retval != NI_RETCODE_SUCCESS)
19594 {
19595 LRETURN;
19596 } else
19597 {
19598 pFrameSurface = (niFrameSurface1_t *)p_frame->p_data[3];
19599 pFrameSurface->ui16FrameIdx = sInstanceBuf.hw_inst_ind.frame_index;
19600 pFrameSurface->ui16session_ID = p_ctx->session_id;
19601 pFrameSurface->device_handle =
19602 (int32_t)((int64_t)p_ctx->blk_io_handle & 0xFFFFFFFF);
19603 pFrameSurface->src_cpu = (uint8_t)NI_DEVICE_TYPE_AI;
19604 pFrameSurface->output_idx = 0;
19605
19606 /* A frame index of zero is invalid, the memory acquisition failed */
19607 if (pFrameSurface->ui16FrameIdx == 0)
19608 {
19609 if (retry_count >= 500)
19610 {
19611 ni_log2(p_ctx, NI_LOG_DEBUG, "Warning hwdesc read fail rc %d\n",
19612 retval);
19613 retval = NI_RETCODE_EAGAIN;
19614 LRETURN;
19615 }
19617 ni_usleep(100);
19619 continue;
19620 }
19621 LRETURN;
19622 }
19623 }
19624
19625END:
19626
19628
19629 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
19630
19631 return retval;
19632}
19633
19634/*!*****************************************************************************
19635 * \brief Get DDR configuration of Quadra device
19636 *
19637 * \param[in/out] p_ctx pointer to a session context with valid file handle
19638 *
19639 * \return On success NI_RETCODE_SUCCESS
19640 * On failure NI_RETCODE_INVALID_PARAM
19641 * NI_RETCODE_ERROR_MEM_ALOC
19642 * NI_RETCODE_ERROR_NVME_CMD_FAILED
19643 ******************************************************************************/
19645{
19646 void *p_buffer = NULL;
19647 ni_nvme_identity_t *p_id_data;
19649 ni_event_handle_t event_handle = NI_INVALID_EVENT_HANDLE;
19650 uint32_t ui32LBA = IDENTIFY_DEVICE_R;
19651 ni_device_handle_t device_handle = p_ctx->blk_io_handle;
19652
19653 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
19654
19655 if (NI_INVALID_DEVICE_HANDLE == device_handle)
19656 {
19657 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid passed parameters\n",
19658 __func__);
19659 retval = NI_RETCODE_INVALID_PARAM;
19660 LRETURN;
19661 }
19662
19663 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
19665 {
19666 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
19667 NI_ERRNO, __func__);
19669 LRETURN;
19670 }
19671
19672 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
19673
19674 if (ni_nvme_send_read_cmd(device_handle, event_handle, p_buffer,
19675 NI_NVME_IDENTITY_CMD_DATA_SZ, ui32LBA) < 0)
19676 {
19678 LRETURN;
19679 }
19680
19681 p_id_data = (ni_nvme_identity_t *) p_buffer;
19682
19683 if (p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_SR_4G)
19684 {
19685 p_ctx->ddr_config = 6;
19686 }
19687 else
19688 {
19691 "6rJ") >= 0)
19692 {
19693 p_ctx->ddr_config = (p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_SR)
19694 ? 3 : ((p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_DR)? 4 : 5);
19695 }
19696 else if (ni_cmp_fw_api_ver(
19698 "6rD") >= 0)
19699 {
19700 p_ctx->ddr_config = (p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_SR)
19701 ? 3 : 4;
19702 } else
19703 {
19704 p_ctx->ddr_config = (p_id_data->memory_cfg == NI_QUADRA_MEMORY_CONFIG_SR)
19705 ? 1 : 2;
19706 }
19707 }
19708
19709 ni_log2(p_ctx, NI_LOG_DEBUG, "Memory configuration %d\n",p_ctx->ddr_config);
19710END:
19711
19712 ni_aligned_free(p_buffer);
19713 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): retval: %d\n", __func__, retval);
19714
19715 return retval;
19716}
19717
19718/*!*****************************************************************************
19719 * \brief Set DDR configuration of Quadra device
19720 *
19721 * \param[in] p_ctx pointer to a session context with valid file handle
19722 * \param[in] ddr_priority_mode ddr priority mode
19723 *
19724 * \return On success NI_RETCODE_SUCCESS
19725 * On failure NI_RETCODE_INVALID_PARAM
19726 * NI_RETCODE_ERROR_MEM_ALOC
19727 * NI_RETCODE_ERROR_NVME_CMD_FAILED
19728 ******************************************************************************/
19730 uint8_t ddr_priority_mode)
19731{
19732 void *p_buffer = NULL;
19734 ni_ddr_priority_config_t *p_cfg = NULL;
19735 uint32_t ui32LBA = CONFIG_SESSION_DDR_PRIORITY_W(p_ctx->session_id);
19736 ni_device_handle_t device_handle = p_ctx->blk_io_handle;
19737
19738 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
19739
19740 ni_log2(p_ctx, NI_LOG_INFO, "set ddr priority %d\n",
19741 ddr_priority_mode);
19742
19743 if (NI_INVALID_DEVICE_HANDLE == device_handle)
19744 {
19745 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s(): invalid passed parameters\n",
19746 __func__);
19747 retval = NI_RETCODE_INVALID_PARAM;
19748 LRETURN;
19749 }
19750
19751 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE),
19753 {
19754 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer.\n",
19755 NI_ERRNO, __func__);
19757 LRETURN;
19758 }
19759
19760 memset(p_buffer, 0, NI_NVME_IDENTITY_CMD_DATA_SZ);
19761 p_cfg = (ni_ddr_priority_config_t *)p_buffer;
19762 p_cfg->ddr_mode = ddr_priority_mode;
19763 if (ni_nvme_send_write_cmd(p_ctx->blk_io_handle, NI_INVALID_EVENT_HANDLE,
19764 p_buffer,NI_DATA_BUFFER_LEN, ui32LBA) < 0)
19765 {
19766 ni_log2(p_ctx, NI_LOG_ERROR, "DDR priority setting failed with mode %d\n",
19767 ddr_priority_mode);
19769 LRETURN;
19770 }
19771END:
19772 ni_aligned_free(p_buffer);
19773 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): retval: %d\n", __func__, retval);
19774
19775 return retval;
19776}
19777
19778/*!*****************************************************************************
19779 * \brief Allocate memory for the metadata header and auxillary data for
19780 * encoder input data.
19781 *
19782 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
19783 *
19784 * \param[in] extra_len Length header and auxillary data
19785 *
19786 * \return On success
19787 * NI_RETCODE_SUCCESS
19788 * On failure
19789 * NI_RETCODE_INVALID_PARAM
19790 * NI_RETCODE_ERROR_MEM_ALOC
19791 *****************************************************************************/
19793 int extra_len)
19794{
19795 void *metadata_buffer = NULL;
19796 int retval = NI_RETCODE_SUCCESS;
19797
19798 if ((!p_frame) || (extra_len <= 0))
19799 {
19801 "ERROR: %s passed parameters are null or not supported, "
19802 "p_frame %p, extra_len %d",
19803 __func__, p_frame, extra_len);
19805 }
19806
19807 int buffer_size = extra_len;
19808 if (buffer_size % NI_MEM_PAGE_ALIGNMENT)
19809 {
19810 buffer_size = ((buffer_size / NI_MEM_PAGE_ALIGNMENT) + 1) *
19812 }
19813
19814 // Check if previous metadata buffer needs to be freed
19815 if ((p_frame->metadata_buffer_size != buffer_size) &&
19816 (p_frame->metadata_buffer_size > 0))
19817 {
19819 "%s: free current p_frame metadata buffer, "
19820 "p_frame->buffer_size=%u\n",
19821 __func__, p_frame->metadata_buffer_size);
19822 p_frame->metadata_buffer_size = 0;
19824 }
19825
19826 // Check if new metadata buffer needs to be allocated
19827 if (p_frame->metadata_buffer_size != buffer_size)
19828 {
19829 if (ni_posix_memalign(&metadata_buffer, sysconf(_SC_PAGESIZE),
19830 buffer_size))
19831 {
19833 "ERROR %d: %s() Cannot allocate metadata buffer.\n",
19834 NI_ERRNO, __func__);
19836 LRETURN;
19837 }
19838
19839 // init once after allocation
19840 memset(metadata_buffer, 0, buffer_size);
19841 p_frame->metadata_buffer_size = buffer_size;
19842 p_frame->p_metadata_buffer = metadata_buffer;
19843
19844 ni_log(NI_LOG_DEBUG, "%s: allocated new metadata buffer\n", __func__);
19845 } else
19846 {
19847 ni_log(NI_LOG_DEBUG, "%s: reuse metadata buffer\n", __func__);
19848 }
19849
19851 "%s: success: p_frame->p_metadata_buffer %p "
19852 "p_frame->metadata_buffer_size=%u\n",
19853 __func__, p_frame->p_metadata_buffer, p_frame->metadata_buffer_size);
19854
19855END:
19856
19857 if (NI_RETCODE_SUCCESS != retval)
19858 {
19859 ni_aligned_free(metadata_buffer);
19860 }
19861
19862 return retval;
19863}
19864
19865/*!*****************************************************************************
19866 * \brief Allocate memory for the non-4k-aligned part at the start of YUV data for
19867 * encoder input data.
19868 *
19869 * \param[in] p_frame Pointer to a caller allocated ni_frame_t struct
19870 *
19871 * \param[in] start_len Length of non-4k-aligned part at the start of YUV data
19872 *
19873 * \return On success
19874 * NI_RETCODE_SUCCESS
19875 * On failure
19876 * NI_RETCODE_INVALID_PARAM
19877 * NI_RETCODE_ERROR_MEM_ALOC
19878 *****************************************************************************/
19880{
19881 void *start_buffer = NULL;
19882 int retval = NI_RETCODE_SUCCESS;
19883
19884 if (!p_frame)
19885 {
19887 "ERROR: %s passed parameters are null or not supported, "
19888 "p_frame %p\n",
19889 __func__, p_frame);
19891 }
19892
19893 // Check if new start buffer needs to be allocated
19894 if (!p_frame->start_buffer_size)
19895 {
19896 if (ni_posix_memalign(&start_buffer, sysconf(_SC_PAGESIZE),
19898 {
19900 "ERROR %d: %s() Cannot allocate start buffer.\n",
19901 NI_ERRNO, __func__);
19903 LRETURN;
19904 }
19905
19906 // init once after allocation
19907 memset(start_buffer, 0, (size_t)NI_MEM_PAGE_ALIGNMENT*NI_MAX_NUM_SW_FRAME_DATA_POINTERS);
19909 p_frame->p_start_buffer = start_buffer;
19910
19911 ni_log(NI_LOG_DEBUG, "%s: allocated new start buffer\n", __func__);
19912 } else
19913 {
19914 ni_log(NI_LOG_DEBUG, "%s: reuse start buffer\n", __func__);
19915 }
19916
19918 "%s: success: p_frame->p_start_buffer %p "
19919 "p_frame->start_buffer_size=%u\n",
19920 __func__, p_frame->p_start_buffer, p_frame->start_buffer_size);
19921
19922END:
19923
19924 if (NI_RETCODE_SUCCESS != retval)
19925 {
19926 ni_aligned_free(start_buffer);
19927 }
19928
19929 return retval;
19930}
19931
19933 ni_network_perf_metrics_t *p_metrics)
19934{
19936 void *p_buffer = NULL;
19937 uint32_t dataLen;
19938 uint32_t ui32LBA = 0;
19939
19940 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): enter\n", __func__);
19941 if (!p_ctx || !p_metrics)
19942 {
19943 ni_log2(p_ctx, NI_LOG_ERROR,
19944 "ERROR: %s() passed parameters are null!, return\n", __func__);
19945 retval = NI_RETCODE_INVALID_PARAM;
19946 LRETURN;
19947 }
19948
19950 "6N") >= 0)
19951 {
19952 dataLen =
19954 ~(NI_MEM_PAGE_ALIGNMENT - 1);
19955 if (ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), dataLen))
19956 {
19957 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate buffer\n",
19958 NI_ERRNO, __func__);
19960 LRETURN;
19961 }
19962 memset(p_buffer, 0, sizeof(ni_network_perf_metrics_t));
19963
19964 ui32LBA =
19966 retval =
19968 p_buffer, dataLen, ui32LBA);
19969 if ((int32_t)retval != NI_RETCODE_SUCCESS)
19970 {
19971 ni_log2(p_ctx, NI_LOG_ERROR, "%s(): NVME command Failed\n", __func__);
19973 LRETURN;
19974 }
19975 CHECK_ERR_RC(p_ctx, retval, 0, nvme_cmd_xcoder_read, p_ctx->device_type,
19976 p_ctx->hw_id, &(p_ctx->session_id), OPT_1);
19977
19978 *p_metrics = *((ni_network_perf_metrics_t *)p_buffer);
19979 } else
19980 {
19981 p_metrics->total_cycles = (uint32_t)(-1);
19982 p_metrics->total_idle_cycles = (uint32_t)(-1);
19983 }
19984END:
19985
19986 ni_aligned_free(p_buffer);
19987 ni_log2(p_ctx, NI_LOG_TRACE, "%s(): exit\n", __func__);
19988
19989 return retval;
19990}
19991
19992/*!*****************************************************************************
19993 * \brief Send namespace num / Opmode and SRIOv index/value to the device with
19994 * specified logic block address.
19995 *
19996 * \param[in] device_handle Device handle obtained by calling ni_device_open
19997 * \param[in] Key Represents either namespace num or opmode
19998 * \param[in] Value Represents either SRIOv index or opmode value
19999 *
20000 * \return On success
20001 * NI_RETCODE_SUCCESS
20002 * On failure
20003 * NI_RETCODE_ERROR_MEM_ALOC
20004 * NI_RETCODE_ERROR_NVME_CMD_FAILED
20005 ******************************************************************************/
20006ni_retcode_t ni_device_config_ns_qos(ni_device_handle_t device_handle,
20007 uint32_t key,
20008 uint32_t value)
20009{
20010 char buf[NI_DATA_BUFFER_LEN] = {'\0'};
20011 uint32_t *u32_buf = (uint32_t *)buf;
20012 u32_buf[0] = key;
20013 u32_buf[1] = value;
20014 // event handle could be ignored
20015 return ni_nvme_send_write_cmd(device_handle, NI_INVALID_EVENT_HANDLE,
20016 (void *)buf, NI_DATA_BUFFER_LEN,
20018}
20019
20021{
20022 char *CoreName;
20023 switch (eCoreType)
20024 {
20025 case ALL_CORE:
20026 CoreName = (char *)"all";
20027 break;
20028 case NVME_CORE:
20029 CoreName = (char *)"np";
20030 break;
20031 case EP_CORE:
20032 CoreName = (char *)"ep";
20033 break;
20034 case DP_CORE:
20035 CoreName = (char *)"dp";
20036 break;
20037 case TP_CORE:
20038 CoreName = (char *)"tp";
20039 break;
20040 case FP_CORE:
20041 CoreName = (char *)"fp";
20042 break;
20043 case FL_CORE:
20044 CoreName = (char *)"fl";
20045 break;
20046 default:
20047 CoreName = (char *)"Not Found";
20048 break;
20049 }
20050 return CoreName;
20051}
20052
20054{
20055 uint32_t lba;
20056 switch (eCoreType)
20057 {
20058 case NVME_CORE:
20060 break;
20061 case EP_CORE:
20062 lba = EP_LOG_OFFSET_IN_4K;
20063 break;
20064 case DP_CORE:
20065 lba = DP_LOG_OFFSET_IN_4K;
20066 break;
20067 case TP_CORE:
20068 lba = TP_LOG_OFFSET_IN_4K;
20069 break;
20070 case FP_CORE:
20071 lba = FP_LOG_OFFSET_IN_4K;
20072 break;
20073 case FL_CORE:
20074 lba = FL_LOG_OFFSET_IN_4K;
20075 break;
20076 default:
20077 ni_log(NI_LOG_ERROR, "%s:() Invalid core ID:%u\n", __func__, eCoreType);
20078 lba = 0;
20079 break;
20080 }
20081
20082 return lba;
20083}
20084
20085static int ni_write_fl_log_decoded_file(void *p_data, uint32_t buf_len, FILE *p_file)
20086{
20087 uint32_t fllen;
20088 uint32_t flsign;
20089 uint32_t log_lines;
20090 uint64_t payload_u;
20091 size_t payload_len;
20092 size_t max_payload;
20093 const uint8_t *in;
20094 uint8_t *out;
20095 size_t i, j;
20096
20097 if (buf_len < 4 || !p_data || !p_file)
20098 return -1;
20099
20100 memcpy(&flsign, p_data, sizeof(flsign));
20101 if (flsign != FL_SIGNATURE)
20102 {
20103 return -4;
20104 }
20105 memcpy(&fllen, (const uint8_t *)p_data + 4, sizeof(fllen));
20106 log_lines = fllen & 0xFFFFFFU;
20107 payload_u = (uint64_t)log_lines * 128ULL;
20108 max_payload = (size_t)buf_len - 4;
20109 payload_len = (payload_u > max_payload) ? max_payload : (size_t)payload_u;
20110
20111 in = (const uint8_t *)p_data + 8;
20112 out = (uint8_t *)malloc(payload_len ? payload_len : 1);
20113 if (!out)
20114 return -2;
20115
20116 for (i = 0, j = 0; i < payload_len; i++)
20117 if (in[i] != 0)
20118 out[j++] = in[i];
20119
20120 if (j > 0 && fwrite(out, 1, j, p_file) != j) {
20121 free(out);
20122 return -3;
20123 }
20124 free(out);
20125 return 0;
20126}
20127
20128ni_retcode_t ni_dump_log_single_core(ni_session_context_t *p_ctx, void* p_data, uint32_t core_id, bool gen_log_file)
20129{
20130 int32_t rc;
20131 uint32_t lba = 0;
20132 uint32_t data_len = CPU_LOG_BUFFER_SIZE;
20133 char *core_name = NULL;
20134 FILE *p_file = NULL;
20136
20137 if (!p_ctx || !p_data)
20138 {
20139 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR invalid pointer p_ctx %p p_data %p\n",
20140 __func__, __LINE__, p_ctx, p_data);
20142 }
20143
20144 if (core_id == FL_CORE)
20145 {
20147 memset(p_data, 0, CPU_FL_LOG_BUFFER_SIZE * CPU_FL_LOG_BUFFER_LEN);
20148 }
20149 else
20150 {
20151 memset(p_data, 0, CPU_LOG_BUFFER_SIZE);
20152 }
20153 *(uint8_t *)p_data = 0x55;
20154
20155 lba = ni_get_log_lba((ni_core_type_t)core_id);
20156 if (lba == 0)
20157 {
20158 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR core_id %u\n",
20159 __func__, __LINE__, core_id);
20161 }
20162
20163 core_name = ni_get_core_name((ni_core_type_t)core_id);
20164
20165 rc = ni_nvme_send_read_cmd(p_ctx->blk_io_handle, p_ctx->event_handle, p_data, data_len, lba);
20166
20167 if (rc != NI_RETCODE_SUCCESS)
20168 {
20169 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR %d: nvme read %s core failed\n",
20170 __func__, __LINE__, rc, core_name);
20171 }
20172 else if (gen_log_file)
20173 {
20174 //generate log file e.g. raw_np_0000_02_00_0_Q1A10BA11FC060-0050_20260703-120340.bin
20175 char filename[80] = "raw_";
20176 ni_strcat(filename, sizeof(filename), core_name);
20177 ni_strcat(filename, sizeof(filename), "_");
20178#ifdef __linux__
20179 bool pcie_id_name = false;
20180 char devFilePath[1024] = {0};
20181 char devFDPath[1024] = {0};
20182 char pcie[64] = {0};
20183 char domain[5] = {0}, slot[3] = {0}, dev[3] = {0}, func[2] = {0};
20184 //p_ctx->blk_dev_name might be empty so look up the file name
20185 (void)snprintf(devFDPath, sizeof(devFDPath), "/proc/self/fd/%d", p_ctx->blk_io_handle);
20186 ssize_t len = readlink(devFDPath, devFilePath, sizeof(devFilePath)-1);
20187 if (len != -1) {
20188 devFilePath[len] = '\0';
20189 }
20190 if (strstr(devFilePath, "/dev/nvme") != NULL)
20191 {
20192 get_dev_pcie_addr(devFilePath, pcie, domain, slot, dev, func);
20193 if (strlen(pcie) > 0 && strlen(slot) > 0 && strlen(domain) > 0)
20194 {
20195 char bdf[16] = {0};
20196 (void)snprintf(bdf, sizeof(bdf), "%s_%s_%s_%s",
20197 domain, slot, dev, func);
20198 ni_strcat(filename, sizeof(filename), bdf);
20199 pcie_id_name = true;
20200 }
20201 }
20202 if (!pcie_id_name)
20203 {
20204 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: For dev %d can't look up PCI slot info, defaulting to hw_id\n",
20205 __func__, __LINE__, p_ctx->blk_io_handle);
20206 char num[4] = {0};
20207 (void)snprintf(num, 4, "%d", p_ctx->hw_id);
20208 ni_strcat(filename, sizeof(filename), num);
20209 }
20210 // Append full NVMe serial number from sysfs (up to 20 chars)
20211 char sn[21] = {0};
20212 int ctrl_idx;
20213 if (sscanf(devFilePath, "/dev/nvme%dn", &ctrl_idx) == 1) // NOLINT(cert-err34-c) - return value checked
20214 {
20215 char sysfs_serial[64] = {0};
20216 (void)snprintf(sysfs_serial, sizeof(sysfs_serial),
20217 "/sys/class/nvme/nvme%d/serial", ctrl_idx);
20218 FILE *sn_f = fopen(sysfs_serial, "r");
20219 if (sn_f)
20220 {
20221 char raw_sn[21] = {0};
20222 if (fgets(raw_sn, sizeof(raw_sn), sn_f))
20223 {
20224 raw_sn[strcspn(raw_sn, " \t\r\n")] = '\0';
20225 (void)snprintf(sn, sizeof(sn), "%s", raw_sn);
20226 }
20227 (void)fclose(sn_f);
20228 }
20229 }
20230 if (sn[0])
20231 {
20232 ni_strcat(filename, sizeof(filename), "_");
20233 ni_strcat(filename, sizeof(filename), sn);
20234 }
20235 else
20236 {
20237 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: For dev %d could not read NVMe serial from sysfs, omitting SN from log filename\n",
20238 __func__, __LINE__, p_ctx->blk_io_handle);
20239 }
20240 char ts[16] = {0};
20241 time_t now = time(NULL);
20242 struct tm tm_buf;
20243 struct tm *tm_info = localtime_r(&now, &tm_buf);
20244 if (tm_info)
20245 (void)strftime(ts, sizeof(ts), "%Y%m%d-%H%M%S", tm_info);
20246 if (ts[0])
20247 {
20248 ni_strcat(filename, sizeof(filename), "_");
20249 ni_strcat(filename, sizeof(filename), ts);
20250 }
20251 ni_strcat(filename, sizeof(filename), ".bin");
20252 ni_log2(p_ctx, NI_LOG_INFO, "For dev %d %s core %s creating file %s\n",
20253 p_ctx->blk_io_handle, devFilePath, core_name, filename);
20254#else
20255 char num[4] = {0};
20256 (void)snprintf(num, 4, "%02x", p_ctx->hw_id);
20257 ni_strcat(filename, sizeof(filename), num);
20258 char ts[16] = {0};
20259 time_t now = time(NULL);
20260 struct tm tm_buf;
20261#if defined(_WIN32)
20262 struct tm *tm_info = (localtime_s(&tm_buf, &now) == 0) ? &tm_buf : NULL;
20263#else
20264 struct tm *tm_info = localtime_r(&now, &tm_buf);
20265#endif
20266 if (tm_info)
20267 (void)strftime(ts, sizeof(ts), "%Y%m%d-%H%M%S", tm_info);
20268 if (ts[0])
20269 {
20270 ni_strcat(filename, sizeof(filename), "_");
20271 ni_strcat(filename, sizeof(filename), ts);
20272 }
20273 ni_strcat(filename, sizeof(filename), ".bin");
20274 ni_log2(p_ctx, NI_LOG_INFO, "For dev %d core %s creating file %s\n",
20275 p_ctx->blk_io_handle, core_name, filename);
20276#endif
20277 ni_fopen(&p_file, filename, "wb");
20278
20279 if (p_file)
20280 {
20281 if (core_id == FL_CORE)
20282 {
20283 int wrc = ni_write_fl_log_decoded_file(p_data, data_len, p_file);
20284 if (wrc == -2)
20285 {
20286 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: FL log decode: malloc failed\n",
20287 __func__, __LINE__);
20288 retval = NI_RETCODE_FAILURE;
20289 }
20290 else if (wrc == -3)
20291 {
20292 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: FL log decode: fwrite failed\n",
20293 __func__, __LINE__);
20294 retval = NI_RETCODE_FAILURE;
20295 }
20296 else if (wrc == -1)
20297 {
20298 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: FL log decode: invalid buffer\n",
20299 __func__, __LINE__);
20300 retval = NI_RETCODE_FAILURE;
20301 }
20302 else if (wrc == -4)
20303 {
20304 ni_log2(p_ctx, NI_LOG_INFO, "%s:():%d: FL log decode: invalid signature\n",
20305 __func__, __LINE__);
20306 retval = NI_RETCODE_FAILURE;
20307 }
20308
20309 }
20310 else if (fwrite((uint8_t *)p_data ,
20311 data_len, 1, p_file) != 1)
20312 {
20313 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: Error: writing data %u bytes error!\n",
20314 __func__, __LINE__, data_len);
20315 ni_log2(p_ctx, NI_LOG_ERROR, "Error: ferror rc = %d\n", ferror(p_file));
20316 retval = NI_RETCODE_FAILURE;
20317 }
20318 if (fflush(p_file))
20319 {
20320 ni_log2(p_ctx, NI_LOG_ERROR, "Error: writing data frame flush failed! errno %d\n",
20321 ferror(p_file));
20322 retval = NI_RETCODE_FAILURE;
20323 }
20324 (void)fclose(p_file);
20325 }
20326 else
20327 {
20328 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: Error: cannot open %s\n",
20329 __func__, __LINE__, filename);
20330 retval = NI_RETCODE_FAILURE;
20331 }
20332 }
20333
20334 return retval;
20335}
20336
20337ni_retcode_t ni_dump_log_all_cores(ni_session_context_t *p_ctx, void* p_data, bool gen_log_file)
20338{
20339 int i = 1;
20340 int max_cores = 0;
20341
20342 if (!p_ctx || !p_data)
20343 {
20344 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR invalid pointer p_ctx %p p_data %p\n",
20345 __func__, __LINE__, p_ctx, p_data);
20347 }
20348
20350 "6t1") < 0)
20351 {
20352 max_cores = FP_CORE;
20353 }
20354 else
20355 {
20356 max_cores = FL_CORE;
20357 }
20358 for (i = NVME_CORE; i<= max_cores; i++)
20359 {
20360 ni_dump_log_single_core(p_ctx, p_data, i, gen_log_file);
20361 p_data = (void*)((uint8_t *)p_data + CPU_LOG_BUFFER_SIZE);
20362 }
20363
20364 return NI_RETCODE_SUCCESS;
20365}
20366
20367/*!*****************************************************************************
20368 * \brief Read log artifacts (tar.gz) from the device via NVMe and write them
20369 * to "artifacts_slot_s_dddd.tar.gz". (d - slot num, dddd - domain)
20370 *
20371 * Buffer layout at ARTIFACTS_OFFSET_IN_4K:
20372 * [0..3] uint32_t artifacts size in bytes
20373 * [4. onwards] tar.gz data
20374 *
20375 * \param[in] p_ctx Pointer to an open session context
20376 * \param[in] gen_artifacts_file Write tar.gz to disk when true
20377 *
20378 * \return NI_RETCODE_SUCCESS or an error code
20379*******************************************************************************/
20381 bool gen_artifacts_file)
20382{
20383 int32_t rc;
20384 uint32_t lba = ARTIFACTS_OFFSET_IN_4K;
20385 uint32_t artifacts_size;
20386 uint32_t max_data_size = LOG_ARTIFACTS_MAX_SIZE - CPU_LOG_ARTIFACTS_HEADER_SIZE;
20387 void *p_buf = NULL;
20388 FILE *p_file = NULL;
20390 /* artifacts compressed with gzip, the gzip file header is used for validation */
20391 static const uint8_t GZIP_MAGIC[2] = {0x1f, 0x8b};
20392
20393 if (!p_ctx)
20394 {
20395 ni_log(NI_LOG_ERROR, "%s: ERROR invalid pointer p_ctx\n", __func__);
20397 }
20398
20399 if (ni_posix_memalign(&p_buf, sysconf(_SC_PAGESIZE), LOG_ARTIFACTS_MAX_SIZE))
20400 {
20401 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate artifacts buffer\n",
20402 NI_ERRNO, __func__);
20404 }
20405 memset(p_buf, 0, LOG_ARTIFACTS_MAX_SIZE);
20406
20408 p_buf, LOG_ARTIFACTS_MAX_SIZE, lba);
20409 if (rc != NI_RETCODE_SUCCESS)
20410 {
20411 ni_log2(p_ctx, NI_LOG_ERROR, "%s: ERROR %d: nvme read artifacts failed\n",
20412 __func__, rc);
20413 retval = rc;
20414 goto cleanup;
20415 }
20416
20417 /* parse the 4-byte - this value indicates the artifacts.tar.gz file size */
20418 memcpy(&artifacts_size, p_buf, CPU_LOG_ARTIFACTS_HEADER_SIZE);
20419
20420 if (artifacts_size == 0)
20421 {
20422 ni_log2(p_ctx, NI_LOG_INFO,
20423 "%s: artifacts size is 0 — firmware has not loaded artifacts\n",
20424 __func__);
20425
20426 retval = NI_RETCODE_SUCCESS;
20427 goto cleanup;
20428 }
20429
20430 /* size > max is unexpected — DDR data is corrupt or from a stale run */
20431 if (artifacts_size > max_data_size)
20432 {
20433 ni_log2(p_ctx, NI_LOG_ERROR,
20434 "%s: artifacts size %u exceeds maximum %u — corrupt or stale DDR data\n",
20435 __func__, artifacts_size, max_data_size);
20436 retval = NI_RETCODE_FAILURE;
20437 goto cleanup;
20438 }
20439
20440 /* check gzip magic header bytes */
20441 if (memcmp((uint8_t *)p_buf + CPU_LOG_ARTIFACTS_HEADER_SIZE, GZIP_MAGIC, 2) != 0)
20442 {
20443 ni_log2(p_ctx, NI_LOG_ERROR, "%s: invalid gzip magic — stale data or firmware too old\n", __func__);
20444 retval = NI_RETCODE_FAILURE;
20445 goto cleanup;
20446 }
20447
20448 ni_log2(p_ctx, NI_LOG_TRACE, "%s: artifacts size %u bytes\n", __func__, artifacts_size);
20449
20450 if (gen_artifacts_file)
20451 {
20452 char filename[64] = "artifacts_slot_";
20453#ifdef __linux__
20454 bool pcie_id_name = false;
20455 char devFilePath[1024] = {0};
20456 char devFDPath[1024] = {0};
20457 char pcie[64] = {0};
20458 char domain[5] = {0}, slot[3] = {0}, dev[3] = {0}, func[2] = {0};
20459 (void)snprintf(devFDPath, sizeof(devFDPath), "/proc/self/fd/%d", p_ctx->blk_io_handle);
20460 ssize_t len = readlink(devFDPath, devFilePath, sizeof(devFilePath) - 1);
20461 if (len != -1)
20462 devFilePath[len] = '\0';
20463 if (strstr(devFilePath, "/dev/nvme") != NULL)
20464 {
20465 get_dev_pcie_addr(devFilePath, pcie, domain, slot, dev, func);
20466 if (strlen(pcie) > 0 && strlen(slot) > 0 && strlen(domain) > 0)
20467 {
20468 ni_strcat(filename, sizeof(filename), slot);
20469 ni_strcat(filename, sizeof(filename), "_");
20470 ni_strcat(filename, sizeof(filename), domain);
20471 pcie_id_name = true;
20472 }
20473 }
20474 if (!pcie_id_name)
20475 {
20476 char num[4] = {0};
20477 (void)snprintf(num, sizeof(num), "%d", p_ctx->hw_id);
20478 ni_strcat(filename, sizeof(filename), num);
20479 ni_strcat(filename, sizeof(filename), "_0000");
20480 }
20481#else
20482 char num[4] = {0};
20483 (void)snprintf(num, sizeof(num), "%02x", p_ctx->hw_id);
20484 ni_strcat(filename, sizeof(filename), num);
20485 ni_strcat(filename, sizeof(filename), "_0000");
20486#endif
20487 ni_strcat(filename, sizeof(filename), ".tar.gz");
20488 ni_log2(p_ctx, NI_LOG_INFO, "%s: writing artifacts to %s\n", __func__, filename);
20489
20490 ni_fopen(&p_file, filename, "wb");
20491 if (p_file)
20492 {
20493 uint8_t *p_data = (uint8_t *)p_buf + CPU_LOG_ARTIFACTS_HEADER_SIZE;
20494 if (fwrite(p_data, artifacts_size, 1, p_file) != 1)
20495 {
20496 ni_log2(p_ctx, NI_LOG_ERROR, "%s: fwrite error %d\n",
20497 __func__, ferror(p_file));
20498 retval = NI_RETCODE_FAILURE;
20499 }
20500 if (fflush(p_file))
20501 {
20502 ni_log2(p_ctx, NI_LOG_ERROR, "%s: fflush error %d\n",
20503 __func__, ferror(p_file));
20504 retval = NI_RETCODE_FAILURE;
20505 }
20506 (void)fclose(p_file);
20507 }
20508 else
20509 {
20510 ni_log2(p_ctx, NI_LOG_ERROR, "%s: cannot open %s\n", __func__, filename);
20511 retval = NI_RETCODE_FAILURE;
20512 }
20513 }
20514
20515cleanup:
20516 ni_aligned_free(p_buf);
20517 return retval;
20518}
20519
20520/*!*****************************************************************************
20521 * \brief Generates and writes a nvme command with sgl list
20522 *
20523 * \param[in] p_ctx Pointer to source card session
20524 * \param[in] pSrcFrame Pointer to source P2P frame
20525 * \param[in] dmaAddrs Destination DMA address on target device
20526 *
20527 * \return on success
20528 * NI_RETCODE_SUCCESS
20529 * on failure
20530 * NI_RETCODE_INVALID_PARAM
20531 * NI_RETCODE_ERROR_INVALID_SESSION
20532 * NI_RETCODE_ERROR_MEM_ALOC
20533 * NI_RETCODE_ERROR_NVME_CMD_FAILED
20534*******************************************************************************/
20536 ni_frame_t *pSrcFrame,
20537 const ni_p2p_sgl_t *dmaAddrs)
20538
20539{
20540 void *p_buffer = NULL;
20541 ni_retcode_t retval;
20542 uint32_t ui32LBA = 0;
20543 niFrameSurface1_t *pSurface;
20544 uint8_t *p_data;
20545 uint16_t ui16Direction = NI_P2P_SEND;
20546 uint32_t i;
20547
20548 if (dmaAddrs->ui32NumEntries > NI_MAX_P2P_SGL_ENTRIES)
20549 {
20550 ni_log2(p_ctx, NI_LOG_ERROR, "Too many SGL entries\n");
20551 retval = NI_RETCODE_INVALID_PARAM;
20552 LRETURN;
20553 }
20554
20555 /* allocate memory aligned buffer */
20556 retval = ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN);
20557 if (retval != 0)
20558 {
20560 LRETURN;
20561 }
20562
20563 pSurface = (niFrameSurface1_t *) pSrcFrame->p_data[3];
20564
20565 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
20566
20567 p_data = (uint8_t *) p_buffer;
20568
20569 /* Add payload */
20570 memcpy(p_data, &dmaAddrs->ui64DMAAddr[0], 8); // dummy data, not used
20571 memcpy(p_data + 8, &dmaAddrs->ui32DMALen[0], 4); // dummy data, not used
20572 memcpy(p_data + 12, &pSurface->ui16FrameIdx, 2); // dummy data, not used
20573 memcpy(p_data + 14, MAGIC_P2P_VALUE, 4);
20574 memcpy(p_data + 18, &ui16Direction, 2);
20575
20576 /* if any SGL entry exceeds the DMA engine max transfer size (>16MB or >24-bit),
20577 * then split the entry into two or more entries that are <=16MB */
20578 {
20579 uint32_t ui32NeedsSplit = 0;
20580 uint32_t ui32EntryIdx = 0;
20581
20582 for (ui32EntryIdx = 0; ui32EntryIdx < dmaAddrs->ui32NumEntries; ui32EntryIdx++)
20583 {
20584 if (dmaAddrs->ui32DMALen[ui32EntryIdx] > NI_DMA_SGL_MAX_XFER_SIZE)
20585 {
20586 ui32NeedsSplit = 1;
20587 break;
20588 }
20589 }
20590
20591 if (ui32NeedsSplit)
20592 {
20593 ni_p2p_sgl_t sSplitSgl;
20594 uint32_t ui32SglIdx = 0;
20595 uint32_t ui32OrigEntries = dmaAddrs->ui32NumEntries;
20596
20597 memset(&sSplitSgl, 0, sizeof(sSplitSgl));
20598 for (ui32EntryIdx = 0;
20599 ui32EntryIdx < ui32OrigEntries && ui32SglIdx < NI_MAX_P2P_SGL_ENTRY;
20600 ui32EntryIdx++)
20601 {
20602 uint64_t ui64BaseAddr = dmaAddrs->ui64DMAAddr[ui32EntryIdx];
20603 uint32_t ui32RemainingData = dmaAddrs->ui32DMALen[ui32EntryIdx];
20604 uint32_t ui32Offset = 0;
20605
20606 while (ui32RemainingData > 0 && ui32SglIdx < NI_MAX_P2P_SGL_ENTRY)
20607 {
20608 uint32_t ui32Seg = (ui32RemainingData > NI_DMA_SGL_MAX_XFER_SIZE)
20609 ? NI_DMA_SGL_MAX_XFER_SIZE : ui32RemainingData;
20610 sSplitSgl.ui64DMAAddr[ui32SglIdx] = ui64BaseAddr + ui32Offset;
20611 sSplitSgl.ui32DMALen[ui32SglIdx] = ui32Seg;
20612 ui32Offset += ui32Seg;
20613 ui32RemainingData -= ui32Seg;
20614 ui32SglIdx++;
20615 }
20616
20617 if (ui32RemainingData > 0)
20618 {
20619 ni_log2(p_ctx, NI_LOG_ERROR,
20620 "%s: SGL overflow: table full (%u slots) at entry"
20621 " %u/%u, %u bytes unprocessed\n",
20622 __func__, NI_MAX_P2P_SGL_ENTRY,
20623 ui32EntryIdx, ui32OrigEntries, ui32RemainingData);
20624 retval = NI_RETCODE_INVALID_PARAM;
20625 LRETURN;
20626 }
20627 }
20628
20629 if (ui32EntryIdx < ui32OrigEntries)
20630 {
20631 ni_log2(p_ctx, NI_LOG_ERROR,
20632 "%s: SGL overflow: table full (%u slots), "
20633 "%u/%u entries not processed\n",
20634 __func__, NI_MAX_P2P_SGL_ENTRY,
20635 ui32OrigEntries - ui32EntryIdx, ui32OrigEntries);
20636 retval = NI_RETCODE_INVALID_PARAM;
20637 LRETURN;
20638 }
20639
20640 sSplitSgl.ui32NumEntries = ui32SglIdx;
20641
20642 ni_log2(p_ctx, NI_LOG_INFO,
20643 "%s: SGL split: %u original entr%s -> %u chunks "
20644 "(max 0x%X bytes/chunk)\n", __func__,
20645 ui32OrigEntries, ui32OrigEntries == 1 ? "y" : "ies",
20646 ui32SglIdx, NI_DMA_SGL_MAX_XFER_SIZE);
20647
20648 memcpy(p_data + 20, &sSplitSgl.ui32NumEntries, 4);
20649 for (i = 0; i < sSplitSgl.ui32NumEntries; i++)
20650 {
20651 memcpy(&p_data[24] + ((size_t)i * 8), &sSplitSgl.ui64DMAAddr[i], 8);
20652 }
20653 for (i = 0; i < sSplitSgl.ui32NumEntries; i++)
20654 {
20655 memcpy(&p_data[24] + ((size_t)sSplitSgl.ui32NumEntries * 8) + ((size_t)i * 4),
20656 &sSplitSgl.ui32DMALen[i], 4);
20657 }
20658 }
20659 else
20660 {
20661 memcpy(p_data + 20, &dmaAddrs->ui32NumEntries, 4);
20662 for (i = 0; i < dmaAddrs->ui32NumEntries; i++)
20663 {
20664 memcpy(&p_data[24] + ((size_t)i * 8), &dmaAddrs->ui64DMAAddr[i], 8);
20665 }
20666 for (i = 0; i < dmaAddrs->ui32NumEntries; i++)
20667 {
20668 memcpy(&p_data[24] + ((size_t)dmaAddrs->ui32NumEntries * 8) + ((size_t)i * 4),
20669 &dmaAddrs->ui32DMALen[i], 4);
20670 }
20671 }
20672 }
20673
20675
20676 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, NI_INVALID_DEVICE_HANDLE,
20677 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
20678
20679 if (retval < 0)
20680 {
20681 ni_log2(p_ctx, NI_LOG_ERROR, "%s: NVME command failed %d\n", __func__, retval);
20682 ni_aligned_free(p_buffer);
20684 LRETURN;
20685 }
20686
20687END:
20688 if (p_buffer != NULL)
20689 ni_aligned_free(p_buffer);
20690 return retval;
20691}
20692
20694 ni_session_context_t *p_ctx,
20695 const ni_p2p_sgl_t *dmaAddrs,
20696 ni_frame_t *pDstFrame)
20697{
20698 void *p_buffer = NULL;
20699 ni_retcode_t retval;
20700 uint32_t ui32LBA = 0;
20701 niFrameSurface1_t *pSurface;
20702 uint8_t *p_data;
20703 uint16_t ui16Direction = NI_P2P_RECV;
20704 uint32_t ui32Dummy = 0;
20705 uint32_t i;
20706
20707 if (dmaAddrs->ui32NumEntries > NI_MAX_P2P_SGL_ENTRIES)
20708 {
20709 ni_log2(p_ctx, NI_LOG_ERROR, "Too many SGL entries\n");
20710 retval = NI_RETCODE_INVALID_PARAM;
20711 LRETURN;
20712 }
20713
20714 /* allocate memory aligned buffer */
20715 retval = ni_posix_memalign(&p_buffer, sysconf(_SC_PAGESIZE), NI_DATA_BUFFER_LEN);
20716 if (retval != 0)
20717 {
20719 LRETURN;
20720 }
20721
20722 pSurface = (niFrameSurface1_t *) pDstFrame->p_data[3];
20723
20724 memset(p_buffer, 0, NI_DATA_BUFFER_LEN);
20725
20726 p_data = (uint8_t *) p_buffer;
20727
20728 /* Add payload */
20729 memcpy(p_data, &dmaAddrs->ui64DMAAddr[0], 8); // dummy data, not used for p2p read
20730 memcpy(p_data + 8, &ui32Dummy, 4); // dummy data, not used for p2p read
20731 memcpy(p_data + 12, &pSurface->ui16FrameIdx, 2); // dummy data, not used for p2p read
20732 memcpy(p_data + 14, MAGIC_P2P_VALUE, 4);
20733 memcpy(p_data + 18, &ui16Direction, 2);
20734 memcpy(p_data + 20, &dmaAddrs->ui32NumEntries, 4);
20735
20736 for (i = 0; i < dmaAddrs->ui32NumEntries; i++)
20737 {
20738 memcpy(&p_data[24] + ((size_t)i*8), &dmaAddrs->ui64DMAAddr[i], 8);
20739 }
20740
20741 for (i = 0; i < dmaAddrs->ui32NumEntries; i++)
20742 {
20743 memcpy(&p_data[24] + ((size_t)dmaAddrs->ui32NumEntries * 8) + ((size_t)i * 4), &dmaAddrs->ui32DMALen[i], 4);
20744 }
20745
20747
20748 retval = ni_nvme_send_write_cmd(p_ctx->blk_io_handle, p_ctx->event_handle,
20749 p_buffer, NI_DATA_BUFFER_LEN, ui32LBA);
20750
20751 if (retval < 0)
20752 {
20753 ni_log2(p_ctx, NI_LOG_ERROR, "%s: NVME command failed\n", __func__);
20754 ni_aligned_free(p_buffer);
20756 LRETURN;
20757 }
20758
20759END:
20760 if (p_buffer != NULL)
20761 ni_aligned_free(p_buffer);
20762 return retval;
20763}
20764
20765int lower_pixel_rate(const ni_load_query_t *pQuery, uint32_t ui32CurrentLowest)
20766{
20767 return (pQuery->total_pixel_load < ui32CurrentLowest) ? 1 : 0;
20768}
20769
20770/*!******************************************************************************
20771 * \brief set cpu affinity based on numa node
20772 *
20773 * \param[in] p_ctx pointer to session context
20774 *
20775 * \return NI_RETCODE_SUCCESS
20776 * NI_RETCODE_ERROR_MEM_ALOC
20777 *******************************************************************************/
20779{
20780 (void)p_ctx;
20781#if defined(__linux__) && defined(XCODER_ENABLE_CPU_AFFINITY)
20782 int numa_node;
20783 if (numa_available() == -1) {
20784 ni_log2(p_ctx, NI_LOG_INFO, "Warning: %s() NUMA not available.\n",
20785 __func__);
20786 }
20787 else
20788 {
20789 numa_node = ni_rsrc_get_numa_node(p_ctx->blk_xcoder_name);
20790
20791 ni_log2(p_ctx, NI_LOG_DEBUG, "%s(): device name %s, numa node %d\n",
20792 __func__, p_ctx->blk_xcoder_name, numa_node);
20793
20794 if (numa_node < 0)
20795 {
20796 ni_log2(p_ctx, NI_LOG_INFO, "Warning: %s() %s NUMA not available.\n",
20797 __func__, p_ctx->blk_dev_name);
20798 }
20799 else
20800 {
20801#if defined(LIBNUMA_API_VERSION) && (LIBNUMA_API_VERSION == 2)
20802 struct bitmask *node_mask = numa_allocate_nodemask();
20803 if (!node_mask)
20804 {
20805 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR: %s() numa_allocate_cpumask failed.\n",
20806 __func__);
20808 }
20809 numa_bitmask_setbit(node_mask, numa_node);
20810 numa_bind(node_mask);
20811 numa_bitmask_free(node_mask);
20812#else
20813 nodemask_t node_mask;
20814 nodemask_zero(&node_mask);
20815 nodemask_set(&node_mask, numa_node);
20816 numa_bind(&node_mask);
20817#endif
20818 }
20819 }
20820#endif
20821 return NI_RETCODE_SUCCESS;
20822}
20823
20824#ifdef PRINT_FW_LOGS
20830static inline bool is_log_start_marker(const uint8_t* data) {
20831 return (data[0] == FW_LOG_START_DELIMITER_0 && data[1] == FW_LOG_START_DELIMITER_1);
20832}
20833
20839static inline bool is_log_end_marker(const uint8_t* data) {
20840 return (data[0] == FW_LOG_END_DELIMITER_0 && data[1] == FW_LOG_END_DELIMITER_1);
20841}
20842
20848static inline uint64_t extract_timestamp(uint8_t* timestamp_bytes) {
20849 uint64_t timestamp = 0;
20850 // Little-endian extraction
20851 for (int i = 0; i < 8; i++) {
20852 timestamp |= ((uint64_t)timestamp_bytes[i] << (i * 8));
20853 }
20854 return timestamp;
20855}
20856
20864static void ni_find_latest_complete_log(const uint8_t* data, size_t data_size,
20865 log_entry_info_t* latest_entry) {
20866 int index = 0;
20867 uint64_t timestamp = 0, max_timestamp = 0;
20868 log_entry_header_t* header;
20869 uint64_t data_start;
20870 bool found_end;
20871 const uint8_t* end_ptr;
20872
20873 // Initialize latest entry with default values
20874 latest_entry->timestamp = 0;
20875 latest_entry->wrap_around = false;
20876 latest_entry->start_ptr = NULL;
20877 latest_entry->end_ptr = NULL;
20878
20879 while (index < data_size - sizeof(log_entry_trailer_t)) {
20880 // Search for start marker (0x5AA5)
20881 if (!is_log_start_marker(data + index)) {
20882 index++;
20883 continue;
20884 }
20885
20886 // Verify there's enough space for a complete log header
20887 if (index + sizeof(log_entry_header_t) > data_size) {
20888 break;
20889 }
20890
20891 header = (log_entry_header_t*)(data + index);
20892 timestamp = extract_timestamp(header->timestamp);
20893
20894 // Basic timestamp validation (skip invalid/zero timestamps)
20895 if (timestamp == 0) {
20896 index++;
20897 continue;
20898 }
20899
20900 data_start = index + sizeof(log_entry_header_t);
20901 found_end = false;
20902 end_ptr = NULL;
20903
20904 // Search for corresponding end marker (0xA55A)
20905 for (uint64_t j = data_start; j < data_size - sizeof(log_entry_trailer_t); j++) {
20906 if (is_log_end_marker(data + j)) {
20907 found_end = true;
20908 end_ptr = data + j + sizeof(log_entry_trailer_t); // Point after end marker
20909 break;
20910 }
20911 }
20912
20913 if (found_end && end_ptr != NULL) {
20914 // Track the entry with maximum timestamp (latest log)
20915 if (timestamp > max_timestamp) {
20916 max_timestamp = timestamp;
20917 latest_entry->start_ptr = data + index;
20918 latest_entry->end_ptr = end_ptr;
20919 latest_entry->timestamp = timestamp;
20920 latest_entry->wrap_around = false;
20921 }
20922 else
20923 {
20924 latest_entry->wrap_around = true;
20925 }
20926
20927 // Continue search from after the end marker
20928 index = end_ptr - data;
20929 } else {
20930 // No end marker found, continue searching
20931 index++;
20932 }
20933 }
20934
20935 return ;
20936}
20937
20947static void ni_extract_64k_from_end_marker(const uint8_t* data, size_t data_size,
20948 const uint8_t* end_marker_ptr,
20949 uint8_t* output, bool wrap_around) {
20950 uint64_t end_marker_offset = end_marker_ptr - data;
20951 uint64_t extract_start;
20952
20953 ni_log(NI_LOG_ERROR,"End marker position: %zu\n", end_marker_offset);
20954
20955 if (end_marker_offset >= PRINT_FW_LOG_SIZE) {
20956 // Enough data available before end marker
20957 extract_start = end_marker_offset - PRINT_FW_LOG_SIZE;
20958 memcpy(output, data + extract_start, PRINT_FW_LOG_SIZE);
20959 } else if (wrap_around) {
20960 // Wrap around buffer: end + beginning
20961 uint64_t first_part_size = PRINT_FW_LOG_SIZE - end_marker_offset;
20962 uint64_t second_part_size = end_marker_offset;
20963
20964 memcpy(output, data + data_size - first_part_size, first_part_size);
20965
20966 if (second_part_size > 0) {
20967 memcpy(output + first_part_size, data, second_part_size);
20968 }
20969 } else {
20970 // Not enough usefull data, extract from beginning
20971 memcpy(output, data, PRINT_FW_LOG_SIZE);
20972 }
20973
20974 return ;
20975}
20976
20983ni_retcode_t ni_extract_64k_from_latest_log_end(const uint8_t* data, uint8_t* output) {
20985 log_entry_info_t entries;
20986 if (data == NULL || output == NULL) {
20988 }
20989
20990 // Find all complete log entries
20991 ni_find_latest_complete_log(data, CPU_LOG_BUFFER_SIZE, &entries);
20992
20993 if (entries.timestamp == 0) {
20994 ni_log(NI_LOG_ERROR, "Get fw log timestamp == 0,"
20995 " it is not expected, So will print the first 64K fw logs\n");
20996 memcpy(output, data, PRINT_FW_LOG_SIZE);
20997 return ret;
20998 }
20999
21000 // Extract 64KB data
21001 ni_extract_64k_from_end_marker(
21002 data, CPU_LOG_BUFFER_SIZE, entries.end_ptr, output, entries.wrap_around);
21003
21004 return ret;
21005}
21006
21014ni_retcode_t ni_device_print_firmware_logs(ni_session_context_t *p_ctx,
21015 const uint8_t *p_data, uint32_t core_id) {
21017 uint8_t *output = NULL;
21018
21019 if (!p_ctx || !p_data) {
21020 ni_log2(p_ctx, NI_LOG_ERROR, "%s:%d: ERROR invalid pointer p_ctx %p\n",
21021 __func__, __LINE__, p_ctx);
21023 }
21024
21025 ni_log(NI_LOG_ERROR, "%s start print %s log, session id %lu\n",
21026 __func__, ni_get_core_name((ni_core_type_t)core_id), p_ctx->session_id);
21027
21028 // Allocate output buffer
21029 output = malloc(PRINT_FW_LOG_SIZE);
21030 if (output == NULL) {
21031 ni_log(NI_LOG_ERROR, "Failed to allocate output buffer\n");
21032 return NI_RETCODE_FAILURE;
21033 }
21034
21035 // Extract 64KB data from latest log
21036 ret = ni_extract_64k_from_latest_log_end(p_data, output);
21037
21038 // Print extracted data in 256-byte chunks with delimiters
21039 if (ret == NI_RETCODE_SUCCESS) {
21040 uint8_t print_buffer[260]; // 256 + 4 delimiter bytes
21041 int chunks = PRINT_FW_LOG_SIZE / 256;
21042
21043 for (int i = 0; i < chunks; i++) {
21044 uint8_t* ptr = print_buffer;
21045
21046 // Start delimiter
21047 *ptr++ = 0x5B;
21048 *ptr++ = 0xB5;
21049
21050 // Copy data chunk
21051 memcpy(ptr, output + (i * 256), 256);
21052 ptr += 256;
21053
21054 // End delimiter
21055 *ptr++ = 0xB5;
21056 *ptr++ = 0x5B;
21057
21058 // Print hex representation
21059 for (int j = 0; j < sizeof(print_buffer); j++) {
21060 ni_log(NI_LOG_ERROR, "%02X", print_buffer[j]);
21061 }
21062 ni_log(NI_LOG_ERROR, "\n");
21063 }
21064 } else {
21065 ni_log(NI_LOG_ERROR, "%s failed ret %d\n", __func__, ret);
21066 }
21067 // Cleanup
21068 free(output);
21069 return ret;
21070}
21071
21082ni_retcode_t ni_device_get_and_print_firmware_logs(ni_session_context_t *p_ctx)
21083{
21085 bool gen_log_file = false;
21086 void *p_log_buffer = NULL;
21087 int i;
21088 int max_cores;
21089 if(!p_ctx)
21090 {
21091 ni_log2(p_ctx, NI_LOG_ERROR, "%s:():%d: ERROR invalid pointer p_ctx %p\n",
21092 __func__, __LINE__, p_ctx);
21094 }
21095 ni_log(NI_LOG_ERROR, "%s enter, session_id %lu, blk_dev_name %s, hw_id %d\n",
21096 __func__, p_ctx->session_id, p_ctx->blk_dev_name, p_ctx->hw_id);
21097
21098 if (ni_posix_memalign(&p_log_buffer, sysconf(_SC_PAGESIZE), CPU_LOG_BUFFER_SIZE))
21099 {
21100 ni_log2(p_ctx, NI_LOG_ERROR, "ERROR %d: %s() Cannot allocate log buffer\n",
21101 NI_ERRNO, __func__);
21103 }
21104
21106 "6t1") < 0)
21107 {
21108 max_cores = FP_CORE;
21109 }
21110 else
21111 {
21112 max_cores = FL_CORE;
21113 }
21114
21115 for (i = NVME_CORE; i<= max_cores; i++)
21116 {
21117 memset(p_log_buffer, 0, CPU_LOG_BUFFER_SIZE);
21118 retval = ni_dump_log_single_core(p_ctx, p_log_buffer, i, gen_log_file);
21119 if (retval != NI_RETCODE_SUCCESS)
21120 {
21121 ni_log2(p_ctx, NI_LOG_ERROR, "ni_dump_log_single_core failed\n");
21122 LRETURN;
21123 }
21124
21125 retval = ni_device_print_firmware_logs(p_ctx, p_log_buffer, i);
21126 if (retval != NI_RETCODE_SUCCESS)
21127 {
21128 ni_log2(p_ctx, NI_LOG_ERROR, "ni_device_print_firmware_logs failed\n");
21129 LRETURN;
21130 }
21131 }
21132
21133END:
21134
21135 ni_aligned_free(p_log_buffer);
21136 return retval;
21137}
21138#endif
#define LOG_ARTIFACTS_MAX_SIZE
Definition ni_defs.h:378
#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:588
@ nvme_cmd_xcoder_read
Definition ni_defs.h:589
#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:384
@ FP_CORE
Definition ni_defs.h:390
@ ALL_CORE
Definition ni_defs.h:385
@ EP_CORE
Definition ni_defs.h:387
@ TP_CORE
Definition ni_defs.h:389
@ NVME_CORE
Definition ni_defs.h:386
@ DP_CORE
Definition ni_defs.h:388
@ FL_CORE
Definition ni_defs.h:391
#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:602
@ NI_SCALER_OPCODE_OVERLAY
Definition ni_defs.h:598
@ NI_SCALER_OPCODE_SCALE
Definition ni_defs.h:594
@ NI_SCALER_OPCODE_WATERMARK
Definition ni_defs.h:603
@ NI_SCALER_OPCODE_STACK
Definition ni_defs.h:599
@ NI_SCALER_OPCODE_ROTATE
Definition ni_defs.h:600
@ NI_SCALER_OPCODE_AI_ALIGN
Definition ni_defs.h:606
#define PRINT_FW_LOG_SIZE
Definition ni_defs.h:380
#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:447
@ NI_RETCODE_PARAM_ERROR_INTRA_PERIOD
Definition ni_defs.h:466
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_BIG
Definition ni_defs.h:519
@ NI_RETCODE_PARAM_ERROR_BRATE
Definition ni_defs.h:461
@ NI_RETCODE_PARAM_ERROR_HVS_QP_EN
Definition ni_defs.h:478
@ NI_RETCODE_FAILURE
Definition ni_defs.h:449
@ NI_RETCODE_PARAM_ERROR_VBV_BUFFER_SIZE
Definition ni_defs.h:465
@ NI_RETCODE_EAGAIN
Definition ni_defs.h:550
@ NI_RETCODE_PARAM_ERROR_CUSIZE_MODE_8X8_EN
Definition ni_defs.h:507
@ NI_RETCODE_PARAM_ERROR_CUSIZE_MODE_32X32_EN
Definition ni_defs.h:509
@ NI_RETCODE_PARAM_ERROR_RCENABLE
Definition ni_defs.h:497
@ NI_RETCODE_PARAM_ERROR_MX_DELTA_QP
Definition ni_defs.h:484
@ NI_RETCODE_PARAM_ERROR_LOOK_AHEAD_DEPTH
Definition ni_defs.h:538
@ NI_RETCODE_PARAM_ERROR_CONF_WIN_R
Definition ni_defs.h:492
@ NI_RETCODE_ERROR_INVALID_SESSION
Definition ni_defs.h:454
@ NI_RETCODE_PARAM_ERROR_CU_SIZE_MODE
Definition ni_defs.h:471
@ NI_RETCODE_PARAM_ERROR_CONF_WIN_BOT
Definition ni_defs.h:488
@ NI_RETCODE_ERROR_UNSUPPORTED_FW_VERSION
Definition ni_defs.h:542
@ NI_RETCODE_PARAM_ERROR_MN_QP
Definition ni_defs.h:480
@ NI_RETCODE_NVME_SC_INVALID_PARAMETER
Definition ni_defs.h:565
@ NI_RETCODE_PARAM_ERROR_PIC_WIDTH
Definition ni_defs.h:501
@ NI_RETCODE_PARAM_ERROR_CONF_WIN_TOP
Definition ni_defs.h:486
@ NI_RETCODE_PARAM_ERROR_CONF_WIN_L
Definition ni_defs.h:490
@ NI_RETCODE_PARAM_ERROR_DECODING_REFRESH_TYPE
Definition ni_defs.h:505
@ NI_RETCODE_PARAM_ERROR_AREA_TOO_BIG
Definition ni_defs.h:523
@ NI_RETCODE_PARAM_ERROR_FRATE
Definition ni_defs.h:459
@ NI_RETCODE_NVME_SC_WRITE_BUFFER_FULL
Definition ni_defs.h:555
@ NI_RETCODE_NVME_SC_VPU_RECOVERY
Definition ni_defs.h:568
@ NI_RETCODE_SUCCESS
Definition ni_defs.h:448
@ NI_RETCODE_PARAM_ERROR_HEIGHT_TOO_SMALL
Definition ni_defs.h:521
@ NI_RETCODE_PARAM_WARN
Definition ni_defs.h:547
@ NI_RETCODE_ERROR_INVALID_HANDLE
Definition ni_defs.h:532
@ NI_RETCODE_PARAM_INVALID_VALUE
Definition ni_defs.h:458
@ NI_RETCODE_ERROR_RESOURCE_UNAVAILABLE
Definition ni_defs.h:455
@ NI_RETCODE_PARAM_ERROR_CU_LVL_RC_EN
Definition ni_defs.h:476
@ NI_RETCODE_PARAM_ERROR_INTRA_QP
Definition ni_defs.h:468
@ NI_RETCODE_PARAM_ERROR_MAXNUMMERGE
Definition ni_defs.h:498
@ NI_RETCODE_NVME_SC_RESOURCE_UNAVAILABLE
Definition ni_defs.h:557
@ NI_RETCODE_PARAM_ERROR_GOP_PRESET
Definition ni_defs.h:469
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_BIG
Definition ni_defs.h:515
@ NI_RETCODE_ERROR_NVME_CMD_FAILED
Definition ni_defs.h:453
@ NI_RETCODE_PARAM_ERROR_USR_RMD_ENC_PARAM
Definition ni_defs.h:494
@ NI_RETCODE_PARAM_ERROR_PIC_HEIGHT
Definition ni_defs.h:503
@ NI_RETCODE_NVME_SC_VPU_RSRC_INSUFFICIENT
Definition ni_defs.h:569
@ NI_RETCODE_ERROR_MEM_ALOC
Definition ni_defs.h:452
@ NI_RETCODE_ERROR_UNSUPPORTED_FEATURE
Definition ni_defs.h:543
@ NI_RETCODE_PARAM_ERROR_OOR
Definition ni_defs.h:514
@ NI_RETCODE_PARAM_ERROR_CUSIZE_MODE_16X16_EN
Definition ni_defs.h:508
@ NI_RETCODE_ERROR_VPU_RECOVERY
Definition ni_defs.h:536
@ NI_RETCODE_PARAM_ERROR_WIDTH_TOO_SMALL
Definition ni_defs.h:517
@ NI_RETCODE_PARAM_ERROR_CUSTOM_GOP
Definition ni_defs.h:499
@ NI_RETCODE_INVALID_PARAM
Definition ni_defs.h:450
@ NI_RETCODE_PARAM_ERROR_TOO_SMALL
Definition ni_defs.h:511
@ NI_RETCODE_PARAM_ERROR_MX_QP
Definition ni_defs.h:482
#define FL_SIGNATURE
Definition ni_defs.h:381
#define CPU_LOG_ARTIFACTS_HEADER_SIZE
Definition ni_defs.h:377
#define IS_XCODER_DEVICE_TYPE(t)
Definition ni_defs.h:431
#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.
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
#define NI_SCALER_Q14_ONE
@ 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
#define NI_SCALER_KERNEL_SLOTS
@ 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_HDR10P_SEI_HDR_AV1_LEN
#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_HDR_AV1_LEN
#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.
#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
#define NI_SCALER_MAX_KERNEL_TAPS
@ 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_SCALER_KERNEL_POSITIONS
#define NI_HDR10P_SEI_BYTE5
#define NI_SCALER_ALGORITHM_USER_KERNEL
#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
#define MOTION_CONSTRAINED_QUALITY_MODE_ADVANCED
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_MAX_DEFAULT_RETRY
#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_dump_log_artifacts(ni_session_context_t *p_ctx, bool gen_artifacts_file)
Read log artifacts (tar.gz) from the device via NVMe and write them to "artifacts_slot_s_dddd....
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
struct _ni_scaler_config ni_scaler_config_t
#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:661
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:927
#define CONFIG_INSTANCE_SetAiHVSPlus_W(sid, instance)
Definition ni_nvme.h:863
#define QUERY_INSTANCE_UPLOAD_ID_R(sid, instance)
Definition ni_nvme.h:744
#define CONFIG_INSTANCE_SetScalerPara_W(sid, instance)
Definition ni_nvme.h:823
#define CONFIG_INSTANCE_SetSOS_W(sid, instance)
Definition ni_nvme.h:812
#define CONFIG_INSTANCE_SetP2P_W(sid, instance)
Definition ni_nvme.h:874
#define WRITE_METADATA_W(sid, instance)
Definition ni_nvme.h:681
#define LBA_BIT_OFFSET
Definition ni_nvme.h:628
#define CONFIG_SESSION_FRAME_COPY_W(sid)
Definition ni_nvme.h:915
#define FL_LOG_OFFSET_IN_4K
Definition ni_nvme.h:669
@ 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:724
#define QUERY_INSTANCE_NL_V2_R(sid, instance)
Definition ni_nvme.h:775
#define WRITE_INSTANCE_W(sid, instance)
Definition ni_nvme.h:679
#define QUERY_INSTANCE_ACQUIRE_BUF(sid, instance)
Definition ni_nvme.h:746
#define QUERY_INSTANCE_NL_R(sid, instance)
Definition ni_nvme.h:763
#define QUERY_INSTANCE_RBUFF_SIZE_BUSY_R(sid, instance)
Definition ni_nvme.h:734
#define CONFIG_INSTANCE_SetEOS_W(sid, instance)
Definition ni_nvme.h:814
#define CONFIG_SESSION_DDR_PRIORITY_W(sid)
Definition ni_nvme.h:909
#define DOWNLOAD_FRAMEIDX_R(frame_id)
Definition ni_nvme.h:688
#define CONFIG_INSTANCE_SetScalerAlloc_W(sid, instance)
Definition ni_nvme.h:828
#define FP_LOG_OFFSET_IN_4K
Definition ni_nvme.h:668
#define QUERY_INSTANCE_HW_OUT_SIZE_R(sid, instance)
Definition ni_nvme.h:752
#define CONFIG_INSTANCE_Flush_W(sid, instance)
Definition ni_nvme.h:816
#define CONFIG_INSTANCE_SetPktSize_W(sid, instance)
Definition ni_nvme.h:852
#define NVME_LOG_OFFSET_IN_4K
Definition ni_nvme.h:664
#define CONFIG_INSTANCE_SetDecPpuPara_W(sid, instance)
Definition ni_nvme.h:821
#define CLOSE_SESSION_R(sid, instance)
Definition ni_nvme.h:706
#define ARTIFACTS_OFFSET_IN_4K
Definition ni_nvme.h:670
#define QUERY_INSTANCE_RBUFF_SIZE_R(sid, instance)
Definition ni_nvme.h:728
#define CONFIG_INSTANCE_SetAiFrm_W(sid, instance)
Definition ni_nvme.h:868
#define QUERY_GENERAL_GET_STATUS_R(instance)
Definition ni_nvme.h:787
#define QUERY_SESSION_STATS_R(sid, instance)
Definition ni_nvme.h:712
#define EP_LOG_OFFSET_IN_4K
Definition ni_nvme.h:665
#define CONFIG_SESSION_Read_W(sid)
Definition ni_nvme.h:883
#define IDENTIFY_DEVICE_R
Definition ni_nvme.h:692
#define QUERY_INSTANCE_WBUFF_SIZE_R_BY_EP(sid, instance)
Definition ni_nvme.h:732
#define NI_DATA_BUFFER_LEN
Definition ni_nvme.h:627
#define QUERY_INSTANCE_EOS_R(sid, instance)
Definition ni_nvme.h:726
#define TP_LOG_OFFSET_IN_4K
Definition ni_nvme.h:667
#define QUERY_DETAIL_GET_STATUS_R(instance)
Definition ni_nvme.h:790
#define QUERY_INSTANCE_AI_INFO_R(sid, instance)
Definition ni_nvme.h:719
#define CONFIG_SESSION_KeepAlive_W(sid)
Definition ni_nvme.h:881
#define CONFIG_INSTANCE_SetEncRoiQpMap_W(sid, instance)
Definition ni_nvme.h:856
#define QUERY_INSTANCE_METRICS_R(sid, instance)
Definition ni_nvme.h:781
#define CONFIG_INSTANCE_SetEncFramePara_W(sid, instance)
Definition ni_nvme.h:850
#define QUERY_INSTANCE_CUR_STATUS_INFO_R(sid, instance)
Definition ni_nvme.h:717
#define QUERY_INSTANCE_NL_SIZE_R(sid, instance)
Definition ni_nvme.h:758
#define CLEAR_INSTANCE_BUF_W(frame_id)
Definition ni_nvme.h:888
#define CONFIG_INSTANCE_SetAiPara_W(sid, instance)
Definition ni_nvme.h:858
#define QUERY_INSTANCE_WBUFF_SIZE_BUSY_R(sid, instance)
Definition ni_nvme.h:739
#define CONFIG_INSTANCE_SetSeqChange_W(sid, instance)
Definition ni_nvme.h:854
#define OPEN_ADD_CODEC(instance, codec, param)
Definition ni_nvme.h:701
#define NI_NVME_IDENTITY_CMD_DATA_SZ
Definition ni_nvme.h:38
#define CONFIG_SESSION_KeepAliveTimeout_W(sid)
Definition ni_nvme.h:892
#define CONFIG_INSTANCE_SetEncPara_W(sid, instance)
Definition ni_nvme.h:846
#define READ_INSTANCE_R(sid, instance)
Definition ni_nvme.h:685
#define QUERY_INSTANCE_WBUFF_SIZE_R(sid, instance)
Definition ni_nvme.h:730
#define QUERY_INSTANCE_NL_SIZE_V2_R(sid, instance)
Definition ni_nvme.h:769
#define QUERY_DETAIL_GET_STATUS_V1_R(instance)
Definition ni_nvme.h:792
@ nvme_config_xcoder_config_set_write_legth
Definition ni_nvme.h:436
@ nvme_config_xcoder_config_set_sequence_change
Definition ni_nvme.h:438
#define CONFIG_SESSION_SWVersion_W(sid)
Definition ni_nvme.h:898
#define CONFIG_SESSION_Write_W(sid)
Definition ni_nvme.h:885
#define OPEN_SESSION_CODEC(instance, codec, param)
Definition ni_nvme.h:699
#define CONFIG_INSTANCE_SetDecPara_W(sid, instance)
Definition ni_nvme.h:819
#define DP_LOG_OFFSET_IN_4K
Definition ni_nvme.h:666
#define CONFIG_GLOBAL_NAMESPACE_NUM
Definition ni_nvme.h:904
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:2013
int ni_pthread_mutex_lock(ni_pthread_mutex_t *mutex)
thread mutex lock
Definition ni_util.c:4768
void ni_buffer_pool_free(ni_queue_buffer_pool_t *p_buffer_pool)
Definition ni_util.c:1427
void ni_dec_fme_buffer_pool_free(ni_buf_pool_t *p_buffer_pool)
Definition ni_util.c:1373
ni_retcode_t ni_strncpy(char *dest, size_t dmax, const char *src, size_t slen)
Definition ni_util.c:525
int ni_pthread_cond_signal(ni_pthread_cond_t *cond)
signal a condition
Definition ni_util.c:4962
int ni_posix_memalign(void **memptr, size_t alignment, size_t size)
Allocate aligned memory.
Definition ni_util.c:206
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:4353
ni_retcode_t ni_strerror(char *dest, size_t dmax, int errnum)
Definition ni_util.c:663
void ni_calculate_sha256(const uint8_t aui8Data[], size_t ui32DataLength, uint8_t aui8Hash[])
Definition ni_util.c:4257
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:1264
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:2064
ni_retcode_t ni_strcat(char *dest, size_t dmax, const char *src)
Definition ni_util.c:704
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:2743
ni_retcode_t ni_fopen(FILE **fp, const char *filename, const char *mode)
Definition ni_util.c:998
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:5016
ni_retcode_t ni_strcpy(char *dest, size_t dmax, const char *src)
Definition ni_util.c:460
uint32_t ni_ai_network_layer_size(ni_network_layer_params_t *p_param)
Definition ni_util.c:4070
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:4982
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:1948
void ni_usleep(int64_t usec)
Definition ni_util.c:366
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:2453
uint64_t ni_gettime_ns(void)
Definition ni_util.c:2701
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:2072
int ni_pthread_mutex_unlock(ni_pthread_mutex_t *mutex)
thread mutex unlock
Definition ni_util.c:4794
ni_retcode_t ni_strtoi(const char *str, int32_t *out_val)
Safely convert a decimal string to a 32-bit integer with full validation. Trailing whitespace is tole...
Definition ni_util.c:2577
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:4383
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:402
#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:412
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
uint8_t timecode_present
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:426
uint64_t ui64DMAAddr[NI_MAX_P2P_SGL_ENTRY]
Definition ni_defs.h:428
uint32_t ui32DMALen[NI_MAX_P2P_SGL_ENTRY]
Definition ni_defs.h:427
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
uint16_t kernel_array[2][NI_SCALER_KERNEL_POSITIONS *NI_SCALER_KERNEL_SLOTS]
uint16_t kernel_array[2][17 *9]
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
uint8_t itu_t_t35_hdr10p_sei_hdr_av1[NI_HDR10P_SEI_HDR_AV1_LEN]
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
uint8_t itu_t_t35_cc_sei_hdr_av1[NI_CC_SEI_HDR_AV1_LEN]
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:401
uint32_t ui32FramesDropped
Definition ni_defs.h:404
uint8_t ui8AdditionalFramesDelay
Definition ni_defs.h:417
uint32_t ui32LastTransactionCompletionStatus
Definition ni_defs.h:410
uint32_t ui32FramesCorrupted
Definition ni_defs.h:419
uint32_t ui32LastErrorStatus
Definition ni_defs.h:412
uint32_t ui32RdBufAvailSize
Definition ni_defs.h:398
uint32_t ui32WrBufAvailSize
Definition ni_defs.h:397
uint32_t ui32LastErrorTransactionId
Definition ni_defs.h:411
uint32_t ui32FramesCompleted
Definition ni_defs.h:402
uint32_t ui32FramesOutput
Definition ni_defs.h:403
uint32_t ui32FramesErrorRatio
Definition ni_defs.h:420
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