
#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 */
}

