• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
ihevce_buff_que_get_num_mem_recs(void)74 WORD32 ihevce_buff_que_get_num_mem_recs(void)
75 {
76     return (NUM_BUFFER_QUE_MEM_RECS);
77 }
78 
79 /*!
80 ************************************************************************
81 * \brief
82 *    return each record attributes of Buffer Que manager
83 ************************************************************************
84 */
ihevce_buff_que_get_mem_recs(iv_mem_rec_t * ps_mem_tab,WORD32 max_num_bufs_in_que,WORD32 i4_mem_space)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 {
88     /* Que manager state structure */
89     ps_mem_tab[BUFFER_QUE_CTXT].i4_mem_size = sizeof(buf_que_t);
90     ps_mem_tab[BUFFER_QUE_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
91     ps_mem_tab[BUFFER_QUE_CTXT].i4_mem_alignment = 8;
92 
93     /* number of users memory */
94     ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].i4_mem_size = (sizeof(WORD32) * max_num_bufs_in_que);
95     ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
96     ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].i4_mem_alignment = 8;
97 
98     /* Produced status memory */
99     ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].i4_mem_size = (sizeof(WORD32) * max_num_bufs_in_que);
100     ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
101     ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].i4_mem_alignment = 8;
102 
103     /* Encode sequence memory */
104     ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].i4_mem_size = (sizeof(UWORD32) * max_num_bufs_in_que);
105     ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
106     ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].i4_mem_alignment = 8;
107 
108     /* Queued sequence memory */
109     ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].i4_mem_size = (sizeof(UWORD32) * max_num_bufs_in_que);
110     ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
111     ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].i4_mem_alignment = 8;
112 
113     return (NUM_BUFFER_QUE_MEM_RECS);
114 }
115 
116 /*!
117 ************************************************************************
118 * \brief
119 *    Intialization for Buffer Que manager state structure
120 ************************************************************************
121 */
ihevce_buff_que_init(iv_mem_rec_t * ps_mem_tab,WORD32 num_bufs_in_que,void ** ppv_buff_ptrs)122 void *ihevce_buff_que_init(iv_mem_rec_t *ps_mem_tab, WORD32 num_bufs_in_que, void **ppv_buff_ptrs)
123 {
124     buf_que_t *ps_buf_que;
125     WORD32 i;
126 
127     /* que manager state structure */
128     ps_buf_que = (buf_que_t *)ps_mem_tab[BUFFER_QUE_CTXT].pv_base;
129 
130     /* buffer status memory init */
131     ps_buf_que->pi4_num_users = (WORD32 *)ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].pv_base;
132 
133     ps_buf_que->pi4_produced_sts = (WORD32 *)ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].pv_base;
134 
135     ps_buf_que->pu4_enc_seq = (UWORD32 *)ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].pv_base;
136 
137     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     ps_buf_que->i4_num_bufs = num_bufs_in_que;
141     ps_buf_que->i4_num_active_bufs = 0;
142     ps_buf_que->u4_last_prod = 0;
143     ps_buf_que->u4_last_cons = 0;
144     ps_buf_que->u4_next_disp_seq = 0;
145     ps_buf_que->u4_last_disp_seq = 0;
146     ps_buf_que->ppv_buff_ptrs = ppv_buff_ptrs;
147 
148     /* init all the buffer status to default values */
149     for(i = 0; i < ps_buf_que->i4_num_bufs; i++)
150     {
151         ps_buf_que->pi4_num_users[i] = 0;
152         ps_buf_que->pi4_produced_sts[i] = 0;
153         ps_buf_que->pu4_enc_seq[i] = UINT32_MAX;
154         ps_buf_que->pu4_que_seq[i] = UINT32_MAX;
155     }
156 
157     return ((void *)ps_buf_que);
158 }
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 */
ihevce_buff_que_get_free_buf(void * pv_buf_que,WORD32 * pi4_id)167 void *ihevce_buff_que_get_free_buf(void *pv_buf_que, WORD32 *pi4_id)
168 {
169     buf_que_t *ps_buf_que;
170     WORD32 i;
171     WORD32 num_bufs;
172 
173     ps_buf_que = (buf_que_t *)pv_buf_que;
174     num_bufs = ps_buf_que->i4_num_bufs;
175 
176     /* loop unitl a free buffer is found */
177     for(i = 0; i < num_bufs; i++)
178     {
179         if((ps_buf_que->pi4_num_users[i] == 0) && (ps_buf_que->pi4_produced_sts[i] == 0))
180         {
181             *(pi4_id) = i;
182             ps_buf_que->pi4_num_users[i] = 1;
183             ps_buf_que->pu4_que_seq[i] = ps_buf_que->u4_last_prod;
184             ps_buf_que->u4_last_prod += 1;
185 
186             return (ps_buf_que->ppv_buff_ptrs[i]);
187         }
188     }
189     return (NULL);
190 }
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 */
ihevce_buff_que_get_next_buf(void * pv_buf_que,WORD32 * pi4_id)199 void *ihevce_buff_que_get_next_buf(void *pv_buf_que, WORD32 *pi4_id)
200 {
201     buf_que_t *ps_buf_que;
202     WORD32 i;
203     UWORD32 next_qued_seq;
204 
205     ps_buf_que = (buf_que_t *)pv_buf_que;
206 
207     /* get the next queued buffer to be sent */
208     next_qued_seq = ps_buf_que->u4_last_cons;
209 
210     /* check for matching index */
211     for(i = 0; i < ps_buf_que->i4_num_bufs; i++)
212     {
213         if(next_qued_seq == ps_buf_que->pu4_que_seq[i])
214         {
215             if(1 == ps_buf_que->pi4_produced_sts[i])
216             {
217                 *(pi4_id) = i;
218                 ps_buf_que->u4_last_cons += 1;
219 
220                 return (ps_buf_que->ppv_buff_ptrs[i]);
221             }
222             else
223             {
224                 break;
225             }
226         }
227     }
228 
229     /* Buffer not ready for Consumption */
230     return (NULL);
231 }
232 
233 /*!
234 **************************************************************************
235 * \brief
236 *    This function gives the buffer curresponding to the id passed
237 **************************************************************************
238 */
ihevce_buff_que_get_buf(void * pv_buf_que,WORD32 i4_id)239 void *ihevce_buff_que_get_buf(void *pv_buf_que, WORD32 i4_id)
240 {
241     buf_que_t *ps_buf_que;
242 
243     ps_buf_que = (buf_que_t *)pv_buf_que;
244 
245     if(i4_id >= ps_buf_que->i4_num_bufs)
246         return (NULL);
247 
248     return (ps_buf_que->ppv_buff_ptrs[i4_id]);
249 }
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 */
ihevce_buff_que_get_next_reorder_buf(void * pv_buf_que,WORD32 * pi4_id)258 void *ihevce_buff_que_get_next_reorder_buf(void *pv_buf_que, WORD32 *pi4_id)
259 {
260     buf_que_t *ps_buf_que;
261     WORD32 i;
262     UWORD32 next_disp_seq;
263 
264     ps_buf_que = (buf_que_t *)pv_buf_que;
265 
266     /* get the next reordered buffer to be sent */
267     next_disp_seq = ps_buf_que->u4_last_disp_seq;
268 
269     /* check for matching index */
270     for(i = 0; i < ps_buf_que->i4_num_bufs; i++)
271     {
272         if(next_disp_seq == ps_buf_que->pu4_enc_seq[i])
273         {
274             *(pi4_id) = i;
275             ps_buf_que->u4_last_disp_seq += 1;
276 
277             return (ps_buf_que->ppv_buff_ptrs[i]);
278         }
279     }
280 
281     /* Buffer not ready for Consumption */
282     return (NULL);
283 }
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 */
ihevce_buff_que_set_buf_prod(void * pv_buf_que,WORD32 buf_id,WORD32 num_users)292 WORD32 ihevce_buff_que_set_buf_prod(void *pv_buf_que, WORD32 buf_id, WORD32 num_users)
293 {
294     buf_que_t *ps_buf_que;
295 
296     ps_buf_que = (buf_que_t *)pv_buf_que;
297 
298     if(buf_id < ps_buf_que->i4_num_bufs)
299     {
300         if(ps_buf_que->pi4_produced_sts[buf_id] == 0)
301         {
302             ps_buf_que->pi4_num_users[buf_id] += num_users;
303             ps_buf_que->i4_num_active_bufs += 1;
304             ps_buf_que->pi4_produced_sts[buf_id] = 1;
305 
306             return 0;
307         }
308         else
309         {
310             /* Buffer is already marked as Produced */
311             return (-1);
312         }
313     }
314     else
315     {
316         /* Unable to recognize the Buffer ID */
317         return (-1);
318     }
319 
320     return (-1);
321 }
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 */
ihevce_buff_que_rel_buf(void * pv_buf_que,WORD32 buf_id)331 WORD32 ihevce_buff_que_rel_buf(void *pv_buf_que, WORD32 buf_id)
332 {
333     buf_que_t *ps_buf_que;
334     WORD32 i;
335 
336     ps_buf_que = (buf_que_t *)pv_buf_que;
337     i = buf_id;
338 
339     /* check if the buf id is less than max num buffers */
340     if(i < ps_buf_que->i4_num_bufs)
341     {
342         if(ps_buf_que->pi4_produced_sts[i] > 0)
343         {
344             /* decrease the number of users */
345             ps_buf_que->pi4_num_users[i] -= 1;
346 
347             if(ps_buf_que->pi4_num_users[i] == 0)
348             {
349                 if(0 == ps_buf_que->i4_num_active_bufs)
350                 {
351                     return (-1);
352                 }
353 
354                 ps_buf_que->i4_num_active_bufs -= 1;
355                 ps_buf_que->pi4_produced_sts[i] = 0;
356             }
357             return 0;
358         }
359         else
360         {
361             /* Illeagal release of Buffer, No one is using it */
362             return (-1);
363         }
364     }
365 
366     /* Unable to recognize the Buffer ID */
367     return (-1);
368 }
369 
370 /*!
371 **************************************************************************
372 * \brief
373 *    This function gets number of active buffers.
374 **************************************************************************
375 */
ihevce_buff_que_get_active_bufs(void * pv_buf_que)376 WORD32 ihevce_buff_que_get_active_bufs(void *pv_buf_que)
377 {
378     buf_que_t *ps_buf_que;
379 
380     ps_buf_que = (buf_que_t *)pv_buf_que;
381     return (ps_buf_que->i4_num_active_bufs);
382 }
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 */
ihevce_buff_que_set_reorder_buf(void * pv_buf_que,WORD32 buf_id)391 WORD32 ihevce_buff_que_set_reorder_buf(void *pv_buf_que, WORD32 buf_id)
392 {
393     buf_que_t *ps_buf_que;
394 
395     ps_buf_que = (buf_que_t *)pv_buf_que;
396 
397     if(buf_id < ps_buf_que->i4_num_bufs)
398     {
399         WORD32 next_disp_seq = ps_buf_que->u4_next_disp_seq;
400 
401         /* increment the seq number */
402         ps_buf_que->u4_next_disp_seq++;
403 
404         /* set the reorder number to the corresponding id */
405         ps_buf_que->pu4_enc_seq[buf_id] = next_disp_seq;
406 
407         return 0;
408     }
409     else
410     {
411         /* invalid buffer id */
412         return (-1);
413     }
414 
415     return (-1);
416 }
417