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