
#include "viddec_pm.h"
#include "viddec_fw_debug.h"
#include "viddec_fw_common_defs.h"
#include "viddec_pm_tags.h"
/*
  Overview of tag association:

  Contribution flags:
  The current list has all the buffers which contribute to this particular workload. So we walkthrough the
  list and throw buf done for all the buffers which were consumed. This can be deduced from total bytes we
  in list which represents the bytes that were used for this acces unit.
  For buffers which were partially used and this can only be the last buffer we throw continued tag. The
  Parser manager tells us when to throw a continued tag. This will only happen when parser Manager detects
  that we reached end of current frame.

  Association Tags:
  These are the tags that FW generates which indicates how to associate metadata with Frames.
  The policy to determine which tag belongs to which frame is based on sc prefix position. If ES buffer starts with
  or has a sc prefix its associated to next decodable frame(based on first slice or header depending on codec).
  We use three state variables to determine where the frame starts and ends.
    frame_start_found: Indicates we saw the beggining of frame in current list of ES buffers(which represent current acces unit).
                       This is decremented on workload done since it normally means we detected frame end. 
    found_fm_st_in_current_au:Indicates we saw the first slice in current access unit. Its mainly used to decide whether the first buffer
                              belongs to current frame or next frame. Its reset after its use.
    Frame Done: Indicates we detected end of frame pointed by current workload.

   Basic algo:
   If we find frame start and if first buffer doesn't start with SC prefix Every consumed buffer belongs to Next frame. If first buffer
   starts with SC prefix on that buffer belongs to Current frame.
   If we haven't found frame start every buffer belongs to current frame.

   TODO: Check for return codes from emitter
*/


/*
  This function generates contribution tags current workload by walking through list of consumed buffers.
  If frame is done(ignore_partial is false) we generate continue tags for the last item in list(if its not completely consumed).
  This is used for all codecs except H264.
 */
uint32_t viddec_pm_generic_generate_contribution_tags(void *parent, uint32_t ignore_partial)
{
    uint32_t ret = PM_SUCCESS;
    viddec_pm_cxt_t *cxt = (viddec_pm_cxt_t *)parent; 
    viddec_pm_utils_list_t *list = &(cxt->list);

    if(list->num_items != 0)
    {
        if(!cxt->late_frame_detect)
        {
            uint32_t num_items = 0;
            while((num_items < list->num_items) && (list->data[num_items].edpos <= (uint32_t)list->total_bytes))
            {/* Walkthrough Consumed buffers and dump the tags */
                viddec_emit_contr_tag(&(cxt->emitter), &(list->sc_ibuf[num_items]), false, false);
                num_items++;
            }
            /* Dump incomplete tags if required */
            if(!ignore_partial)
            {/* check to see if last item is not consumed and dump continued flag */
                if((num_items < list->num_items)
                   && (list->data[num_items].edpos >= (uint32_t)list->total_bytes))
                {
                    viddec_emit_contr_tag(&(cxt->emitter), &(list->sc_ibuf[num_items]), true, false);
                }
            }
        }
        else
        {
            /* Only happens for dangling fields in MP2 Field pictures, in which case we find out the current frame was done in
               last access unit, which is similar to H264 */
            ret = viddec_pm_lateframe_generate_contribution_tags(parent, ignore_partial);
            cxt->late_frame_detect = false;
        }
    }
    return ret;
}

/*
  For H264 when a frame is done it really means current frame was done in last access unit. The current access unit represnted
  by list belongs to next frame. ignore_partial is false for frame done.
  When frame is not done we dump all consumed buffers into next workload else they go to current workload.
  If frame is done we throw a continued flag for first buffer in current workload if it was used in last access unit.
 */
uint32_t viddec_pm_lateframe_generate_contribution_tags(void *parent, uint32_t ignore_partial)
{
    uint32_t ret = PM_SUCCESS;
    viddec_pm_cxt_t *cxt = (viddec_pm_cxt_t *)parent; 
    viddec_pm_utils_list_t *list = &(cxt->list);

    if(list->num_items != 0)
    {
        uint32_t num_items = 0;
        /* If start offset is not 0 then it was partially used in last access unit. !ignore_partial means frame done*/
        if((list->start_offset!= 0) && !ignore_partial)
        {/* Emit continue in current if necessary. */
            viddec_emit_contr_tag(&(cxt->emitter), &(list->sc_ibuf[num_items]), true, false);
        }
        
        while((num_items < list->num_items) && (list->data[num_items].edpos <= (uint32_t)list->total_bytes))
        {  /* Walkthrough Consumed buffers and dump the tags to current or Next*/
            viddec_emit_contr_tag(&(cxt->emitter), &(list->sc_ibuf[num_items]), false, !ignore_partial);
            num_items++;
        }
    }
    return ret;
}

