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
76void 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*/
115WORD32 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*/
162void* 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*/
206WORD32 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*/
251WORD32 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*/
307WORD32 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*/
350UWORD32 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*/
380void* 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*/
407UWORD32 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