/src/libhevc/encoder/ihevce_buffer_que.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2018 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | |
21 | | /** |
22 | | ****************************************************************************** |
23 | | * @file |
24 | | * ihevce_buffer_que.c |
25 | | * |
26 | | * @brief |
27 | | * This file contains all the functions related to Buffer Queue manager |
28 | | * |
29 | | * @author |
30 | | * ittiam |
31 | | * |
32 | | * @par List of Functions: |
33 | | * ihevce_buff_que_get_mem_recs |
34 | | * ihevce_buff_que_get_num_mem_recs |
35 | | * ihevce_buff_que_init |
36 | | * ihevce_buff_que_get_free_buf |
37 | | * ihevce_buff_que_get_next_buf |
38 | | * ihevce_buff_que_get_next_reorder_buf |
39 | | * ihevce_buff_que_set_buf_prod |
40 | | * ihevce_buff_que_rel_buf |
41 | | * ihevce_buff_que_get_active_bufs |
42 | | * ihevce_buff_que_set_reorder_buf |
43 | | * |
44 | | ****************************************************************************** |
45 | | */ |
46 | | |
47 | | /*****************************************************************************/ |
48 | | /* File Includes */ |
49 | | /*****************************************************************************/ |
50 | | |
51 | | /* System Include Files */ |
52 | | #include <stdio.h> |
53 | | #include <string.h> |
54 | | #include <stdlib.h> |
55 | | #include <stdint.h> |
56 | | #include <assert.h> |
57 | | |
58 | | /* User Include Files */ |
59 | | #include "ihevc_typedefs.h" |
60 | | #include "itt_video_api.h" |
61 | | #include "ihevce_buffer_que_interface.h" |
62 | | #include "ihevce_buffer_que_private.h" |
63 | | |
64 | | /*****************************************************************************/ |
65 | | /* Function Definitions */ |
66 | | /*****************************************************************************/ |
67 | | |
68 | | /*! |
69 | | ************************************************************************ |
70 | | * \brief |
71 | | * return number of records used by Buffer Que manager. |
72 | | ************************************************************************ |
73 | | */ |
74 | | WORD32 ihevce_buff_que_get_num_mem_recs(void) |
75 | 142k | { |
76 | 142k | return (NUM_BUFFER_QUE_MEM_RECS); |
77 | 142k | } |
78 | | |
79 | | /*! |
80 | | ************************************************************************ |
81 | | * \brief |
82 | | * return each record attributes of Buffer Que manager |
83 | | ************************************************************************ |
84 | | */ |
85 | | WORD32 ihevce_buff_que_get_mem_recs( |
86 | | iv_mem_rec_t *ps_mem_tab, WORD32 max_num_bufs_in_que, WORD32 i4_mem_space) |
87 | 71.3k | { |
88 | | /* Que manager state structure */ |
89 | 71.3k | ps_mem_tab[BUFFER_QUE_CTXT].i4_mem_size = sizeof(buf_que_t); |
90 | 71.3k | ps_mem_tab[BUFFER_QUE_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space; |
91 | 71.3k | ps_mem_tab[BUFFER_QUE_CTXT].i4_mem_alignment = 8; |
92 | | |
93 | | /* number of users memory */ |
94 | 71.3k | ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].i4_mem_size = (sizeof(WORD32) * max_num_bufs_in_que); |
95 | 71.3k | ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space; |
96 | 71.3k | ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].i4_mem_alignment = 8; |
97 | | |
98 | | /* Produced status memory */ |
99 | 71.3k | ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].i4_mem_size = (sizeof(WORD32) * max_num_bufs_in_que); |
100 | 71.3k | ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space; |
101 | 71.3k | ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].i4_mem_alignment = 8; |
102 | | |
103 | | /* Encode sequence memory */ |
104 | 71.3k | ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].i4_mem_size = (sizeof(UWORD32) * max_num_bufs_in_que); |
105 | 71.3k | ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space; |
106 | 71.3k | ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].i4_mem_alignment = 8; |
107 | | |
108 | | /* Queued sequence memory */ |
109 | 71.3k | ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].i4_mem_size = (sizeof(UWORD32) * max_num_bufs_in_que); |
110 | 71.3k | ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space; |
111 | 71.3k | ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].i4_mem_alignment = 8; |
112 | | |
113 | 71.3k | return (NUM_BUFFER_QUE_MEM_RECS); |
114 | 71.3k | } |
115 | | |
116 | | /*! |
117 | | ************************************************************************ |
118 | | * \brief |
119 | | * Intialization for Buffer Que manager state structure |
120 | | ************************************************************************ |
121 | | */ |
122 | | void *ihevce_buff_que_init(iv_mem_rec_t *ps_mem_tab, WORD32 num_bufs_in_que, void **ppv_buff_ptrs) |
123 | 71.3k | { |
124 | 71.3k | buf_que_t *ps_buf_que; |
125 | 71.3k | WORD32 i; |
126 | | |
127 | | /* que manager state structure */ |
128 | 71.3k | ps_buf_que = (buf_que_t *)ps_mem_tab[BUFFER_QUE_CTXT].pv_base; |
129 | | |
130 | | /* buffer status memory init */ |
131 | 71.3k | ps_buf_que->pi4_num_users = (WORD32 *)ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].pv_base; |
132 | | |
133 | 71.3k | ps_buf_que->pi4_produced_sts = (WORD32 *)ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].pv_base; |
134 | | |
135 | 71.3k | ps_buf_que->pu4_enc_seq = (UWORD32 *)ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].pv_base; |
136 | | |
137 | 71.3k | ps_buf_que->pu4_que_seq = (UWORD32 *)ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].pv_base; |
138 | | |
139 | | /* reset the state structure variables */ |
140 | 71.3k | ps_buf_que->i4_num_bufs = num_bufs_in_que; |
141 | 71.3k | ps_buf_que->i4_num_active_bufs = 0; |
142 | 71.3k | ps_buf_que->u4_last_prod = 0; |
143 | 71.3k | ps_buf_que->u4_last_cons = 0; |
144 | 71.3k | ps_buf_que->u4_next_disp_seq = 0; |
145 | 71.3k | ps_buf_que->u4_last_disp_seq = 0; |
146 | 71.3k | ps_buf_que->ppv_buff_ptrs = ppv_buff_ptrs; |
147 | | |
148 | | /* init all the buffer status to default values */ |
149 | 237k | for(i = 0; i < ps_buf_que->i4_num_bufs; i++) |
150 | 166k | { |
151 | 166k | ps_buf_que->pi4_num_users[i] = 0; |
152 | 166k | ps_buf_que->pi4_produced_sts[i] = 0; |
153 | 166k | ps_buf_que->pu4_enc_seq[i] = UINT32_MAX; |
154 | 166k | ps_buf_que->pu4_que_seq[i] = UINT32_MAX; |
155 | 166k | } |
156 | | |
157 | 71.3k | return ((void *)ps_buf_que); |
158 | 71.3k | } |
159 | | |
160 | | /*! |
161 | | ************************************************************************** |
162 | | * \brief |
163 | | * This function gets the next free buffer. This function is called by the |
164 | | * Producer to get a free buffer |
165 | | ************************************************************************** |
166 | | */ |
167 | | void *ihevce_buff_que_get_free_buf(void *pv_buf_que, WORD32 *pi4_id) |
168 | 1.23M | { |
169 | 1.23M | buf_que_t *ps_buf_que; |
170 | 1.23M | WORD32 i; |
171 | 1.23M | WORD32 num_bufs; |
172 | | |
173 | 1.23M | ps_buf_que = (buf_que_t *)pv_buf_que; |
174 | 1.23M | num_bufs = ps_buf_que->i4_num_bufs; |
175 | | |
176 | | /* loop unitl a free buffer is found */ |
177 | 1.47M | for(i = 0; i < num_bufs; i++) |
178 | 1.37M | { |
179 | 1.37M | if((ps_buf_que->pi4_num_users[i] == 0) && (ps_buf_que->pi4_produced_sts[i] == 0)) |
180 | 1.13M | { |
181 | 1.13M | *(pi4_id) = i; |
182 | 1.13M | ps_buf_que->pi4_num_users[i] = 1; |
183 | 1.13M | ps_buf_que->pu4_que_seq[i] = ps_buf_que->u4_last_prod; |
184 | 1.13M | ps_buf_que->u4_last_prod += 1; |
185 | | |
186 | 1.13M | return (ps_buf_que->ppv_buff_ptrs[i]); |
187 | 1.13M | } |
188 | 1.37M | } |
189 | 96.3k | return (NULL); |
190 | 1.23M | } |
191 | | |
192 | | /*! |
193 | | ************************************************************************** |
194 | | * \brief |
195 | | * This function gets the next buffer in Que . This function will be called by |
196 | | * consumer to get the next buffer in Queued order. |
197 | | ************************************************************************** |
198 | | */ |
199 | | void *ihevce_buff_que_get_next_buf(void *pv_buf_que, WORD32 *pi4_id) |
200 | 2.81M | { |
201 | 2.81M | buf_que_t *ps_buf_que; |
202 | 2.81M | WORD32 i; |
203 | 2.81M | UWORD32 next_qued_seq; |
204 | | |
205 | 2.81M | ps_buf_que = (buf_que_t *)pv_buf_que; |
206 | | |
207 | | /* get the next queued buffer to be sent */ |
208 | 2.81M | next_qued_seq = ps_buf_que->u4_last_cons; |
209 | | |
210 | | /* check for matching index */ |
211 | 6.43M | for(i = 0; i < ps_buf_que->i4_num_bufs; i++) |
212 | 4.77M | { |
213 | 4.77M | if(next_qued_seq == ps_buf_que->pu4_que_seq[i]) |
214 | 1.16M | { |
215 | 1.16M | if(1 == ps_buf_que->pi4_produced_sts[i]) |
216 | 1.13M | { |
217 | 1.13M | *(pi4_id) = i; |
218 | 1.13M | ps_buf_que->u4_last_cons += 1; |
219 | | |
220 | 1.13M | return (ps_buf_que->ppv_buff_ptrs[i]); |
221 | 1.13M | } |
222 | 27.5k | else |
223 | 27.5k | { |
224 | 27.5k | break; |
225 | 27.5k | } |
226 | 1.16M | } |
227 | 4.77M | } |
228 | | |
229 | | /* Buffer not ready for Consumption */ |
230 | 1.68M | return (NULL); |
231 | 2.81M | } |
232 | | |
233 | | /*! |
234 | | ************************************************************************** |
235 | | * \brief |
236 | | * This function gives the buffer curresponding to the id passed |
237 | | ************************************************************************** |
238 | | */ |
239 | | void *ihevce_buff_que_get_buf(void *pv_buf_que, WORD32 i4_id) |
240 | 0 | { |
241 | 0 | buf_que_t *ps_buf_que; |
242 | |
|
243 | 0 | ps_buf_que = (buf_que_t *)pv_buf_que; |
244 | |
|
245 | 0 | if(i4_id >= ps_buf_que->i4_num_bufs) |
246 | 0 | return (NULL); |
247 | | |
248 | 0 | return (ps_buf_que->ppv_buff_ptrs[i4_id]); |
249 | 0 | } |
250 | | |
251 | | /*! |
252 | | ************************************************************************** |
253 | | * \brief |
254 | | * This function gets the next buffer for in reordered order. This function |
255 | | * will be called by consumer to get the next buffer in reordered order |
256 | | ************************************************************************** |
257 | | */ |
258 | | void *ihevce_buff_que_get_next_reorder_buf(void *pv_buf_que, WORD32 *pi4_id) |
259 | 0 | { |
260 | 0 | buf_que_t *ps_buf_que; |
261 | 0 | WORD32 i; |
262 | 0 | UWORD32 next_disp_seq; |
263 | |
|
264 | 0 | ps_buf_que = (buf_que_t *)pv_buf_que; |
265 | | |
266 | | /* get the next reordered buffer to be sent */ |
267 | 0 | next_disp_seq = ps_buf_que->u4_last_disp_seq; |
268 | | |
269 | | /* check for matching index */ |
270 | 0 | for(i = 0; i < ps_buf_que->i4_num_bufs; i++) |
271 | 0 | { |
272 | 0 | if(next_disp_seq == ps_buf_que->pu4_enc_seq[i]) |
273 | 0 | { |
274 | 0 | *(pi4_id) = i; |
275 | 0 | ps_buf_que->u4_last_disp_seq += 1; |
276 | |
|
277 | 0 | return (ps_buf_que->ppv_buff_ptrs[i]); |
278 | 0 | } |
279 | 0 | } |
280 | | |
281 | | /* Buffer not ready for Consumption */ |
282 | 0 | return (NULL); |
283 | 0 | } |
284 | | |
285 | | /*! |
286 | | ************************************************************************** |
287 | | * \brief |
288 | | * This function sets the buffer as produced. This function will be called |
289 | | * by Producer to say that buffer is ready for consumption. |
290 | | ************************************************************************** |
291 | | */ |
292 | | WORD32 ihevce_buff_que_set_buf_prod(void *pv_buf_que, WORD32 buf_id, WORD32 num_users) |
293 | 1.13M | { |
294 | 1.13M | buf_que_t *ps_buf_que; |
295 | | |
296 | 1.13M | ps_buf_que = (buf_que_t *)pv_buf_que; |
297 | | |
298 | 1.13M | if(buf_id < ps_buf_que->i4_num_bufs) |
299 | 1.13M | { |
300 | 1.13M | if(ps_buf_que->pi4_produced_sts[buf_id] == 0) |
301 | 1.13M | { |
302 | 1.13M | ps_buf_que->pi4_num_users[buf_id] += num_users; |
303 | 1.13M | ps_buf_que->i4_num_active_bufs += 1; |
304 | 1.13M | ps_buf_que->pi4_produced_sts[buf_id] = 1; |
305 | | |
306 | 1.13M | return 0; |
307 | 1.13M | } |
308 | 0 | else |
309 | 0 | { |
310 | | /* Buffer is already marked as Produced */ |
311 | 0 | return (-1); |
312 | 0 | } |
313 | 1.13M | } |
314 | 0 | else |
315 | 0 | { |
316 | | /* Unable to recognize the Buffer ID */ |
317 | 0 | return (-1); |
318 | 0 | } |
319 | | |
320 | 0 | return (-1); |
321 | 1.13M | } |
322 | | |
323 | | /*! |
324 | | ************************************************************************** |
325 | | * \brief |
326 | | * This function decrements number of users. If Number of users are Zero, |
327 | | * then active Buffers in list gets decremented and this buffer is marked |
328 | | * unused. |
329 | | ************************************************************************** |
330 | | */ |
331 | | WORD32 ihevce_buff_que_rel_buf(void *pv_buf_que, WORD32 buf_id) |
332 | 1.14M | { |
333 | 1.14M | buf_que_t *ps_buf_que; |
334 | 1.14M | WORD32 i; |
335 | | |
336 | 1.14M | ps_buf_que = (buf_que_t *)pv_buf_que; |
337 | 1.14M | i = buf_id; |
338 | | |
339 | | /* check if the buf id is less than max num buffers */ |
340 | 1.14M | if(i < ps_buf_que->i4_num_bufs) |
341 | 1.14M | { |
342 | 1.14M | if(ps_buf_que->pi4_produced_sts[i] > 0) |
343 | 1.13M | { |
344 | | /* decrease the number of users */ |
345 | 1.13M | ps_buf_que->pi4_num_users[i] -= 1; |
346 | | |
347 | 1.13M | if(ps_buf_que->pi4_num_users[i] == 0) |
348 | 1.13M | { |
349 | 1.13M | if(0 == ps_buf_que->i4_num_active_bufs) |
350 | 0 | { |
351 | 0 | return (-1); |
352 | 0 | } |
353 | | |
354 | 1.13M | ps_buf_que->i4_num_active_bufs -= 1; |
355 | 1.13M | ps_buf_que->pi4_produced_sts[i] = 0; |
356 | 1.13M | } |
357 | 1.13M | return 0; |
358 | 1.13M | } |
359 | 8.92k | else |
360 | 8.92k | { |
361 | | /* Illeagal release of Buffer, No one is using it */ |
362 | 8.92k | return (-1); |
363 | 8.92k | } |
364 | 1.14M | } |
365 | | |
366 | | /* Unable to recognize the Buffer ID */ |
367 | 0 | return (-1); |
368 | 1.14M | } |
369 | | |
370 | | /*! |
371 | | ************************************************************************** |
372 | | * \brief |
373 | | * This function gets number of active buffers. |
374 | | ************************************************************************** |
375 | | */ |
376 | | WORD32 ihevce_buff_que_get_active_bufs(void *pv_buf_que) |
377 | 0 | { |
378 | 0 | buf_que_t *ps_buf_que; |
379 | |
|
380 | 0 | ps_buf_que = (buf_que_t *)pv_buf_que; |
381 | 0 | return (ps_buf_que->i4_num_active_bufs); |
382 | 0 | } |
383 | | |
384 | | /*! |
385 | | ************************************************************************** |
386 | | * \brief |
387 | | * This function sets the reorder number for given buffer. |
388 | | * this will set the order for the consumer who is consuming in reorder order |
389 | | ************************************************************************** |
390 | | */ |
391 | | WORD32 ihevce_buff_que_set_reorder_buf(void *pv_buf_que, WORD32 buf_id) |
392 | 0 | { |
393 | 0 | buf_que_t *ps_buf_que; |
394 | |
|
395 | 0 | ps_buf_que = (buf_que_t *)pv_buf_que; |
396 | |
|
397 | 0 | if(buf_id < ps_buf_que->i4_num_bufs) |
398 | 0 | { |
399 | 0 | WORD32 next_disp_seq = ps_buf_que->u4_next_disp_seq; |
400 | | |
401 | | /* increment the seq number */ |
402 | 0 | ps_buf_que->u4_next_disp_seq++; |
403 | | |
404 | | /* set the reorder number to the corresponding id */ |
405 | 0 | ps_buf_que->pu4_enc_seq[buf_id] = next_disp_seq; |
406 | |
|
407 | 0 | return 0; |
408 | 0 | } |
409 | 0 | else |
410 | 0 | { |
411 | | /* invalid buffer id */ |
412 | 0 | return (-1); |
413 | 0 | } |
414 | | |
415 | 0 | return (-1); |
416 | 0 | } |