
#ifdef ANDROID
//#ifndef NULL
//#define NULL (void*)0x0
//#endif

#define true 1
#define false 0
#endif

#include "viddec_pm_utils_list.h"
#include "viddec_fw_debug.h"

/*
  Initialize list.
 */
void viddec_pm_utils_list_init(viddec_pm_utils_list_t *cxt)
{
    cxt->num_items = 0;
    cxt->start_offset = 0;
    cxt->end_offset = -1;
    cxt->total_bytes = 0;
    cxt->first_scprfx_length = 0;
}

/*
  Add a new ES buffer to list. If not succesful returns 0.
 */
uint32_t viddec_pm_utils_list_addbuf(viddec_pm_utils_list_t *list, viddec_input_buffer_t *es_buf)
{
    uint32_t ret = 0;
    if((list->num_items + 1) <= MAX_IBUFS_PER_SC)
    {
        list->num_items +=1;
        list->sc_ibuf[list->num_items - 1] = *es_buf;
        ret = 1;
    }
    return ret;
}

/*
  We return the index of es buffer and the offset into it for the requested byte offset.
  EX: if byte=4, and the first es buffer in list is of length 100, we return lis_index=0, offset=3.
  byte value should range from [1-N].
 */
uint32_t viddec_pm_utils_list_getbyte_position(viddec_pm_utils_list_t *list, uint32_t byte, uint32_t *list_index, uint32_t *offset)
{
    uint32_t index = 0, accumulated_size=0;
    
    /* First buffer in list is always special case, since start offset is tied to it */
    accumulated_size = list->sc_ibuf[index].len - list->start_offset;
    if( accumulated_size >= byte)
    {
        /* we found a match in first buffer itself */
        *offset = list->start_offset + byte - 1;
        *list_index = index;
        return 0;
    }
    index++;
    /* walkthrough the list until we find the byte */
    while(index < list->num_items)
    { 
        if((accumulated_size + list->sc_ibuf[index].len) >= byte)
        {
            *offset = byte - accumulated_size - 1;
            *list_index = index;
            return 0;
        }
        accumulated_size += list->sc_ibuf[index].len;
        index++;
    }
    return 1;
}

/*
  Since the stream data can span multiple ES buffers on different DDR locations, for our purpose
  we store start and end position on each ES buffer to make the data look linear.
  The start represents the linear offset of the first byte in list.
  end-1 represents linear offset of last byte in list.
 */
void viddec_pm_utils_list_updatebytepos(viddec_pm_utils_list_t *list, uint8_t sc_prefix_length)
{
    uint32_t items=0;
    uint32_t start=0, end=0;
 
    if(list->num_items != 0)
    {
        end = list->sc_ibuf[0].len - list->start_offset;
        if((int32_t)end >= list->total_bytes) end = list->total_bytes;
        list->data[items].stpos = start;
        list->data[items].edpos = end;
        items++;
        while((int32_t)end < list->total_bytes)
        {
            start = end;
            end += list->sc_ibuf[items].len;
            if((int32_t)end >= list->total_bytes) end = list->total_bytes;
            list->data[items].stpos = start;
            list->data[items].edpos = end;
            items++;
        }
        while(items < list->num_items)
        {
            if(sc_prefix_length != 0)
            {
                start = end = list->total_bytes+1;
            }
            else
            {
                start = end = list->total_bytes;
            }
            list->data[items].stpos = start;
            list->data[items].edpos = end;
            items++;            
        }
        /* Normal access unit sequence is SC+data+SC. We read SC+data+SC bytes so far.
           but the current access unit should be SC+data, the Second SC belongs to next access unit.
           So we subtract SC length to reflect that */
        list->total_bytes -= sc_prefix_length;
    }
}

static inline void viddec_pm_utils_list_emit_slice_tags_append(viddec_emitter_wkld *cur_wkld, viddec_workload_item_t *wi)
{
    /*
      Most of the time len >0. However we can have a condition on EOS where the last buffer can be
      zero sized in which case we want to make sure that we emit END of SLICE information.
     */
    if((wi->es.es_phys_len != 0) || (wi->es.es_flags&VIDDEC_WORKLOAD_FLAGS_ES_END_SLICE))
    {
        viddec_emit_append(cur_wkld, wi);
    }
}

