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
74void 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*/
113WORD32 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*/
160void* 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*/
206WORD32 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*/
253WORD32 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*/
305WORD32 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*/
349UWORD32 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*/
379void* 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*/
406UWORD32 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