/*
  This function dumps tags from temporary array into a workload(we indicate either current or next from using_next).
*/
uint32_t viddec_pm_generate_missed_association_tags(viddec_pm_cxt_t *cxt, uint32_t using_next)
{
    uint32_t i=0, ret = PM_SUCCESS;

    while((i < MAX_IBUFS_PER_SC) && (cxt->pending_tags.pending_tags[i] != INVALID_ENTRY))
    {
        viddec_emit_assoc_tag(&(cxt->emitter), cxt->pending_tags.pending_tags[i], using_next);
        cxt->pending_tags.pending_tags[i] = INVALID_ENTRY;
        i++;
    }
    return ret;
}

/* This function adds current list of es buffer to pending list. ignore_first when set tells us to ignore the first
   buffer in list.
*/
void viddec_pm_add_tags_to_pendinglist(viddec_pm_cxt_t *cxt, uint32_t ignore_first)
{
    viddec_pm_utils_list_t *list = &(cxt->list);
    vidded_pm_pending_tags_t *pend = &(cxt->pending_tags);
    uint32_t index=0, t_index=0;

    if(!ignore_first && (list->start_offset == 0))
    {/* If start offset is 0 we are saying that first buffer in list starts with start code */
        pend->first_buf_aligned = true;
    }
    else
    {/* We are ignoring first item in list since we already threw a tag for this buffer */
        index++;
        pend->first_buf_aligned  = false;
    }

    while( (index < list->num_items) && (list->data[index].edpos <= (uint32_t)list->total_bytes))
    {/* walk through consumed buffers and buffer id's in pending list */
        pend->pending_tags[t_index] = list->sc_ibuf[index].id;
        index++;t_index++;
    }
    if( (index < list->num_items) && (list->data[index].stpos < (uint32_t)list->total_bytes))
    {/* If last item is partially consumed still add it to pending tags since tag association is based on start of ES buffer */
        pend->pending_tags[t_index] = list->sc_ibuf[index].id;
    }
}

/* Helper function to emit a association tag from pending list and resetting the value to invalid entry */
static inline void viddec_pm_emit_pending_tag_item(viddec_emitter *emit, vidded_pm_pending_tags_t *pend, uint32_t index, uint32_t using_next)
{
    viddec_emit_assoc_tag(emit, pend->pending_tags[index], using_next);
    pend->pending_tags[index] = INVALID_ENTRY;
}

/*
  Tag association for mpeg2:
  start frame is detected in pict header extension, but pict header represents start of frame.
  To handle this we always store current AU list in temporary pending list. At the start of function
  we look to see if a frame start was found, if we did we start dumping items from pending list based
  on byte position of sc in first buffer of pending list. At the end we copy current list items to
  pending list.
  Limitation With Dangling fields: If we have AF1 AF2 BF1 CF1 CF2 as the sequence of fields
  Tag assocaiation will be fine for A & B, However the first buffer tag on C will fall into B
  We donot want to fix this issue right now as it means doubling size of pending list which
  increases memory usage. Normally dangling fields are thrown away so worst case we will miss
  one original PTS, So its OK not to fix it right now.
 */
uint32_t viddec_mpeg2_add_association_tags(void *parent)
{
    uint32_t ret = PM_SUCCESS;
    viddec_pm_cxt_t *cxt = (viddec_pm_cxt_t *)parent; 
    vidded_pm_pending_tags_t *pend = &(cxt->pending_tags);
    uint32_t first_slice = false, index = 0;
    /* check to see if we found a frame start in current access unit */
    first_slice = cxt->frame_start_found && cxt->found_fm_st_in_current_au;
    cxt->found_fm_st_in_current_au = false;
    /* If we found frame start and first item in pending tags is start with start code
       then it needs to go to current frame. */
    if(first_slice && pend->first_buf_aligned && (pend->pending_tags[index] != INVALID_ENTRY))
    {
        viddec_pm_emit_pending_tag_item(&(cxt->emitter), pend, index, false);
        index++;
    }
    /* rest of list goes to current if frame start is not found else next frame */
    while((index < MAX_IBUFS_PER_SC) && (pend->pending_tags[index] != INVALID_ENTRY))
    {
        viddec_pm_emit_pending_tag_item(&(cxt->emitter), pend, index, cxt->frame_start_found);
        index++;
    }
    /* Copy items to temporary List */
    viddec_pm_add_tags_to_pendinglist(cxt, false);
    return ret;
}

/*
  Tag association for h264:
  In this case when we get frame done it means current frame was done in last access unit. The data in current list belongs
  to next frame. To handle this we always dump the buffered tags from last list and throw them in current/next frame based on pend state.
  If the first item in current list is on sc boundary, it has to go into next so we always throw that tag in next.
  For rest of items we store them in pending tags array and store inforamtion on where these stored tags should go into for
  next run. Thi is detemined by start frame. we do this because at this state our next should be current and "next next" should
  be next.
 */