/*
  Emit requested tags for data from start to end position. The tags should include end byte too.
 */
void viddec_pm_utils_list_emit_slice_tags(viddec_pm_utils_list_t *list, uint32_t start, uint32_t end, viddec_emitter *emitter, uint32_t is_cur_wkld, viddec_workload_item_t *wi)
{
    if((list->num_items != 0) && ((int32_t)start < (list->total_bytes)) && ((int32_t)end <= (list->total_bytes)))
    {
        uint32_t flags=0, items=0;
        viddec_emitter_wkld *cur_wkld;

        flags = wi->es.es_flags;
        cur_wkld = (is_cur_wkld != 0) ? &(emitter->cur):&(emitter->next);
        /* Seek until we find a ES buffer entry which has the start position */
        while(start >= list->data[items].edpos) items++;
        
        if(end < list->data[items].edpos)
        { /* One ES buffer has both start and end in it. So dump a single entry */
            wi->es.es_phys_len = end - start + 1;
            wi->es.es_phys_addr = list->sc_ibuf[items].phys + start - list->data[items].stpos;
            /* Account for start_offset if its the first buffer in List */
            if(items == 0) wi->es.es_phys_addr += list->start_offset;

            wi->es.es_flags = flags | VIDDEC_WORKLOAD_FLAGS_ES_START_SLICE | VIDDEC_WORKLOAD_FLAGS_ES_END_SLICE;
            viddec_pm_utils_list_emit_slice_tags_append(cur_wkld, wi);
        }
        else
        {
            /* We know that there are at least two buffers for the requested data. Dump the first item */
            wi->es.es_phys_len = list->data[items].edpos - start;
            wi->es.es_phys_addr = list->sc_ibuf[items].phys + start - list->data[items].stpos;
            if(items == 0) wi->es.es_phys_addr += list->start_offset;
            wi->es.es_flags = flags | VIDDEC_WORKLOAD_FLAGS_ES_START_SLICE;
            viddec_pm_utils_list_emit_slice_tags_append(cur_wkld, wi);
            items++;
            /* Dump everything in between if any until the last buffer */
            while(end >= list->data[items].edpos)
            {
                wi->es.es_phys_len = list->data[items].edpos - list->data[items].stpos;
                wi->es.es_phys_addr = list->sc_ibuf[items].phys;
                wi->es.es_flags = flags;
                viddec_pm_utils_list_emit_slice_tags_append(cur_wkld, wi);
                items++;
            }
            /* Dump ES buffer which has end in it along with end slice flag */
            wi->es.es_phys_len = end - list->data[items].stpos + 1;
            wi->es.es_phys_addr = list->sc_ibuf[items].phys;
            wi->es.es_flags = flags | VIDDEC_WORKLOAD_FLAGS_ES_END_SLICE;
            viddec_pm_utils_list_emit_slice_tags_append(cur_wkld, wi);
        }
    }
}

/*
  We delete the consumed buffers in our list. If there are any buffers left over which have more data
  the get moved to the top of the list array.
 */
void viddec_pm_utils_list_remove_used_entries(viddec_pm_utils_list_t *list, uint32_t length)
{
    list->end_offset = -1;

    if(list->num_items != 0)
    {
        if(length != 0)
        {
            uint32_t items = list->num_items-1, byte_pos;
            uint32_t index=0;
            viddec_input_buffer_t *es_buf;
            byte_pos = list->total_bytes;
            while((list->data[items].edpos > byte_pos) && (list->data[items].stpos > byte_pos))
            {
                items--;
            }
            if(items != 0)
            {
                list->start_offset = byte_pos - list->data[items].stpos;
                while(items < list->num_items)
                {
                    es_buf = &(list->sc_ibuf[items]);
                    list->sc_ibuf[index] = *es_buf;
                    index++;
                    items++;
                }
                list->num_items = index;
            }
            else
            {
                list->start_offset += (byte_pos - list->data[items].stpos);
            }
        }
        else
        {
            list->num_items = 0;
            list->start_offset = 0;
        }
        list->total_bytes = length;
    }
}
