You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
417 lines
13 KiB
417 lines
13 KiB
/******************************************************************************
|
|
*
|
|
* Copyright (C) 2018 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at:
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*****************************************************************************
|
|
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
|
|
*/
|
|
|
|
/**
|
|
******************************************************************************
|
|
* @file
|
|
* ihevce_buffer_que.c
|
|
*
|
|
* @brief
|
|
* This file contains all the functions related to Buffer Queue manager
|
|
*
|
|
* @author
|
|
* ittiam
|
|
*
|
|
* @par List of Functions:
|
|
* ihevce_buff_que_get_mem_recs
|
|
* ihevce_buff_que_get_num_mem_recs
|
|
* ihevce_buff_que_init
|
|
* ihevce_buff_que_get_free_buf
|
|
* ihevce_buff_que_get_next_buf
|
|
* ihevce_buff_que_get_next_reorder_buf
|
|
* ihevce_buff_que_set_buf_prod
|
|
* ihevce_buff_que_rel_buf
|
|
* ihevce_buff_que_get_active_bufs
|
|
* ihevce_buff_que_set_reorder_buf
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
/* File Includes */
|
|
/*****************************************************************************/
|
|
|
|
/* System Include Files */
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <assert.h>
|
|
|
|
/* User Include Files */
|
|
#include "ihevc_typedefs.h"
|
|
#include "itt_video_api.h"
|
|
#include "ihevce_buffer_que_interface.h"
|
|
#include "ihevce_buffer_que_private.h"
|
|
|
|
/*****************************************************************************/
|
|
/* Function Definitions */
|
|
/*****************************************************************************/
|
|
|
|
/*!
|
|
************************************************************************
|
|
* \brief
|
|
* return number of records used by Buffer Que manager.
|
|
************************************************************************
|
|
*/
|
|
WORD32 ihevce_buff_que_get_num_mem_recs(void)
|
|
{
|
|
return (NUM_BUFFER_QUE_MEM_RECS);
|
|
}
|
|
|
|
/*!
|
|
************************************************************************
|
|
* \brief
|
|
* return each record attributes of Buffer Que manager
|
|
************************************************************************
|
|
*/
|
|
WORD32 ihevce_buff_que_get_mem_recs(
|
|
iv_mem_rec_t *ps_mem_tab, WORD32 max_num_bufs_in_que, WORD32 i4_mem_space)
|
|
{
|
|
/* Que manager state structure */
|
|
ps_mem_tab[BUFFER_QUE_CTXT].i4_mem_size = sizeof(buf_que_t);
|
|
ps_mem_tab[BUFFER_QUE_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
|
|
ps_mem_tab[BUFFER_QUE_CTXT].i4_mem_alignment = 8;
|
|
|
|
/* number of users memory */
|
|
ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].i4_mem_size = (sizeof(WORD32) * max_num_bufs_in_que);
|
|
ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
|
|
ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].i4_mem_alignment = 8;
|
|
|
|
/* Produced status memory */
|
|
ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].i4_mem_size = (sizeof(WORD32) * max_num_bufs_in_que);
|
|
ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
|
|
ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].i4_mem_alignment = 8;
|
|
|
|
/* Encode sequence memory */
|
|
ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].i4_mem_size = (sizeof(UWORD32) * max_num_bufs_in_que);
|
|
ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
|
|
ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].i4_mem_alignment = 8;
|
|
|
|
/* Queued sequence memory */
|
|
ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].i4_mem_size = (sizeof(UWORD32) * max_num_bufs_in_que);
|
|
ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
|
|
ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].i4_mem_alignment = 8;
|
|
|
|
return (NUM_BUFFER_QUE_MEM_RECS);
|
|
}
|
|
|
|
/*!
|
|
************************************************************************
|
|
* \brief
|
|
* Intialization for Buffer Que manager state structure
|
|
************************************************************************
|
|
*/
|
|
void *ihevce_buff_que_init(iv_mem_rec_t *ps_mem_tab, WORD32 num_bufs_in_que, void **ppv_buff_ptrs)
|
|
{
|
|
buf_que_t *ps_buf_que;
|
|
WORD32 i;
|
|
|
|
/* que manager state structure */
|
|
ps_buf_que = (buf_que_t *)ps_mem_tab[BUFFER_QUE_CTXT].pv_base;
|
|
|
|
/* buffer status memory init */
|
|
ps_buf_que->pi4_num_users = (WORD32 *)ps_mem_tab[BUFFER_QUE_NUM_USER_MEM].pv_base;
|
|
|
|
ps_buf_que->pi4_produced_sts = (WORD32 *)ps_mem_tab[BUFFER_QUE_PROD_STS_MEM].pv_base;
|
|
|
|
ps_buf_que->pu4_enc_seq = (UWORD32 *)ps_mem_tab[BUFFER_QUE_ENC_SEQ_MEM].pv_base;
|
|
|
|
ps_buf_que->pu4_que_seq = (UWORD32 *)ps_mem_tab[BUFFER_QUE_QUED_SEQ_MEM].pv_base;
|
|
|
|
/* reset the state structure variables */
|
|
ps_buf_que->i4_num_bufs = num_bufs_in_que;
|
|
ps_buf_que->i4_num_active_bufs = 0;
|
|
ps_buf_que->u4_last_prod = 0;
|
|
ps_buf_que->u4_last_cons = 0;
|
|
ps_buf_que->u4_next_disp_seq = 0;
|
|
ps_buf_que->u4_last_disp_seq = 0;
|
|
ps_buf_que->ppv_buff_ptrs = ppv_buff_ptrs;
|
|
|
|
/* init all the buffer status to default values */
|
|
for(i = 0; i < ps_buf_que->i4_num_bufs; i++)
|
|
{
|
|
ps_buf_que->pi4_num_users[i] = 0;
|
|
ps_buf_que->pi4_produced_sts[i] = 0;
|
|
ps_buf_que->pu4_enc_seq[i] = UINT32_MAX;
|
|
ps_buf_que->pu4_que_seq[i] = UINT32_MAX;
|
|
}
|
|
|
|
return ((void *)ps_buf_que);
|
|
}
|
|
|
|
/*!
|
|
**************************************************************************
|
|
* \brief
|
|
* This function gets the next free buffer. This function is called by the
|
|
* Producer to get a free buffer
|
|
**************************************************************************
|
|
*/
|
|
void *ihevce_buff_que_get_free_buf(void *pv_buf_que, WORD32 *pi4_id)
|
|
{
|
|
buf_que_t *ps_buf_que;
|
|
WORD32 i;
|
|
WORD32 num_bufs;
|
|
|
|
ps_buf_que = (buf_que_t *)pv_buf_que;
|
|
num_bufs = ps_buf_que->i4_num_bufs;
|
|
|
|
/* loop unitl a free buffer is found */
|
|
for(i = 0; i < num_bufs; i++)
|
|
{
|
|
if((ps_buf_que->pi4_num_users[i] == 0) && (ps_buf_que->pi4_produced_sts[i] == 0))
|
|
{
|
|
*(pi4_id) = i;
|
|
ps_buf_que->pi4_num_users[i] = 1;
|
|
ps_buf_que->pu4_que_seq[i] = ps_buf_que->u4_last_prod;
|
|
ps_buf_que->u4_last_prod += 1;
|
|
|
|
return (ps_buf_que->ppv_buff_ptrs[i]);
|
|
}
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
/*!
|
|
**************************************************************************
|
|
* \brief
|
|
* This function gets the next buffer in Que . This function will be called by
|
|
* consumer to get the next buffer in Queued order.
|
|
**************************************************************************
|
|
*/
|
|
void *ihevce_buff_que_get_next_buf(void *pv_buf_que, WORD32 *pi4_id)
|
|
{
|
|
buf_que_t *ps_buf_que;
|
|
WORD32 i;
|
|
UWORD32 next_qued_seq;
|
|
|
|
ps_buf_que = (buf_que_t *)pv_buf_que;
|
|
|
|
/* get the next queued buffer to be sent */
|
|
next_qued_seq = ps_buf_que->u4_last_cons;
|
|
|
|
/* check for matching index */
|
|
for(i = 0; i < ps_buf_que->i4_num_bufs; i++)
|
|
{
|
|
if(next_qued_seq == ps_buf_que->pu4_que_seq[i])
|
|
{
|
|
if(1 == ps_buf_que->pi4_produced_sts[i])
|
|
{
|
|
*(pi4_id) = i;
|
|
ps_buf_que->u4_last_cons += 1;
|
|
|
|
return (ps_buf_que->ppv_buff_ptrs[i]);
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Buffer not ready for Consumption */
|
|
return (NULL);
|
|
}
|
|
|
|
/*!
|
|
**************************************************************************
|
|
* \brief
|
|
* This function gives the buffer curresponding to the id passed
|
|
**************************************************************************
|
|
*/
|
|
void *ihevce_buff_que_get_buf(void *pv_buf_que, WORD32 i4_id)
|
|
{
|
|
buf_que_t *ps_buf_que;
|
|
|
|
ps_buf_que = (buf_que_t *)pv_buf_que;
|
|
|
|
if(i4_id >= ps_buf_que->i4_num_bufs)
|
|
return (NULL);
|
|
|
|
return (ps_buf_que->ppv_buff_ptrs[i4_id]);
|
|
}
|
|
|
|
/*!
|
|
**************************************************************************
|
|
* \brief
|
|
* This function gets the next buffer for in reordered order. This function
|
|
* will be called by consumer to get the next buffer in reordered order
|
|
**************************************************************************
|
|
*/
|
|
void *ihevce_buff_que_get_next_reorder_buf(void *pv_buf_que, WORD32 *pi4_id)
|
|
{
|
|
buf_que_t *ps_buf_que;
|
|
WORD32 i;
|
|
UWORD32 next_disp_seq;
|
|
|
|
ps_buf_que = (buf_que_t *)pv_buf_que;
|
|
|
|
/* get the next reordered buffer to be sent */
|
|
next_disp_seq = ps_buf_que->u4_last_disp_seq;
|
|
|
|
/* check for matching index */
|
|
for(i = 0; i < ps_buf_que->i4_num_bufs; i++)
|
|
{
|
|
if(next_disp_seq == ps_buf_que->pu4_enc_seq[i])
|
|
{
|
|
*(pi4_id) = i;
|
|
ps_buf_que->u4_last_disp_seq += 1;
|
|
|
|
return (ps_buf_que->ppv_buff_ptrs[i]);
|
|
}
|
|
}
|
|
|
|
/* Buffer not ready for Consumption */
|
|
return (NULL);
|
|
}
|
|
|
|
/*!
|
|
**************************************************************************
|
|
* \brief
|
|
* This function sets the buffer as produced. This function will be called
|
|
* by Producer to say that buffer is ready for consumption.
|
|
**************************************************************************
|
|
*/
|
|
WORD32 ihevce_buff_que_set_buf_prod(void *pv_buf_que, WORD32 buf_id, WORD32 num_users)
|
|
{
|
|
buf_que_t *ps_buf_que;
|
|
|
|
ps_buf_que = (buf_que_t *)pv_buf_que;
|
|
|
|
if(buf_id < ps_buf_que->i4_num_bufs)
|
|
{
|
|
if(ps_buf_que->pi4_produced_sts[buf_id] == 0)
|
|
{
|
|
ps_buf_que->pi4_num_users[buf_id] += num_users;
|
|
ps_buf_que->i4_num_active_bufs += 1;
|
|
ps_buf_que->pi4_produced_sts[buf_id] = 1;
|
|
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
/* Buffer is already marked as Produced */
|
|
return (-1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Unable to recognize the Buffer ID */
|
|
return (-1);
|
|
}
|
|
|
|
return (-1);
|
|
}
|
|
|
|
/*!
|
|
**************************************************************************
|
|
* \brief
|
|
* This function decrements number of users. If Number of users are Zero,
|
|
* then active Buffers in list gets decremented and this buffer is marked
|
|
* unused.
|
|
**************************************************************************
|
|
*/
|
|
WORD32 ihevce_buff_que_rel_buf(void *pv_buf_que, WORD32 buf_id)
|
|
{
|
|
buf_que_t *ps_buf_que;
|
|
WORD32 i;
|
|
|
|
ps_buf_que = (buf_que_t *)pv_buf_que;
|
|
i = buf_id;
|
|
|
|
/* check if the buf id is less than max num buffers */
|
|
if(i < ps_buf_que->i4_num_bufs)
|
|
{
|
|
if(ps_buf_que->pi4_produced_sts[i] > 0)
|
|
{
|
|
/* decrease the number of users */
|
|
ps_buf_que->pi4_num_users[i] -= 1;
|
|
|
|
if(ps_buf_que->pi4_num_users[i] == 0)
|
|
{
|
|
if(0 == ps_buf_que->i4_num_active_bufs)
|
|
{
|
|
return (-1);
|
|
}
|
|
|
|
ps_buf_que->i4_num_active_bufs -= 1;
|
|
ps_buf_que->pi4_produced_sts[i] = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
/* Illeagal release of Buffer, No one is using it */
|
|
return (-1);
|
|
}
|
|
}
|
|
|
|
/* Unable to recognize the Buffer ID */
|
|
return (-1);
|
|
}
|
|
|
|
/*!
|
|
**************************************************************************
|
|
* \brief
|
|
* This function gets number of active buffers.
|
|
**************************************************************************
|
|
*/
|
|
WORD32 ihevce_buff_que_get_active_bufs(void *pv_buf_que)
|
|
{
|
|
buf_que_t *ps_buf_que;
|
|
|
|
ps_buf_que = (buf_que_t *)pv_buf_que;
|
|
return (ps_buf_que->i4_num_active_bufs);
|
|
}
|
|
|
|
/*!
|
|
**************************************************************************
|
|
* \brief
|
|
* This function sets the reorder number for given buffer.
|
|
* this will set the order for the consumer who is consuming in reorder order
|
|
**************************************************************************
|
|
*/
|
|
WORD32 ihevce_buff_que_set_reorder_buf(void *pv_buf_que, WORD32 buf_id)
|
|
{
|
|
buf_que_t *ps_buf_que;
|
|
|
|
ps_buf_que = (buf_que_t *)pv_buf_que;
|
|
|
|
if(buf_id < ps_buf_que->i4_num_bufs)
|
|
{
|
|
WORD32 next_disp_seq = ps_buf_que->u4_next_disp_seq;
|
|
|
|
/* increment the seq number */
|
|
ps_buf_que->u4_next_disp_seq++;
|
|
|
|
/* set the reorder number to the corresponding id */
|
|
ps_buf_que->pu4_enc_seq[buf_id] = next_disp_seq;
|
|
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
/* invalid buffer id */
|
|
return (-1);
|
|
}
|
|
|
|
return (-1);
|
|
}
|