uint32_t viddec_h264_add_association_tags(void *parent)
{
    uint32_t ret = PM_SUCCESS;
    viddec_pm_cxt_t *cxt = (viddec_pm_cxt_t *)parent; 
    viddec_pm_utils_list_t *list = &(cxt->list);
    vidded_pm_pending_tags_t *pend = &(cxt->pending_tags);
    uint32_t first_slice = false, index = 0;

    /* Throw tags for items from pending list based on stored state  from last run */
    viddec_pm_generate_missed_association_tags(cxt, pend->using_next);
    first_slice = cxt->frame_start_found && cxt->found_fm_st_in_current_au;
    cxt->found_fm_st_in_current_au = false;
    /* If we saw frame start and first buffer is aligned to start code throw it into next */
    if(first_slice && (list->start_offset == 0))
    {
        viddec_emit_assoc_tag(&(cxt->emitter), list->sc_ibuf[index].id, cxt->frame_start_found && cxt->pending_tags.frame_done);
        index++;
    }
    /* add tags to pending list */
    viddec_pm_add_tags_to_pendinglist(cxt, (index != 0));
    /* We want to figure out where these buffers should go into. There are three possible cases
       current: If no frame start found these should go into next.
       next: If one frame start is found and frame is not done then it should go to next.
             if a frame is done then pm will push current out and next time we come here previous next is current.
       next next: If two frame starts are found then we want it to be next next workload, which is what next will be
                  when we get called next time.
    */
    pend->using_next = (!cxt->pending_tags.frame_done && (cxt->frame_start_found == 1)) || (cxt->frame_start_found > 1);
    return ret;
}

/*
  Tag association for vc1:
  Frame header represents start of new frame. If we saw a frame start in current access unit and the buffer starts
  with start code it needs to go to current frame.  Rest of items go to next if frame start found else current frame.
 */
uint32_t viddec_generic_add_association_tags(void *parent)
{
    uint32_t ret = PM_SUCCESS;
    viddec_pm_cxt_t *cxt = (viddec_pm_cxt_t *)parent;
    viddec_pm_utils_list_t *list = &(cxt->list);
    uint32_t not_first_slice = false, index = 0;

    /* We check to see if this access unit is not the first one with frame start. This evaluates to true in that case */
    not_first_slice = cxt->frame_start_found && !cxt->found_fm_st_in_current_au;
    cxt->found_fm_st_in_current_au = false;
    if(list->start_offset == 0)
    {/* If start offset is 0, we have start code at beggining of buffer. If frame start was detected in this
        access unit we put the tag in current else it goes to next */
        viddec_emit_assoc_tag(&(cxt->emitter), list->sc_ibuf[index].id, not_first_slice);
    }
    /* Skip first item always, for start_offset=0 its already been handled above*/
    index++;
    while( (index < list->num_items) && (list->data[index].edpos <= (uint32_t)list->total_bytes))
    {/* Walkthrough Consumed buffers and dump the tags to current or next*/
        viddec_emit_assoc_tag(&(cxt->emitter), list->sc_ibuf[index].id, cxt->frame_start_found);
        index++;
    }
    if( (index < list->num_items) && (list->data[index].stpos < (uint32_t)list->total_bytes))
    {/* Dump last item if it was partially consumed */
        viddec_emit_assoc_tag(&(cxt->emitter), list->sc_ibuf[index].id, cxt->frame_start_found);
    }
    return ret;
}

/*
  This function throws tags for buffers which were not used yet during flush.
 */
void viddec_pm_generate_tags_for_unused_buffers_to_flush(viddec_pm_cxt_t *cxt)
{
    viddec_pm_utils_list_t *list;
    uint32_t index=0;

    list = &(cxt->list);
    /* Generate association tags from temporary pending array */
    viddec_pm_generate_missed_association_tags(cxt, false);
    if(list->num_items > 0)
    {
        /* Throw contribution flag for first item as done */
        viddec_emit_contr_tag(&(cxt->emitter), &(list->sc_ibuf[index]), false, false);
        if(cxt->list.start_offset == 0)
        {/* Throw association for first item if it was not done already */
            viddec_emit_assoc_tag(&(cxt->emitter), list->sc_ibuf[index].id, false);
        }
        index++;
        while(index < list->num_items)
        {/* Walk through list and throw contribution and association flags */
            viddec_emit_contr_tag(&(cxt->emitter), &(list->sc_ibuf[index]), false, false);
            viddec_emit_assoc_tag(&(cxt->emitter), list->sc_ibuf[index].id, false);
            index++;
        }
    }
    /* Not required to re init list structure as flush takes care of it */
}

