1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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 /**
19 *******************************************************************************
20 * @file
21 *  ihevc_buf_mgr.c
22 *
23 * @brief
24 *  Contains function definitions for buffer management
25 *
26 * @author
27 *  Srinivas T
28 *
29 * @par List of Functions:
30 *   - ihevc_buf_mgr_init()
31 *   - ihevc_buf_mgr_add()
32 *   - ihevc_buf_mgr_get_next_free()
33 *   - ihevc_buf_mgr_check_free()
34 *   - ihevc_buf_mgr_release()
35 *   - ihevc_buf_mgr_set_status()
36 *   - ihevc_buf_mgr_get_status()
37 *   - ihevc_buf_mgr_get_buf()
38 *   - ihevc_buf_mgr_get_num_active_buf()
39 *
40 * @remarks
41 *  None
42 *
43 *******************************************************************************
44 */
45 #include <stdlib.h>
46 #include <assert.h>
47 #include "ihevc_typedefs.h"
48 #include "ihevc_macros.h"
49 #include "ihevc_func_selector.h"
50 #include "ihevc_buf_mgr.h"
51 #include "ihevc_debug.h"
52 
53 
54 /**
55 *******************************************************************************
56 *
57 * @brief
58 *      Buffer manager initialization function.
59 *
60 * @par Description:
61 *    Initializes the buffer manager structure
62 *
63 * @param[in] ps_buf_mgr
64 *  Pointer to the buffer manager
65 *
66 * @returns
67 *
68 * @remarks
69 *  None
70 *
71 *******************************************************************************
72 */
73 
ihevc_buf_mgr_init(buf_mgr_t * ps_buf_mgr)74 void ihevc_buf_mgr_init(
75                 buf_mgr_t *ps_buf_mgr)
76 {
77     WORD32 id;
78 
79     ps_buf_mgr->u4_max_buf_cnt = BUF_MGR_MAX_CNT;
80     ps_buf_mgr->u4_active_buf_cnt = 0;
81 
82     for(id = 0; id < BUF_MGR_MAX_CNT; id++)
83     {
84         ps_buf_mgr->au4_status[id] = 0;
85         ps_buf_mgr->apv_ptr[id] = NULL;
86     }
87 }
88 
89 
90 /**
91 *******************************************************************************
92 *
93 * @brief
94 *       Adds and increments the buffer and buffer count.
95 *
96 * @par Description:
97 *     Adds a buffer to the buffer manager if it is not already  present and
98 *   increments the  active buffer count
99 *
100 * @param[in] ps_buf_mgr
101 *  Pointer to the buffer manager
102 *
103 * @param[in] pv_ptr
104 *  Pointer to the buffer to be added
105 *
106 * @returns  Returns 0 on success, -1 otherwise
107 *
108 * @remarks
109 *  None
110 *
111 *******************************************************************************
112 */
ihevc_buf_mgr_add(buf_mgr_t * ps_buf_mgr,void * pv_ptr,WORD32 buf_id)113 WORD32 ihevc_buf_mgr_add(
114                 buf_mgr_t *ps_buf_mgr,
115                 void *pv_ptr,
116                 WORD32 buf_id)
117 {
118 
119     /* Check if buffer ID is within allowed range */
120     if(buf_id >= (WORD32)ps_buf_mgr->u4_max_buf_cnt)
121     {
122         return (-1);
123     }
124 
125     /* Check if the current ID is being used to hold some other buffer */
126     if((ps_buf_mgr->apv_ptr[buf_id] != NULL) &&
127        (ps_buf_mgr->apv_ptr[buf_id] != pv_ptr))
128     {
129         return (-1);
130     }
131     ps_buf_mgr->apv_ptr[buf_id] = pv_ptr;
132 
133     return 0;
134 }
135 
136 
137 /**
138 *******************************************************************************
139 *
140 * @brief
141 *   Gets the next free buffer.
142 *
143 * @par Description:
144 *     Returns the next free buffer available and sets the  corresponding status
145 *   to DEC
146 *
147 * @param[in] ps_buf_mgr
148 *  Pointer to the buffer manager
149 *
150 * @param[in] pi4_buf_id
151 *  Pointer to the id of the free buffer
152 *
153 * @returns  Pointer to the free buffer
154 *
155 * @remarks
156 *  None
157 *
158 *******************************************************************************
159 */
ihevc_buf_mgr_get_next_free(buf_mgr_t * ps_buf_mgr,WORD32 * pi4_buf_id)160 void* ihevc_buf_mgr_get_next_free(
161                 buf_mgr_t *ps_buf_mgr,
162                 WORD32 *pi4_buf_id)
163 {
164     WORD32 id;
165     void *pv_ret_ptr;
166 
167     pv_ret_ptr = NULL;
168     for(id = 0; id < (WORD32)ps_buf_mgr->u4_max_buf_cnt; id++)
169     {
170         ASSERT(ps_buf_mgr->au4_status[id] != 2);
171 
172         /* Check if the buffer is non-null and status is zero */
173         if((ps_buf_mgr->au4_status[id] == 0) && (ps_buf_mgr->apv_ptr[id]))
174         {
175             *pi4_buf_id = id;
176             /* DEC is set to 1 */
177             ps_buf_mgr->au4_status[id] = 1;
178             pv_ret_ptr = ps_buf_mgr->apv_ptr[id];
179             break;
180         }
181     }
182 
183     return pv_ret_ptr;
184 }
185 
186 
187 /**
188 *******************************************************************************
189 *
190 * @brief
191 *      Checks the buffer manager for free buffers available.
192 *
193 * @par Description:
194 *  Checks if there are any free buffers available
195 *
196 * @param[in] ps_buf_mgr
197 *  Pointer to the buffer manager
198 *
199 * @returns  Returns 0 if available, -1 otherwise
200 *
201 * @remarks
202 *  None
203 *
204 *******************************************************************************
205 */
ihevc_buf_mgr_check_free(buf_mgr_t * ps_buf_mgr)206 WORD32 ihevc_buf_mgr_check_free(
207                 buf_mgr_t *ps_buf_mgr)
208 {
209     UWORD32 id;
210 
211     for(id = 0; id < ps_buf_mgr->u4_max_buf_cnt; id++)
212     {
213         ASSERT(ps_buf_mgr->au4_status[id] != 2);
214 
215         if((ps_buf_mgr->au4_status[id] == 0) &&
216            (ps_buf_mgr->apv_ptr[id]))
217         {
218             return 1;
219         }
220     }
221 
222     return 0;
223 
224 }
225 
226 
227 /**
228 *******************************************************************************
229 *
230 * @brief
231 *       Resets the status bits.
232 *
233 * @par Description:
234 *     resets the status bits that the mask contains (status  corresponding to
235 *    the id)
236 *
237 * @param[in] ps_buf_mgr
238 *  Pointer to the buffer manager
239 *
240 * @param[in] buf_id
241 *  ID of the buffer status to be released
242 *
243 * @param[in] mask
244 *  Contains the bits that are to be reset
245 *
246 * @returns  0 if success, -1 otherwise
247 *
248 * @remarks
249 *  None
250 *
251 *******************************************************************************
252 */
ihevc_buf_mgr_release(buf_mgr_t * ps_buf_mgr,WORD32 buf_id,UWORD32 mask)253 WORD32 ihevc_buf_mgr_release(
254                 buf_mgr_t *ps_buf_mgr,
255                 WORD32 buf_id,
256                 UWORD32 mask)
257 {
258     /* If the given id is pointing to an id which is not yet added */
259     if(buf_id >= (WORD32)ps_buf_mgr->u4_max_buf_cnt)
260     {
261         return (-1);
262     }
263 
264     ps_buf_mgr->au4_status[buf_id] &= ~mask;
265     ASSERT(ps_buf_mgr->au4_status[buf_id] != 2);
266 
267     /* If both the REF and DISP are zero, DEC is set to zero */
268     if(ps_buf_mgr->au4_status[buf_id] == 1)
269     {
270         ps_buf_mgr->au4_status[buf_id] = 0;
271     }
272 
273     return 0;
274 }
275 
276 
277 /**
278 *******************************************************************************
279 *
280 * @brief
281 *      Sets the status bit.
282 *
283 * @par Description:
284 *     sets the status bits that the mask contains (status  corresponding to the
285 *    id)
286 *
287 *
288 * @param[in] ps_buf_mgr
289 *  Pointer to the buffer manager
290 *
291 * @param[in] buf_id
292 *  ID of the buffer whose status needs to be modified
293 *
294 *
295 * @param[in] mask
296 *  Contains the bits that are to be set
297 *
298 * @returns  0 if success, -1 otherwise
299 *
300 * @remarks
301 *  None
302 *
303 *******************************************************************************
304 */
ihevc_buf_mgr_set_status(buf_mgr_t * ps_buf_mgr,WORD32 buf_id,UWORD32 mask)305 WORD32 ihevc_buf_mgr_set_status(
306                 buf_mgr_t *ps_buf_mgr,
307                 WORD32 buf_id,
308                 UWORD32 mask)
309 {
310     if(buf_id >= (WORD32)ps_buf_mgr->u4_max_buf_cnt)
311     {
312         return (-1);
313     }
314 
315 
316     if((ps_buf_mgr->au4_status[buf_id] & mask) != 0)
317     {
318         return (-1);
319     }
320 
321     ps_buf_mgr->au4_status[buf_id] |= mask;
322     ASSERT(ps_buf_mgr->au4_status[buf_id] != 2);
323     return 0;
324 }
325 
326 
327 /**
328 *******************************************************************************
329 *
330 * @brief
331 *   Returns the status of the buffer.
332 *
333 * @par Description:
334 *  Returns the status of the buffer corresponding to the id
335 *
336 * @param[in] ps_buf_mgr
337 *  Pointer to the buffer manager
338 *
339 * @param[in] buf_id
340 *  ID of the buffer status required
341 *
342 * @returns  Status of the buffer corresponding to the id
343 *
344 * @remarks
345 *  None
346 *
347 *******************************************************************************
348 */
ihevc_buf_mgr_get_status(buf_mgr_t * ps_buf_mgr,WORD32 buf_id)349 UWORD32 ihevc_buf_mgr_get_status(
350                 buf_mgr_t *ps_buf_mgr,
351                 WORD32 buf_id)
352 {
353     return ps_buf_mgr->au4_status[buf_id];
354 }
355 
356 
357 /**
358 *******************************************************************************
359 *
360 * @brief
361 *      Gets the buffer from the buffer manager
362 *
363 * @par Description:
364 *        Returns the pointer to the buffer corresponding to the id
365 *
366 * @param[in] ps_buf_mgr
367 *  Pointer to the buffer manager
368 *
369 * @param[in] buf_id
370 *  ID of the buffer required
371 *
372 * @returns  Pointer to the buffer required
373 *
374 * @remarks
375 *  None
376 *
377 *******************************************************************************
378 */
ihevc_buf_mgr_get_buf(buf_mgr_t * ps_buf_mgr,WORD32 buf_id)379 void* ihevc_buf_mgr_get_buf(
380                 buf_mgr_t *ps_buf_mgr,
381                 WORD32 buf_id)
382 {
383     return ps_buf_mgr->apv_ptr[buf_id];
384 }
385 
386 
387 /**
388 *******************************************************************************
389 *
390 * @brief
391 *        Gets the no.of active buffer
392 *
393 * @par Description:
394 *      Return the number of active buffers in the buffer manager
395 *
396 * @param[in] ps_buf_mgr
397 *  Pointer to the buffer manager
398 *
399 * @returns  number of active buffers
400 *
401 * @remarks
402 *  None
403 *
404 *******************************************************************************
405 */
ihevc_buf_mgr_get_num_active_buf(buf_mgr_t * ps_buf_mgr)406 UWORD32 ihevc_buf_mgr_get_num_active_buf(
407                 buf_mgr_t *ps_buf_mgr)
408 {
409     return ps_buf_mgr->u4_max_buf_cnt;
410 }
411