Home | History | Annotate | Download | only in common
      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 * @file
     23 *  ih264_buf_mgr.c
     24 *
     25 * @brief
     26 *  Contains function definitions for buffer management
     27 *
     28 * @author
     29 *  Srinivas T
     30 *
     31 * @par List of Functions:
     32 *   - ih264_buf_mgr_size()
     33 *   - ih264_buf_mgr_lock()
     34 *   - ih264_buf_mgr_unlock()
     35 *   - ih264_buf_mgr_yield()
     36 *   - ih264_buf_mgr_free()
     37 *   - ih264_buf_mgr_init()
     38 *   - ih264_buf_mgr_add()
     39 *   - ih264_buf_mgr_get_next_free()
     40 *   - ih264_buf_mgr_check_free()
     41 *   - ih264_buf_mgr_set_status()
     42 *   - ih264_buf_mgr_get_status()
     43 *   - ih264_buf_mgr_get_buf()
     44 *   - ih264_buf_mgr_get_bufid()
     45 *   - ih264_buf_mgr_get_num_active_buf()
     46 *
     47 * @remarks
     48 *  None
     49 *
     50 *******************************************************************************
     51 */
     52 #include <stdio.h>
     53 #include <stdlib.h>
     54 #include "ih264_typedefs.h"
     55 #include "ih264_macros.h"
     56 #include "ih264_defs.h"
     57 #include "ih264_error.h"
     58 #include "ih264_buf_mgr.h"
     59 
     60 #include "ithread.h"
     61 
     62 /**
     63 *******************************************************************************
     64 *
     65 * @brief Returns size for buf queue context. Does not include buf queue buffer
     66 * requirements
     67 *
     68 * @par   Description
     69 * Returns size for buf queue context. Does not include buf queue buffer
     70 * requirements. Buffer size required to store the bufs should be allocated in
     71 * addition to the value returned here.
     72 *
     73 * @returns Size of the buf queue context
     74 *
     75 * @remarks
     76 *
     77 *******************************************************************************
     78 */
     79 WORD32 ih264_buf_mgr_size(void)
     80 {
     81     WORD32 size;
     82 
     83     size = sizeof(buf_mgr_t);
     84     size += ithread_get_mutex_lock_size();
     85 
     86     return size;
     87 }
     88 
     89 /**
     90 *******************************************************************************
     91 *
     92 * @brief
     93 *   Locks the buf_mgr context
     94 *
     95 * @par   Description
     96 *   Locks the buf_mgr context by calling ithread_mutex_lock()
     97 *
     98 * @param[in] ps_buf_mgr
     99 *   Job Queue context
    100 *
    101 * @returns IH264_FAIL if mutex lock fails else IH264_SUCCESS
    102 *
    103 * @remarks
    104 *
    105 *******************************************************************************
    106 */
    107 IH264_ERROR_T ih264_buf_mgr_lock(buf_mgr_t *ps_buf_mgr)
    108 {
    109     WORD32 retval;
    110     retval = ithread_mutex_lock(ps_buf_mgr->pv_mutex);
    111     if(retval)
    112     {
    113         return IH264_FAIL;
    114     }
    115     return IH264_SUCCESS;
    116 }
    117 
    118 /**
    119 *******************************************************************************
    120 *
    121 * @brief
    122 *   Unlocks the buf_mgr context
    123 *
    124 * @par   Description
    125 *   Unlocks the buf_mgr context by calling ithread_mutex_unlock()
    126 *
    127 * @param[in] ps_buf_mgr
    128 *   Job Queue context
    129 *
    130 * @returns IH264_FAIL if mutex unlock fails else IH264_SUCCESS
    131 *
    132 * @remarks
    133 *
    134 *******************************************************************************
    135 */
    136 
    137 IH264_ERROR_T ih264_buf_mgr_unlock(buf_mgr_t *ps_buf_mgr)
    138 {
    139     WORD32 retval;
    140     retval = ithread_mutex_unlock(ps_buf_mgr->pv_mutex);
    141     if(retval)
    142     {
    143         return IH264_FAIL;
    144     }
    145     return IH264_SUCCESS;
    146 
    147 }
    148 /**
    149 *******************************************************************************
    150 *
    151 * @brief
    152 *   Yeilds the thread
    153 *
    154 * @par   Description
    155 *   Unlocks the buf_mgr context by calling
    156 * ih264_buf_mgr_unlock(), ithread_yield() and then ih264_buf_mgr_lock()
    157 * buf_mgr is unlocked before to ensure the buf_mgr can be accessed by other threads
    158 * If unlock is not done before calling yield then no other thread can access
    159 * the buf_mgr functions and update buf_mgr.
    160 *
    161 * @param[in] ps_buf_mgr
    162 *   Job Queue context
    163 *
    164 * @returns IH264_FAIL if mutex lock unlock or yield fails else IH264_SUCCESS
    165 *
    166 * @remarks
    167 *
    168 *******************************************************************************
    169 */
    170 IH264_ERROR_T ih264_buf_mgr_yield(buf_mgr_t *ps_buf_mgr)
    171 {
    172 
    173     IH264_ERROR_T ret = IH264_SUCCESS;
    174 
    175     IH264_ERROR_T rettmp;
    176     rettmp = ih264_buf_mgr_unlock(ps_buf_mgr);
    177     RETURN_IF((rettmp != IH264_SUCCESS), rettmp);
    178 
    179     //ithread_usleep(10);
    180     ithread_yield();
    181 
    182     rettmp = ih264_buf_mgr_lock(ps_buf_mgr);
    183     RETURN_IF((rettmp != IH264_SUCCESS), rettmp);
    184     return ret;
    185 }
    186 
    187 
    188 /**
    189 *******************************************************************************
    190 *
    191 * @brief free the buf queue pointers
    192 *
    193 * @par   Description
    194 * Frees the buf_mgr context
    195 *
    196 * @param[in] pv_buf
    197 * Memoy for buf queue buffer and buf queue context
    198 *
    199 * @returns Pointer to buf queue context
    200 *
    201 * @remarks
    202 * Since it will be called only once by master thread this is not thread safe.
    203 *
    204 *******************************************************************************
    205 */
    206 IH264_ERROR_T ih264_buf_mgr_free(buf_mgr_t *ps_buf_mgr)
    207 {
    208     WORD32 ret;
    209     ret = ithread_mutex_destroy(ps_buf_mgr->pv_mutex);
    210 
    211     if(0 == ret)
    212         return IH264_SUCCESS;
    213     else
    214         return IH264_FAIL;
    215 }
    216 /**
    217 *******************************************************************************
    218 *
    219 * @brief
    220 *      Buffer manager initialization function.
    221 *
    222 * @par Description:
    223 *    Initializes the buffer manager structure
    224 *
    225 * @param[in] ps_buf_mgr
    226 *  Pointer to the buffer manager
    227 *
    228 * @returns
    229 *
    230 * @remarks
    231 *  None
    232 *
    233 *******************************************************************************
    234 */
    235 
    236 
    237 void *ih264_buf_mgr_init(void *pv_buf)
    238 {
    239     WORD32 id;
    240     UWORD8 *pu1_buf;
    241     buf_mgr_t *ps_buf_mgr;
    242     pu1_buf = (UWORD8 *)pv_buf;
    243 
    244     ps_buf_mgr = (buf_mgr_t *)pu1_buf;
    245     pu1_buf += sizeof(buf_mgr_t);
    246 
    247     ps_buf_mgr->pv_mutex = pu1_buf;
    248     pu1_buf += ithread_get_mutex_lock_size();
    249 
    250     ithread_mutex_init(ps_buf_mgr->pv_mutex);
    251 
    252     ps_buf_mgr->i4_max_buf_cnt = BUF_MGR_MAX_CNT;
    253     ps_buf_mgr->i4_active_buf_cnt = 0;
    254 
    255     for(id = 0; id < BUF_MGR_MAX_CNT; id++)
    256     {
    257         ps_buf_mgr->au4_status[id] = 0;
    258         ps_buf_mgr->apv_ptr[id] = NULL;
    259     }
    260 
    261     return ps_buf_mgr;
    262 }
    263 
    264 
    265 /**
    266 *******************************************************************************
    267 *
    268 * @brief
    269 *       Adds and increments the buffer and buffer count.
    270 *
    271 * @par Description:
    272 *     Adds a buffer to the buffer manager if it is not already  present and
    273 *   increments the  active buffer count
    274 *
    275 * @param[in] ps_buf_mgr
    276 *  Pointer to the buffer manager
    277 *
    278 * @param[in] pv_ptr
    279 *  Pointer to the buffer to be added
    280 *
    281 * @returns  Returns 0 on success, -1 otherwise
    282 *
    283 * @remarks
    284 *  None
    285 *
    286 *******************************************************************************
    287 */
    288 IH264_ERROR_T ih264_buf_mgr_add(buf_mgr_t *ps_buf_mgr,
    289                                 void *pv_ptr,
    290                                 WORD32 buf_id)
    291 {
    292 
    293     IH264_ERROR_T ret = IH264_SUCCESS;
    294     ret = ih264_buf_mgr_lock(ps_buf_mgr);
    295     RETURN_IF((ret != IH264_SUCCESS), ret);
    296 
    297     /* Check if buffer ID is within allowed range */
    298     if(buf_id >= ps_buf_mgr->i4_max_buf_cnt)
    299     {
    300         ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    301         RETURN_IF((ret != IH264_SUCCESS), ret);
    302 
    303         return IH264_FAIL;
    304     }
    305 
    306     /* Check if the current ID is being used to hold some other buffer */
    307     if((ps_buf_mgr->apv_ptr[buf_id] != NULL) &&
    308        (ps_buf_mgr->apv_ptr[buf_id] !=pv_ptr))
    309     {
    310         ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    311         RETURN_IF((ret != IH264_SUCCESS), ret);
    312 
    313         return IH264_FAIL;
    314     }
    315     ps_buf_mgr->apv_ptr[buf_id] = pv_ptr;
    316     ps_buf_mgr->i4_active_buf_cnt++;
    317 
    318     ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    319     RETURN_IF((ret != IH264_SUCCESS), ret);
    320 
    321     return ret;
    322 }
    323 
    324 /**
    325 *******************************************************************************
    326 *
    327 * @brief
    328 *   Gets the next free buffer.
    329 *
    330 * @par Description:
    331 *     Returns the next free buffer available and sets the  corresponding status
    332 *   to DEC
    333 *
    334 * @param[in] ps_buf_mgr
    335 *  Pointer to the buffer manager
    336 *
    337 * @param[in] pi4_buf_id
    338 *  Pointer to the id of the free buffer
    339 *
    340 * @returns  Pointer to the free buffer
    341 *
    342 * @remarks
    343 *  None
    344 *
    345 *******************************************************************************
    346 */
    347 void* ih264_buf_mgr_get_next_free(buf_mgr_t *ps_buf_mgr, WORD32 *pi4_buf_id)
    348 {
    349     WORD32 id;
    350     void *pv_ret_ptr;
    351     IH264_ERROR_T ret = IH264_SUCCESS;
    352     ret = ih264_buf_mgr_lock(ps_buf_mgr);
    353     RETURN_IF((ret != IH264_SUCCESS), NULL);
    354 
    355     pv_ret_ptr = NULL;
    356     for(id = 0; id < ps_buf_mgr->i4_active_buf_cnt; id++)
    357     {
    358         /* Check if the buffer is non-null and status is zero */
    359         if((ps_buf_mgr->au4_status[id] == 0) && (ps_buf_mgr->apv_ptr[id]))
    360         {
    361             *pi4_buf_id = id;
    362             /* DEC is set to 1 */
    363             ps_buf_mgr->au4_status[id] = 1;
    364             pv_ret_ptr = ps_buf_mgr->apv_ptr[id];
    365             break;
    366         }
    367     }
    368     ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    369     RETURN_IF((ret != IH264_SUCCESS), NULL);
    370 
    371     return pv_ret_ptr;
    372 }
    373 
    374 
    375 /**
    376 *******************************************************************************
    377 *
    378 * @brief
    379 *      Checks the buffer manager for free buffers available.
    380 *
    381 * @par Description:
    382 *  Checks if there are any free buffers available
    383 *
    384 * @param[in] ps_buf_mgr
    385 *  Pointer to the buffer manager
    386 *
    387 * @returns  Returns 0 if available, -1 otherwise
    388 *
    389 * @remarks
    390 *  None
    391 *
    392 *******************************************************************************
    393 */
    394 IH264_ERROR_T ih264_buf_mgr_check_free(buf_mgr_t *ps_buf_mgr)
    395 {
    396     WORD32 id;
    397     IH264_ERROR_T ret = IH264_SUCCESS;
    398     IH264_ERROR_T rettmp = IH264_SUCCESS;
    399     rettmp = ih264_buf_mgr_lock(ps_buf_mgr);
    400     RETURN_IF((rettmp != IH264_SUCCESS), ret);
    401 
    402     ret = IH264_FAIL;
    403     for(id = 0; id < ps_buf_mgr->i4_active_buf_cnt; id++)
    404     {
    405         if((ps_buf_mgr->au4_status[id] == 0) &&
    406            (ps_buf_mgr->apv_ptr[id]))
    407         {
    408             ret = IH264_SUCCESS;
    409             break;
    410         }
    411     }
    412     rettmp = ih264_buf_mgr_unlock(ps_buf_mgr);
    413     RETURN_IF((rettmp != IH264_SUCCESS), ret);
    414 
    415     return ret;
    416 
    417 }
    418 
    419 
    420 /**
    421 *******************************************************************************
    422 *
    423 * @brief
    424 *       Resets the status bits.
    425 *
    426 * @par Description:
    427 *     resets the status bits that the mask contains (status  corresponding to
    428 *    the id)
    429 *
    430 * @param[in] ps_buf_mgr
    431 *  Pointer to the buffer manager
    432 *
    433 * @param[in] buf_id
    434 *  ID of the buffer status to be released
    435 *
    436 * @param[in] mask
    437 *  Contains the bits that are to be reset
    438 *
    439 * @returns  0 if success, -1 otherwise
    440 *
    441 * @remarks
    442 *  None
    443 *
    444 *******************************************************************************
    445 */
    446 IH264_ERROR_T ih264_buf_mgr_release(buf_mgr_t *ps_buf_mgr,
    447                                     WORD32 buf_id,
    448                                     UWORD32 mask)
    449 {
    450     IH264_ERROR_T ret = IH264_SUCCESS;
    451     ret = ih264_buf_mgr_lock(ps_buf_mgr);
    452     RETURN_IF((ret != IH264_SUCCESS), ret);
    453 
    454 
    455     /* If the given id is pointing to an id which is not yet added */
    456     if(buf_id >= ps_buf_mgr->i4_active_buf_cnt)
    457     {
    458         ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    459         RETURN_IF((ret != IH264_SUCCESS), ret);
    460         return IH264_FAIL;
    461     }
    462 
    463     ps_buf_mgr->au4_status[buf_id] &= ~mask;
    464 
    465 
    466 /*     If both the REF and DISP are zero, DEC is set to zero */
    467     if(ps_buf_mgr->au4_status[buf_id] == 1)
    468     {
    469         ps_buf_mgr->au4_status[buf_id] = 0;
    470     }
    471 
    472 
    473     ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    474     RETURN_IF((ret != IH264_SUCCESS), ret);
    475 
    476     return ret;
    477 }
    478 
    479 
    480 /**
    481 *******************************************************************************
    482 *
    483 * @brief
    484 *      Sets the status bit.
    485 *
    486 * @par Description:
    487 *     sets the status bits that the mask contains (status  corresponding to the
    488 *    id)
    489 *
    490 *
    491 * @param[in] ps_buf_mgr
    492 *  Pointer to the buffer manager
    493 *
    494 * @param[in] buf_id
    495 *  ID of the buffer whose status needs to be modified
    496 *
    497 *
    498 * @param[in] mask
    499 *  Contains the bits that are to be set
    500 *
    501 * @returns  0 if success, -1 otherwise
    502 *
    503 * @remarks
    504 *  None
    505 *
    506 *******************************************************************************
    507 */
    508 IH264_ERROR_T ih264_buf_mgr_set_status(buf_mgr_t *ps_buf_mgr,
    509                                        WORD32 buf_id,
    510                                        UWORD32 mask)
    511 {
    512     IH264_ERROR_T ret = IH264_SUCCESS;
    513     ret = ih264_buf_mgr_lock(ps_buf_mgr);
    514     RETURN_IF((ret != IH264_SUCCESS), ret);
    515 
    516     if(buf_id >= ps_buf_mgr->i4_active_buf_cnt)
    517     {
    518         ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    519         RETURN_IF((ret != IH264_SUCCESS), ret);
    520         return IH264_FAIL;
    521     }
    522 
    523 
    524     if((ps_buf_mgr->au4_status[buf_id] & mask) != 0)
    525     {
    526         ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    527         RETURN_IF((ret != IH264_SUCCESS), ret);
    528         return IH264_FAIL;
    529     }
    530 
    531     ps_buf_mgr->au4_status[buf_id] |= mask;
    532     ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    533     RETURN_IF((ret != IH264_SUCCESS), ret);
    534 
    535     return ret;
    536 }
    537 
    538 
    539 /**
    540 *******************************************************************************
    541 *
    542 * @brief
    543 *   Returns the status of the buffer.
    544 *
    545 * @par Description:
    546 *  Returns the status of the buffer corresponding to the id
    547 *
    548 * @param[in] ps_buf_mgr
    549 *  Pointer to the buffer manager
    550 *
    551 * @param[in] buf_id
    552 *  ID of the buffer status required
    553 *
    554 * @returns  Status of the buffer corresponding to the id
    555 *
    556 * @remarks
    557 *  None
    558 *
    559 *******************************************************************************
    560 */
    561 WORD32 ih264_buf_mgr_get_status( buf_mgr_t *ps_buf_mgr, WORD32 buf_id )
    562 {
    563     IH264_ERROR_T ret = IH264_SUCCESS;
    564     UWORD32 status;
    565 
    566     ret = ih264_buf_mgr_lock(ps_buf_mgr);
    567     RETURN_IF((ret != IH264_SUCCESS), ret);
    568 
    569     status = ps_buf_mgr->au4_status[buf_id];
    570 
    571     ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    572     RETURN_IF((ret != IH264_SUCCESS), ret);
    573 
    574     return status;
    575 }
    576 
    577 
    578 /**
    579 *******************************************************************************
    580 *
    581 * @brief
    582 *      Gets the buffer from the buffer manager
    583 *
    584 * @par Description:
    585 *        Returns the pointer to the buffer corresponding to the id
    586 *
    587 * @param[in] ps_buf_mgr
    588 *  Pointer to the buffer manager
    589 *
    590 * @param[in] buf_id
    591 *  ID of the buffer required
    592 *
    593 * @returns  Pointer to the buffer required
    594 *
    595 * @remarks
    596 *  None
    597 *
    598 *******************************************************************************
    599 */
    600 void* ih264_buf_mgr_get_buf(buf_mgr_t *ps_buf_mgr, WORD32 buf_id)
    601 {
    602     IH264_ERROR_T ret = IH264_SUCCESS;
    603     void *pv_buf;
    604     ret = ih264_buf_mgr_lock(ps_buf_mgr);
    605     RETURN_IF((ret != IH264_SUCCESS), NULL);
    606 
    607     pv_buf = ps_buf_mgr->apv_ptr[buf_id];
    608 
    609     ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    610     RETURN_IF((ret != IH264_SUCCESS), NULL);
    611 
    612     return pv_buf;
    613 }
    614 
    615 
    616 /**
    617 *******************************************************************************
    618 *
    619 * @brief
    620 *  Gets the buffer id from the buffer manager if the buffer is added to the
    621 *  buffer manager
    622 *
    623 * @par Description:
    624 *  Returns the buffer id corresponding to the given buffer if it exists
    625 *
    626 * @param[in] ps_buf_mgr
    627 *  Pointer to the buffer manager
    628 *
    629 * @param[in] pv_buf
    630 *  Pointer to the buffer
    631 *
    632 * @returns  Buffer id if exists, else -1
    633 *
    634 * @remarks
    635 *  None
    636 *
    637 *******************************************************************************
    638 */
    639 WORD32 ih264_buf_mgr_get_bufid(buf_mgr_t *ps_buf_mgr, void *pv_buf)
    640 {
    641     WORD32 id;
    642     WORD32 buf_id = -1;
    643     IH264_ERROR_T ret = IH264_SUCCESS;
    644     ret = ih264_buf_mgr_lock(ps_buf_mgr);
    645     RETURN_IF((ret != IH264_SUCCESS), ret);
    646 
    647     for(id = 0; id < ps_buf_mgr->i4_active_buf_cnt; id++)
    648     {
    649         if(ps_buf_mgr->apv_ptr[id] == pv_buf)
    650         {
    651             buf_id = id;
    652             break;
    653         }
    654     }
    655     ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    656     RETURN_IF((ret != IH264_SUCCESS), ret);
    657 
    658     return buf_id;
    659 }
    660 
    661 
    662 /**
    663 *******************************************************************************
    664 *
    665 * @brief
    666 *        Gets the no.of active buffer
    667 *
    668 * @par Description:
    669 *      Return the number of active buffers in the buffer manager
    670 *
    671 * @param[in] ps_buf_mgr
    672 *  Pointer to the buffer manager
    673 *
    674 * @returns  number of active buffers
    675 *
    676 * @remarks
    677 *  None
    678 *
    679 *******************************************************************************
    680 */
    681 UWORD32 ih264_buf_mgr_get_num_active_buf(buf_mgr_t *ps_buf_mgr)
    682 {
    683     UWORD32 u4_buf_cnt;
    684     IH264_ERROR_T ret = IH264_SUCCESS;
    685 
    686     u4_buf_cnt = 0;
    687 
    688     ret = ih264_buf_mgr_lock(ps_buf_mgr);
    689     RETURN_IF((ret != IH264_SUCCESS), ret);
    690     u4_buf_cnt = ps_buf_mgr->i4_active_buf_cnt;
    691 
    692     ret = ih264_buf_mgr_unlock(ps_buf_mgr);
    693     RETURN_IF((ret != IH264_SUCCESS), ret);
    694 
    695     return u4_buf_cnt;
    696 }
    697