libxcoder  5.2.0
ni_lat_meas.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_lat_meas.c
24  *
25  * \brief Utility definitions for measuring frame/packet processing time in
26  * NETINT video processing devices
27  ******************************************************************************/
28 
29 #ifdef __linux__
30 #include <sys/ioctl.h>
31 #include <sys/stat.h>
32 #include <sys/ioctl.h>
33 #include <sys/mman.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #endif
39 
40 #include "ni_lat_meas.h"
41 #include "ni_log.h"
42 #include "ni_util.h"
43 
44 /*!*****************************************************************************
45  * \brief Create a latency measurement queue object of a given capacity
46  *
47  * \param capacity maximum size of queue
48  *
49  * \return ni_lat_meas_q_t latency measurement queue structure
50  *
51  ******************************************************************************/
53 {
54  if (1 > capacity)
55  {
57  "ERROR: ni_lat_meas_q_create() called with capacity less than 1"
58  "\n");
59  return NULL;
60  }
61 
62  ni_lat_meas_q_t *queue = (ni_lat_meas_q_t *)malloc(sizeof(ni_lat_meas_q_t));
63  if (!queue)
64  {
66  "ERROR %d: Failed to allocate memory for "
67  "lat_meas-queue queue\n",
68  NI_ERRNO);
69  return NULL;
70  }
71  queue->capacity = capacity;
72  queue->front = queue->size = 0;
73  queue->rear = capacity - 1;
75  queue->array = (ni_lat_meas_q_entry_t *)malloc(
76  queue->capacity * sizeof(ni_lat_meas_q_entry_t));
77  if (!queue->array)
78  {
80  "ERROR %d: Failed to allocate memory for "
81  "lat_meas_queue queue->array\n",
82  NI_ERRNO);
83  free(queue);
84  return NULL;
85  }
86  return queue;
87 }
88 
89 /*!*****************************************************************************
90  * \brief Destroy a latency measurement queue object
91  *
92  * \param frame_time_q pointer to ni_lat_meas_q_t object
93  *
94  * \return
95  *
96  ******************************************************************************/
98 {
99  free(frame_time_q->array);
100  free(frame_time_q);
101 }
102 
103 /*!*****************************************************************************
104  * \brief Push an item onto the queue
105  *
106  * \param queue pointer to latency queue
107  * \param item ni_lat_meas_q_entry_t item to push onto the queue
108  *
109  * \return void 1 if success, NULL if failed
110  *
111  ******************************************************************************/
113 {
114  if (queue->size == queue->capacity)
115  {
116  return NULL;
117  }
118  queue->rear = (queue->rear + 1) % queue->capacity;
119  queue->array[queue->rear] = item;
120  queue->size = queue->size + 1;
121  return (void *)1;
122 }
123 
124 /*!*****************************************************************************
125  * \brief Pop an item from the queue
126  *
127  * \param queue pointer to latency queue
128  *
129  * \return void pointer to popped item
130  *
131  ******************************************************************************/
133 {
134  ni_lat_meas_q_entry_t *dequeue_item;
135  if (queue->size == 0)
136  {
137  return NULL;
138  }
139  dequeue_item = &queue->array[queue->front];
140  queue->front = (queue->front + 1) % queue->capacity;
141  queue->size = queue->size - 1;
142  return dequeue_item;
143 }
144 
145 /*!*****************************************************************************
146  * \brief Get a pointer to rear of queue
147  *
148  * \param queue pointer to latency queue
149  *
150  * \return void pointer to rear of queue
151  *
152  ******************************************************************************/
154 {
155  return queue->size == 0 ? NULL : &queue->array[queue->rear];
156 }
157 
158 /*!*****************************************************************************
159  * \brief Get a pointer to front of queue
160  *
161  * \param queue pointer to latency queue
162  *
163  * \return void pointer to front of queue
164  *
165  ******************************************************************************/
167 {
168  return queue->size == 0 ? NULL : &queue->array[queue->front];
169 }
170 
171 /*!*****************************************************************************
172  * \brief Add a new entry to latency queue
173  *
174  * \param frame_time_q pointer to latency queue
175  * \param abs_time frame start time for latency comparison
176  * \param ts_time reference frame timestamp time
177  *
178  * \return void 1 if success, NULL if failed
179  *
180  ******************************************************************************/
181 void *ni_lat_meas_q_add_entry(ni_lat_meas_q_t *frame_time_q, uint64_t abs_time,
182  int64_t ts_time)
183 {
184  // ni_log(NI_LOG_DEBUG, "ni_lat_meas_q_add_entry abs_time=%" PRIu64 " "
185  // "ts_time=%" PRId64 "\n", abs_time, ts_time);
186  ni_lat_meas_q_entry_t entry = {.abs_timenano = abs_time,
187  .ts_time = ts_time};
188  return ni_lat_meas_q_enqueue(frame_time_q, entry);
189 }
190 
191 /*!*****************************************************************************
192  * \brief Check latency of a frame referenced by its timestamp
193  *
194  * \param frame_time_q pointer to latency queue
195  * \param abs_time frame end time for latency comparison
196  * \param ts_time reference frame timestamp time
197  *
198  * \return uint64_t value of latency if suceeded, -1 if failed
199  *
200  ******************************************************************************/
202  uint64_t abs_time, int64_t ts_time)
203 {
204  // ni_log(NI_LOG_DEBUG, "ni_lat_meas_q_check_latency abs_time=%" PRIu64 " "
205  // "ts_time="%" PRId64 "\n", abs_time, ts_time);
206  uint64_t ret = -1;
207  uint32_t dequeue_count = 0;
208  ni_lat_meas_q_entry_t *entry = ni_lat_meas_q_front(frame_time_q);
209 
210  if (entry == NULL)
211  {
212  return -1;
213  }
214 
215  if (entry->ts_time == ts_time)
216  {
217  ni_lat_meas_q_dequeue(frame_time_q);
218  dequeue_count++;
219  } else
220  { // queue miss, perhaps frame was not decoded properly or TS was offset
221  while (entry->ts_time < ts_time)
222  {
223  entry = ni_lat_meas_q_dequeue(frame_time_q);
224  dequeue_count++;
225  if (entry == NULL)
226  {
227  return -1;
228  }
229  }
230  }
231  ni_log(NI_LOG_DEBUG, "DQ_CNT:%u,QD:%d", dequeue_count, frame_time_q->size);
232 
233  if ((entry == NULL) || (entry->ts_time > ts_time))
234  { // queue overrun OR
235  // queue miss, perhaps frame was not enqueued properly or TS was offset
236  ret = -1;
237  } else if (entry->ts_time == ts_time)
238  {
239  ret = abs_time - entry->abs_timenano;
240  }
241 
242  return ret;
243 }
ni_lat_meas.h
Utility definitions for measuring frame/packet processing time in NETINT video processing devices.
_ni_lat_meas_q_t::front
int front
Definition: ni_lat_meas.h:41
ni_lat_meas_q_enqueue
void * ni_lat_meas_q_enqueue(ni_lat_meas_q_t *queue, ni_lat_meas_q_entry_t item)
Push an item onto the queue.
Definition: ni_lat_meas.c:112
_ni_lat_meas_q_entry_t
Definition: ni_lat_meas.h:33
ni_lat_meas_q_front
void * ni_lat_meas_q_front(ni_lat_meas_q_t *queue)
Get a pointer to front of queue.
Definition: ni_lat_meas.c:166
_ni_lat_meas_q_t
Definition: ni_lat_meas.h:39
_ni_lat_meas_q_entry_t::abs_timenano
uint64_t abs_timenano
Definition: ni_lat_meas.h:35
ni_gettime_ns
uint64_t ni_gettime_ns(void)
Definition: ni_util.c:1998
ni_lat_meas_q_rear
void * ni_lat_meas_q_rear(ni_lat_meas_q_t *queue)
Get a pointer to rear of queue.
Definition: ni_lat_meas.c:153
ni_lat_meas_q_add_entry
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.
Definition: ni_lat_meas.c:181
_ni_lat_meas_q_t::last_benchmark_time
uint64_t last_benchmark_time
Definition: ni_lat_meas.h:42
ni_lat_meas_q_check_latency
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.
Definition: ni_lat_meas.c:201
ni_log.h
Logging definitions.
_ni_lat_meas_q_t::capacity
int capacity
Definition: ni_lat_meas.h:41
NI_LOG_ERROR
@ NI_LOG_ERROR
Definition: ni_log.h:60
ni_log
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition: ni_log.c:183
_ni_lat_meas_q_t::rear
int rear
Definition: ni_lat_meas.h:41
NI_ERRNO
#define NI_ERRNO
Definition: ni_defs.h:217
ni_lat_meas_q_create
ni_lat_meas_q_t * ni_lat_meas_q_create(int capacity)
Create a latency measurement queue object of a given capacity.
Definition: ni_lat_meas.c:52
_ni_lat_meas_q_t::size
int size
Definition: ni_lat_meas.h:41
ni_lat_meas_q_destroy
void ni_lat_meas_q_destroy(ni_lat_meas_q_t *frame_time_q)
Destroy a latency measurement queue object.
Definition: ni_lat_meas.c:97
_ni_lat_meas_q_t::array
ni_lat_meas_q_entry_t * array
Definition: ni_lat_meas.h:43
ni_util.h
Utility definitions.
NI_LOG_DEBUG
@ NI_LOG_DEBUG
Definition: ni_log.h:62
_ni_lat_meas_q_entry_t::ts_time
int64_t ts_time
Definition: ni_lat_meas.h:36
ni_lat_meas_q_dequeue
void * ni_lat_meas_q_dequeue(ni_lat_meas_q_t *queue)
Pop an item from the queue.
Definition: ni_lat_meas.c:132