libxcoder  3.5.1
test_rsrc_api_logan.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  *
24  * @file test_rsrc_api_logan.c
25  *
26  * @date April 1, 2018
27  *
28  * @brief Example code to test resource API
29  *
30  * @author
31  *
32  ******************************************************************************/
33 
34 #ifdef __linux__
35 #include <unistd.h>
36 #include <sys/file.h> /* For flock constants */
37 #endif
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <fcntl.h>
41 #include <string.h>
42 #include <errno.h>
43 
44 #include "ni_rsrc_api_logan.h"
45 #include "ni_rsrc_priv_logan.h"
46 #include "ni_util_logan.h"
47 
48 
49 /*******************************************************************************
50  * @brief
51  *
52  * @param
53  *
54  * @return
55  *******************************************************************************/
56 void getStr(const char *prompt, char *str)
57 {
58  char para[16];
59  printf("%s", prompt);
60 
61  if (fgets(para, sizeof(para), stdin) != 0) {
62  size_t len = strlen(para);
63  if (len > 0 && para[len - 1] == '\n')
64  {
65  para[len - 1] = '\0';
66  }
67  str[0] = '\0';
68  strncat(str, para, strlen(para));
69  }
70 }
71 
72 /*******************************************************************************
73  * @brief
74  *
75  * @param
76  *
77  * @return
78  *******************************************************************************/
79 int getCmd(const char *prompt)
80 {
81  char cmd[16];
82 
83  getStr(prompt, cmd);
84  return (int)cmd[0];
85 }
86 
87 /******************************************************************************
88  * @brief
89  *
90  * @param
91  *
92  * @return
93  ******************************************************************************/
94 void change_log_level(void)
95 {
96  char log_level[16];
97  getStr("set log level to [info, debug, trace]: ", log_level);
98  if (!strcmp(log_level, "none")) {
100  } else if (!strcmp(log_level, "fatal")) {
102  } else if (!strcmp(log_level, "error")) {
104  } else if (!strcmp(log_level, "info")) {
106  } else if (!strcmp(log_level, "debug")) {
108  } else if (!strcmp(log_level, "trace")) {
110  } else {
111  printf("unknown log level selected: %s", log_level);
112  return;
113  }
114 }
115 
116 /*******************************************************************************
117  * @brief
118  *
119  * @param
120  *
121  * @return
122  *******************************************************************************/
123 int getInt(const char *prompt)
124 {
125  char para[16];
126 
127  getStr(prompt, para);
128  return atoi(para);
129 }
130 
131 /*******************************************************************************
132  * @brief
133  *
134  * @param
135  *
136  * @return
137  *******************************************************************************/
138 float getFloat(const char *prompt)
139 {
140  char para[16];
141 
142  getStr(prompt, para);
143  return (float)atof(para);
144 }
145 
146 /*******************************************************************************
147  * @brief
148  *
149  * @param
150  *
151  * @return
152  *******************************************************************************/
153 long getLong(const char *prompt)
154 {
155  char para[32];
156 
157  getStr(prompt, para);
158  return atol(para);
159 }
160 
161 /*******************************************************************************
162  * @brief
163  *
164  * @param
165  *
166  * @return
167  *******************************************************************************/
169 {
171  int i, count = 0;
172 
173  // Store array of ni_logan_device_info_t in heap as each ni_logan_device_info_t is ~1.75KB
175  if (NULL == coders) {
176  fprintf(stderr, "Error failed to malloc ni_logan_device_info_t * %d\n",
178  return;
179  }
180  memset(coders, 0, sizeof(ni_logan_device_info_t) * LOGAN_MAX_DEVICE_CNT);
181 
182  type = (ni_logan_device_type_t) getInt("coder type, decoder (0) encoder (1): ");
183  if (ni_logan_rsrc_list_devices(type, coders, &count) == 0) {
184  for (i = 0; i < count; i++) {
186  }
187  }
188  free(coders);
189 }
190 
191 /*******************************************************************************
192  * @brief
193  *
194  * @param
195  *
196  * @return
197  *******************************************************************************/
198 void listModuleId(void)
199 {
200  /* read back the stored coders numbers */
201  uint32_t i;
203  ni_logan_device_pool_t *p_device_pool;
204  ni_logan_device_info_t *p_device_info;
205 
206  p_device_pool = ni_logan_rsrc_get_device_pool();
207  if (p_device_pool)
208  {
209 #ifdef _WIN32
210  if (WAIT_ABANDONED == WaitForSingleObject(p_device_pool->lock, INFINITE)) // no time-out interval)
211  {
212  fprintf(stderr, "ERROR: listModuleId() failed o obtain mutex: %p", p_device_pool->lock);
213  return;
214  }
215 #elif defined(__linux__)
216  if( flock(p_device_pool->lock, LOCK_EX) )
217  {
218  fprintf(stderr, "Error flock() failed\n");
219  }
220 #endif
221 
222  /* print out coders in their current order */
223  ptr = p_device_pool->p_device_queue;
224  printf("Num decoders: %d\n", ptr->decoders_cnt);
225  for (i = 0; i < ptr->decoders_cnt; i++) {
227  printf("[%d]. %d (load: %d inst: %d %s.%d)\n", i, ptr->decoders[i],
228  p_device_info->load, p_device_info->active_num_inst, p_device_info->dev_name, p_device_info->hw_id);
229  free(p_device_info);
230  }
231  printf("\n\nNum encoders: %d\n", ptr->encoders_cnt);
232  for (i = 0; i < ptr->encoders_cnt; i++) {
234  printf("[%d]. %d (load: %d inst: %d %s.%d)\n", i, ptr->encoders[i],
235  p_device_info->load, p_device_info->active_num_inst, p_device_info->dev_name, p_device_info->hw_id);
236  free(p_device_info);
237  }
238  printf("\n\n");
239 
240 #ifdef _WIN32
241  ReleaseMutex(p_device_pool->lock);
242 #elif defined(__linux__)
243  if( flock(p_device_pool->lock, LOCK_UN) )
244  {
245  fprintf(stderr, "Error flock() failed\n");
246  }
247 #endif
248  ni_logan_rsrc_free_device_pool(p_device_pool);
249  }
250 }
251 
252 /*******************************************************************************
253  * @brief
254  *
255  * @param
256  *
257  * @return
258  *******************************************************************************/
260 {
261  int i;
262  // Store ni_logan_device_t in heap as it is ~450KB
263  ni_logan_device_t *coders = malloc(sizeof(ni_logan_device_t));
264  if (NULL == coders) {
265  fprintf(stderr, "Error failed to malloc ni_logan_device_t\n");
266  return;
267  }
268  memset(coders, 0, sizeof(ni_logan_device_t));
269 
270  if (ni_logan_rsrc_list_all_devices(coders) == 0) {
271  /* print out coders in the order based on their guid */
272  printf("Num decoders: %d\n", coders->decoders_cnt);
273 
274  for (i = 0; i < coders->decoders_cnt; i++) {
276  }
277  printf("Num encoders: %d\n", coders->encoders_cnt);
278  for (i = 0; i < coders->encoders_cnt; i++) {
280  }
281  }
282  free(coders);
283 }
284 
285 /*******************************************************************************
286  * @brief
287  *
288  * @param
289  *
290  * @return
291  *******************************************************************************/
292 void updateCoderLoad(void)
293 {
295  int guid;
296  int load;
297  ni_logan_device_context_t *p_device_context;
298  int i, nb_insts;
299  ni_logan_sw_instance_info_t sw_insts[8];
300 
301  type = (ni_logan_device_type_t)getInt("coder type, decoder (0) encoder (1): ");
302  guid = getInt("Coder module ID: ");
303  load = getInt("load value: ");
304  nb_insts = getInt("Number of s/w instances: ");
305  for (i = 0; i < nb_insts; i++) {
306  sw_insts[i].id = getInt("s/w inst. id: ");
307  sw_insts[i].status = (ni_sw_instance_status_t)getInt("s/w inst. status, idle (0) active (1): ");
308  sw_insts[i].codec = (ni_codec_t)getInt("s/w inst. codec, H.264 (0) H.265 (1): ");
309  sw_insts[i].width = getInt("s/w inst. width: ");
310  sw_insts[i].height = getInt("s/w inst. height: ");
311  sw_insts[i].fps = getInt("s/w inst. fps: ");
312  }
313 
314  p_device_context = ni_logan_rsrc_get_device_context(type, guid);
315  if (p_device_context) {
316  ni_logan_rsrc_update_device_load(p_device_context, load, nb_insts, sw_insts);
317  ni_logan_rsrc_free_device_context(p_device_context);
318  } else {
319  printf("Error coder not found ..\n");
320  }
321 }
322 
323 /*******************************************************************************
324  * @brief
325  *
326  * @param
327  *
328  * @return
329  *******************************************************************************/
331 {
333  int guid;
334  ni_logan_device_info_t *p_device_info;
335 
336  type = (ni_logan_device_type_t)getInt("coder type, decoder (0) encoder (1): ");
337  guid = getInt("Coder module ID: ");
338  printf("type: %d id %d\n", type, guid);
339  p_device_info = ni_logan_rsrc_get_device_info(type, guid);
340  if (p_device_info) {
341  ni_logan_rsrc_print_device_info(p_device_info);
342  free(p_device_info);
343  }
344 }
345 
346 /******************************************************************************
347  * @brief
348  *
349  * @param
350  *
351  * @return
352  ******************************************************************************/
354 {
355  int guid, width, height, fps;
356  ni_codec_t codec;
359 
360  type = (ni_logan_device_type_t)getInt("coder type, decoder (0) encoder (1): ");
361  codec = (ni_codec_t)getInt("codec, H.264 (0) H.265 (1): ");
362  width = getInt("video width: ");
363  height = getInt("video height: ");
364  fps = getInt("video frame rate: ");
365  guid = ni_logan_rsrc_get_available_device(width, height, fps, codec, type, &info);
366  if (guid == -1) {
367  printf("Error coder not found ..\n");
368  } else {
370  }
371 }
372 
373 /*******************************************************************************
374  * @brief
375  *
376  * @param
377  *
378  * @return
379  *******************************************************************************/
380 void allocAuto(void)
381 {
382  ni_logan_device_context_t *p_device_context;
384  ni_alloc_rule_t rule;
385  unsigned long model_load;
386 
387  type = (ni_logan_device_type_t)getInt("coder type, decoder (0) encoder (1): ");
388  rule = (ni_alloc_rule_t)getInt("auto-alloc rule, least-load (0) load-instance (1): ");
389  printf("type: %d rule %d\n", type, rule);
390 
391  p_device_context = ni_logan_rsrc_allocate_auto(type, rule, EN_H265, 1920, 1080, 30, &model_load);
392  if (p_device_context) {
393  printf("Successfully auto-allocated s/w instance on:\n");
395  printf("Allocated load: %ld\n", model_load);
396  ni_logan_rsrc_free_device_context(p_device_context);
397  }
398 }
399 
400 /*******************************************************************************
401  * @brief
402  *
403  * @param
404  *
405  * @return
406  *******************************************************************************/
407 void allocDirect(void)
408 {
409  ni_logan_device_context_t *p_device_context;
411  int guid;
412  unsigned long model_load;
413 
414  type = (ni_logan_device_type_t)getInt("coder type, decoder (0) encoder (1): ");
415  guid = getInt("Coder module ID: ");
416  printf("type: %d id %d\n", type, guid);
417 
418  p_device_context = ni_logan_rsrc_allocate_direct(type, guid, EN_H264, 1920, 1080, 30, &model_load);
419  if (p_device_context) {
420  printf("Successfully allocated directly the s/w instance ..\n");
421  ni_logan_rsrc_free_device_context(p_device_context);
422  }
423 }
424 
425 /*******************************************************************************
426  * @brief
427  *
428  * @param
429  *
430  * @return
431  ******************************************************************************/
432 void releaseEncRsrc(void)
433 {
434  unsigned long load;
435  int guid;
436  ni_logan_device_context_t *p_device_context;
437  //ni_logan_device_info_t *p_device_info;
438 
439  guid = getInt("Coder module ID: ");
440  load = (unsigned long)getLong("load value: ");
441  printf("id %d load: %ld\n", guid, load);
443  if (p_device_context) {
445  ni_logan_rsrc_free_device_context(p_device_context);
446  } else {
447  printf("Error coder not found ..\n");
448  }
449 }
450 
451 /******************************************************************************
452  * @brief
453  *
454  * @param
455  *
456  * @return
457  ******************************************************************************/
458 void deleteCoder(void)
459 {
460  char dev[16];
461  getStr("device name (/dev/*): ", dev);
463 }
464 
465 /*******************************************************************************
466  * @brief
467  *
468  * @param
469  *
470  * @return
471  ******************************************************************************/
472 void addCoder(void)
473 {
474  char dev[16];
475  int should_match_rev = 0;
476  getStr("device name (/dev/*): ", dev);
477  should_match_rev = getInt("should match current release version, yes (1) no (0): ");
478  ni_logan_rsrc_add_device(dev, should_match_rev);
479 }
480 
481 /*******************************************************************************
482  * @brief
483  *
484  * @param
485  *
486  * @return
487  ******************************************************************************/
488 void checkHW(void)
489 {
491  int guid;
492  int rc;
493 
494  type = (ni_logan_device_type_t)getInt("coder type, decoder (0) encoder (1): ");
495  guid = getInt("Coder module ID (GUID): ");
496  printf("type: %d id %d\n", type, guid);
497 
498  rc = ni_logan_rsrc_codec_is_available(guid, type);
499  if (rc == NI_LOGAN_RETCODE_SUCCESS)
500  {
501  printf("%s module ID (GUID) %d is good\n", (type ==0 ? "decoder":"encoder"), guid);
502  }
503  else
504  {
505  printf("%s module ID (GUID) %d is bad\n", (type ==0 ? "decoder":"encoder"), guid);
506  }
507 }
508 
509 /*******************************************************************************
510  * @brief
511  *
512  * @param
513  *
514  * @return
515  ******************************************************************************/
516 void checkHWInfo(void)
517 {
519  printf("**************************************************\n");
520 
522  printf("\n");
524 
525  printf("**************************************************\n\n\n");
526 }
527 /*******************************************************************************
528  * @brief
529  *
530  * @param
531  *
532  * @return
533  *******************************************************************************/
534 int main(void)
535 {
536  int stop = 0;
537  int control;
538  while (!stop) {
539  printf("Key function\n"
540  "? show this help\n"
541  "v change libxcoder_logan log level\n"
542  "l list all decoders, or all encoders\n"
543  "L list all coders detailed info\n"
544  "o list all coders' module #, in order of position in queue\n"
545  "g get a coder's info\n"
546  "G get the least used coder for a video stream\n"
547  "u update a coder's load/instances value\n"
548  "A allocate directly a s/w instance on a h/w coder\n"
549  "a allocate automatically a s/w instance\n"
550  "r release encoding resource (load) from a h/w instance\n"
551  "d delete xcoder from host resource pool\n"
552  "x add xcoder into host resource pool\n"
553  "c check hardware status in resource pool\n"
554  "C check hardware device detailed info\n"
555  "q quit\n");
556  control = getCmd("> ");
557 
558  switch (control) {
559  case '?':
560  continue;
561  case 'v':
563  case 'l':
565  break;
566  case 'L':
568  break;
569  case 'o':
570  listModuleId();
571  break;
572  case 'g':
574  break;
575  case 'G':
577  break;
578  case 'u':
579  updateCoderLoad();
580  break;
581  case 'A':
582  allocDirect();
583  break;
584  case 'a':
585  allocAuto();
586  break;
587  case 'r':
588  releaseEncRsrc();
589  break;
590  case 'd':
591  deleteCoder();
592  break;
593  case 'x':
594  addCoder();
595  break;
596  case 'c':
597  checkHW();
598  break;
599  case 'C':
600  checkHWInfo();
601  break;
602  case 'q':
603  case EOF:
604  stop = 1;
605  break;
606  default:
607  continue;
608  }
609  }
610  return 0;
611 }
@ NI_LOGAN_RETCODE_SUCCESS
#define LOGAN_MAX_DEVICE_CNT
ni_logan_device_type_t
@ NI_LOGAN_DEVICE_TYPE_ENCODER
@ NI_LOGAN_DEVICE_TYPE_DECODER
#define atof(p_str)
#define atoi(p_str)
void ni_log_set_level(ni_log_level_t level)
Set ni_log_level.
Definition: ni_log_logan.c:138
@ NI_LOG_NONE
Definition: ni_log_logan.h:62
@ NI_LOG_DEBUG
Definition: ni_log_logan.h:66
@ NI_LOG_TRACE
Definition: ni_log_logan.h:67
@ NI_LOG_FATAL
Definition: ni_log_logan.h:63
@ NI_LOG_ERROR
Definition: ni_log_logan.h:64
@ NI_LOG_INFO
Definition: ni_log_logan.h:65
ni_logan_retcode_t ni_logan_rsrc_list_all_devices(ni_logan_device_t *p_device)
List all devices with full information including s/w instances on the system.
ni_logan_device_context_t * ni_logan_rsrc_get_device_context(ni_logan_device_type_t device_type, int guid)
Allocates and returns a pointer to ni_logan_device_context_t struct based on provided device_type and...
ni_logan_retcode_t ni_logan_rsrc_list_devices(ni_logan_device_type_t device_type, ni_logan_device_info_t *p_device_info, int *p_device_count)
List device(s) based on device type with full information including s/w instances on the system.
void ni_logan_rsrc_free_device_pool(ni_logan_device_pool_t *p_device_pool)
Free all resources taken by the device pool.
int ni_logan_rsrc_add_device(const char *dev, int should_match_rev)
Add an NetInt h/w device into resource pool on the host.
void ni_logan_rsrc_release_resource(ni_logan_device_context_t *p_device_context, ni_codec_t codec, unsigned long load)
Release resources allocated for decoding/encoding. function This must be called at the end of transco...
void ni_logan_rsrc_free_device_context(ni_logan_device_context_t *p_device_context)
Free previously allocated device context.
ni_logan_device_context_t * ni_logan_rsrc_allocate_direct(ni_logan_device_type_t device_type, int guid, ni_codec_t codec, int width, int height, int frame_rate, unsigned long *p_load)
Allocate resources for decoding/encoding, by designating explicitly the device to use.
ni_logan_device_context_t * ni_logan_rsrc_allocate_auto(ni_logan_device_type_t device_type, ni_alloc_rule_t rule, ni_codec_t codec, int width, int height, int frame_rate, unsigned long *p_load)
Allocate resources for decoding/encoding, based on the provided rule.
int ni_logan_rsrc_codec_is_available(int guid, ni_logan_device_type_t device_type)
check the NetInt h/w device in resource pool on the host.
int ni_logan_rsrc_remove_device(const char *dev)
Remove an NetInt h/w device from resource pool on the host.
ni_logan_device_info_t * ni_logan_rsrc_get_device_info(ni_logan_device_type_t device_type, int guid)
Query a specific device with detailed information on the system.
int ni_logan_check_hw_info(hw_device_info_t *p_hw_device_info, int task_mode, int load_threshold, int task_num_threshold, ni_logan_device_type_t device_type, int resolution)
check hw info, return the appropriate card number to use depends on the load&task_num&used resource
void ni_logan_rsrc_print_device_info(const ni_logan_device_info_t *p_device_info)
Print the content of the ni_logan_device_info_t struct.
ni_logan_device_pool_t * ni_logan_rsrc_get_device_pool(void)
Create and return the allocated ni_logan_device_pool_t struct.
int ni_logan_rsrc_update_device_load(ni_logan_device_context_t *p_device_context, int load, int sw_instance_cnt, const ni_logan_sw_instance_info_t sw_instance_info[])
Update the load value and s/w instances info of a specific decoder or encoder. This is used by resour...
int ni_logan_rsrc_get_available_device(int width, int height, int frame_rate, ni_codec_t codec, ni_logan_device_type_t device_type, ni_logan_device_info_t *p_device_info)
Get the least used device that can handle decoding or encoding a video stream of certain resolution/f...
Exported definitions related to resource management of NI T-408 devices.
ni_sw_instance_status_t
ni_codec_t
@ EN_H264
@ EN_H265
ni_alloc_rule_t
Private definitions related to resource management of NI T-408 devices.
Exported utility routines definition.
ni_logan_device_info_t * p_device_info
char dev_name[NI_LOGAN_MAX_DEVICE_NAME_LEN]
ni_logan_device_queue_t * p_device_queue
int32_t decoders[LOGAN_MAX_DEVICE_CNT]
int32_t encoders[LOGAN_MAX_DEVICE_CNT]
ni_logan_device_info_t encoders[LOGAN_MAX_DEVICE_CNT]
ni_logan_device_info_t decoders[LOGAN_MAX_DEVICE_CNT]
ni_sw_instance_status_t status
void listModuleId(void)
void deleteCoder(void)
int getInt(const char *prompt)
void addCoder(void)
void getLeastUsedCoderForVideo(void)
void change_log_level(void)
void checkHW(void)
int getCmd(const char *prompt)
void checkHWInfo(void)
void getStr(const char *prompt, char *str)
int main(void)
void listAllCodersFull(void)
void updateCoderLoad(void)
void listOneTypeCoders(void)
void releaseEncRsrc(void)
void allocAuto(void)
float getFloat(const char *prompt)
void getCoderDetailInfo(void)
long getLong(const char *prompt)
void allocDirect(void)