#include <string.h>

#include "viddec_fw_debug.h"
#include "viddec_parser_ops.h"
#include "viddec_mp4_parse.h"
#include "viddec_mp4_decodevideoobjectplane.h"
#include "viddec_mp4_shortheader.h"
#include "viddec_mp4_videoobjectlayer.h"
#include "viddec_mp4_videoobjectplane.h"
#include "viddec_mp4_visualobject.h"

extern uint32_t viddec_parse_sc_mp4(void *in, void *pcxt, void *sc_state);

void viddec_mp4_get_context_size(viddec_parser_memory_sizes_t *size)
{
    /* Should return size of my structure */
    size->context_size = sizeof(viddec_mp4_parser_t);
    size->persist_size = 0;
    return;
} // viddec_mp4_get_context_size

uint32_t viddec_mp4_wkld_done(void *parent, void *ctxt, uint32_t next_sc, uint32_t *codec_specific_errors)
{
    viddec_mp4_parser_t *parser = (viddec_mp4_parser_t *) ctxt;
    int result = VIDDEC_PARSE_SUCESS;
    uint8_t frame_boundary = false;
    uint8_t emit_workload = false;

    //DEB("entering is_wkld_done: next_sc: 0x%x, sc_seen: %d\n", next_sc, parser->sc_seen);

    parent = parent;

    // VS, VO, VOL, VOP or GVOP start codes indicate frame boundary.
    frame_boundary = (  (MP4_SC_VISUAL_OBJECT_SEQUENCE == next_sc) || 
                        (MP4_SC_VISUAL_OBJECT == next_sc) || 
                        ((MP4_SC_VIDEO_OBJECT_LAYER_MIN <= next_sc) && (next_sc <= MP4_SC_VIDEO_OBJECT_LAYER_MAX)) || 
                        (next_sc <= MP4_SC_VIDEO_OBJECT_MAX) ||
                        (MP4_SC_VIDEO_OBJECT_PLANE == next_sc) || 
                        ((SHORT_THIRD_STARTCODE_BYTE & 0xFC) == (next_sc & 0xFC)) || 
                        (MP4_SC_GROUP_OF_VOP == next_sc)    );

    // Mark workload is ready to be emitted based on the start codes seen.
    if (frame_boundary)
    {
        uint8_t vol_error_found = false, frame_complete = false;
        
        // Frame is considered complete and without errors, if a VOL was received since startup and
        // if a VOP was received for this workload (or) if short video header is found.
        frame_complete = ( ((parser->sc_seen & MP4_SC_SEEN_VOL) && (parser->sc_seen & MP4_SC_SEEN_VOP)) ||
                           (parser->sc_seen & MP4_SC_SEEN_SVH) );

        // For non SVH case, the video object layer data should be followed by video object plane data
        // If not, error occurred and we need to throw the current workload as error.
        vol_error_found = ( (parser->prev_sc == MP4_SC_VIDEO_OBJECT_LAYER_MIN) &&
                            !(MP4_SC_VIDEO_OBJECT_PLANE == next_sc) );
        
        emit_workload = (frame_complete || vol_error_found);

        //DEB("emit workload: frame_complete: %d, vol_error_found %d\n", frame_complete, vol_error_found);
    }

    // EOS and discontinuity should force workload completion.
    emit_workload |= ((VIDDEC_PARSE_EOS == next_sc) || (VIDDEC_PARSE_DISCONTINUITY == next_sc));

    if(emit_workload)
    {
        *codec_specific_errors = 0;

        // If the frame is not complete but we have received force frame complete because of EOS or
        // discontinuity, we mark the workload as not decodeable.
        if (!((parser->sc_seen & MP4_SC_SEEN_VOL) && (parser->sc_seen & MP4_SC_SEEN_VOP)) && !(parser->sc_seen & MP4_SC_SEEN_SVH))
            *codec_specific_errors |= VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE;

        /*
        This is the strategy for error detection.
        Errors in any field needed by the firmware (parser/decoder) are treated as non-decodable. 
        Errors in other fields will be considered decodable.
        Defaults/alternate strategies will be considered on a case-by-case basis as customer content is seen.

        ERROR_TYPE      |       PARSING         |   INVALID/UNSUPPORTED |       BS = Bitstream error
        -----------------------------------------------------------------       UNSUP = Un-supported
        DFLT_PRESENT    |       YES |   NO      |       YES |   NO      |       ND = Non-decodable
        COMPONENT USED  |           |           |           |           |       DFLT = Populate defaults
        -----------------------------------------------------------------
        FIRMWARE        | BS+ND     | BS+ND     | UNSUP+ND  | UNSUP+ND  |
        DRIVER/USER     | BS+DFLT   | BS        | UNSUP     | UNSUP     |
        NONE            | BS        | BS        | UNSUP     | UNSUP     | 
                        |           |           | Continue Parsing      |
        */ 
        if((parser->bitstream_error & MP4_BS_ERROR_HDR_NONDEC) || (parser->bitstream_error & MP4_BS_ERROR_FRM_NONDEC))
            *codec_specific_errors |= (VIDDEC_FW_WORKLOAD_ERR_NOTDECODABLE | VIDDEC_FW_WORKLOAD_ERR_MISSING_DMEM);

        if((parser->bitstream_error & MP4_BS_ERROR_HDR_UNSUP) || (parser->bitstream_error & MP4_BS_ERROR_FRM_UNSUP))
            *codec_specific_errors |= VIDDEC_FW_WORKLOAD_ERR_UNSUPPORTED;

        if((parser->bitstream_error & MP4_BS_ERROR_HDR_PARSE) || (parser->bitstream_error & MP4_BS_ERROR_FRM_PARSE))
            *codec_specific_errors |= VIDDEC_FW_WORKLOAD_ERR_BITSTREAM_ERROR;
            
        parser->bitstream_error &= MP4_HDR_ERROR_MASK;
        parser->sc_seen &= MP4_SC_SEEN_VOL;
        result = VIDDEC_PARSE_FRMDONE;
    }
    //DEB("exiting is_wkld_done: next_sc: 0x%x, sc_seen: %d, err: %d, fr_bnd:%d, force:%d\n", 
    //        next_sc, parser->sc_seen, *codec_specific_errors, frame_boundary, force_frame_complete);

    return result;
} // viddec_mp4_wkld_done

void viddec_mp4_init(void *ctxt, uint32_t *persist_mem, uint32_t preserve)
{
    viddec_mp4_parser_t *parser = (viddec_mp4_parser_t *) ctxt;

    persist_mem = persist_mem;
    parser->is_frame_start = false;
    parser->prev_sc = MP4_SC_INVALID;
    parser->current_sc = MP4_SC_INVALID;
    parser->cur_sc_prefix = false;
    parser->next_sc_prefix = false;
    parser->ignore_scs = false;

    if(preserve)
    {
        // Need to maintain information till VOL
        parser->sc_seen &= MP4_SC_SEEN_VOL;
        parser->bitstream_error &= MP4_HDR_ERROR_MASK;

        // Reset only frame related data
        memset(&(parser->info.VisualObject.VideoObject.VideoObjectPlane), 0, sizeof(mp4_VideoObjectPlane_t)); 
        memset(&(parser->info.VisualObject.VideoObject.VideoObjectPlaneH263), 0, sizeof(mp4_VideoObjectPlaneH263)); 
    }
    else
    {
        parser->sc_seen = MP4_SC_SEEN_INVALID;
        parser->bitstream_error = MP4_BS_ERROR_NONE;
        memset(&(parser->info), 0, sizeof(mp4_Info_t)); 
    }

    return;
} // viddec_mp4_init

static uint32_t viddec_mp4_decodevop_and_emitwkld(void *parent, void *ctxt)
{
    int status = MP4_STATUS_OK;
    viddec_mp4_parser_t *cxt = (viddec_mp4_parser_t *)ctxt;
 
    status = mp4_DecodeVideoObjectPlane(&(cxt->info));

#ifndef VBP
    status = viddec_fw_mp4_emit_workload(parent, ctxt);
#endif

    return status;
} // viddec_mp4_decodevop_and_emitwkld

uint32_t viddec_mp4_parse(void *parent, void *ctxt)
{
    uint32_t sc=0;
    viddec_mp4_parser_t *cxt;
    uint8_t is_svh=0;
    int32_t getbits=0;
    int32_t status = 0;
    
    cxt = (viddec_mp4_parser_t *)ctxt;
    is_svh = (cxt->cur_sc_prefix) ? false: true;
    if((getbits = viddec_pm_peek_bits(parent, &sc, 32)) == -1)
    {
        DEB("Start code not found\n");
        return VIDDEC_PARSE_ERROR;
    }
    
    if(!is_svh)
    {
        viddec_pm_get_bits(parent, &sc, 32);
        sc = sc & 0xFF;
        cxt->current_sc = sc;
        cxt->current_sc |= 0x100;
        DEB("current_sc=0x%.8X, prev_sc=0x%x\n", sc, cxt->prev_sc);

        switch(sc)
        {
            case MP4_SC_VISUAL_OBJECT_SEQUENCE:
            {
                status = mp4_Parse_VisualSequence(parent, cxt);
                cxt->prev_sc = MP4_SC_VISUAL_OBJECT_SEQUENCE;
                DEB("MP4_VISUAL_OBJECT_SEQUENCE_SC: \n");
                break;
            }
            case MP4_SC_VISUAL_OBJECT_SEQUENCE_EC:
            {/* Not required to do anything */
                break;
            }
            case MP4_SC_USER_DATA:
            {   /* Copy userdata to user-visible buffer (EMIT) */
                status = mp4_Parse_UserData(parent, cxt);
                DEB("MP4_USER_DATA_SC: \n");
                break;
            }
            case MP4_SC_GROUP_OF_VOP:
            {
                status = mp4_Parse_GroupOfVideoObjectPlane(parent, cxt);
                cxt->prev_sc = MP4_SC_GROUP_OF_VOP;
                DEB("MP4_GROUP_OF_VOP_SC:0x%.8X\n", status);
                break;
            }
            case MP4_SC_VIDEO_SESSION_ERROR:
            {/* Not required to do anything?? */
                break;
            }
            case MP4_SC_VISUAL_OBJECT:
            {
                status = mp4_Parse_VisualObject(parent, cxt);
                cxt->prev_sc = MP4_SC_VISUAL_OBJECT;
                DEB("MP4_VISUAL_OBJECT_SC: status=%.8X\n", status);
                break;
            }
            case MP4_SC_VIDEO_OBJECT_PLANE:
            {
                /* We must decode the VOP Header information, it does not end  on a byte boundary, so we need to emit
                   a starting bit offset after parsing the header. */
                status = mp4_Parse_VideoObjectPlane(parent, cxt);
                status = viddec_mp4_decodevop_and_emitwkld(parent, cxt);
                // TODO: Fix this for interlaced
                cxt->is_frame_start = true;
                cxt->sc_seen |= MP4_SC_SEEN_VOP;

                DEB("MP4_VIDEO_OBJECT_PLANE_SC: status=0x%.8X\n", status);
                break;
            }
            case MP4_SC_STUFFING:
            {
                break;
            }            
            default:
            {
                if( (sc >=  MP4_SC_VIDEO_OBJECT_LAYER_MIN) && (sc <=  MP4_SC_VIDEO_OBJECT_LAYER_MAX) )
                {
                    status = mp4_Parse_VideoObjectLayer(parent, cxt);
                    cxt->sc_seen = MP4_SC_SEEN_VOL;
                    cxt->prev_sc = MP4_SC_VIDEO_OBJECT_LAYER_MIN;
                    DEB("MP4_VIDEO_OBJECT_LAYER_MIN_SC:status=0x%.8X\n", status);
                    sc = MP4_SC_VIDEO_OBJECT_LAYER_MIN;
                }
                // sc is unsigned and will be >= 0, so no check needed for sc >= MP4_SC_VIDEO_OBJECT_MIN
                else if(sc <= MP4_SC_VIDEO_OBJECT_MAX)
                {
                     // If there is more data, it is short video header, else the next start code is expected to be VideoObjectLayer
                     getbits = viddec_pm_get_bits(parent, &sc, 22);
                     if(getbits != -1)
                     {
                        cxt->current_sc = sc;
                        status = mp4_Parse_VideoObject_svh(parent, cxt);
                        status = viddec_mp4_decodevop_and_emitwkld(parent, cxt);
                        cxt->sc_seen = MP4_SC_SEEN_SVH;
                        cxt->is_frame_start = true;
                        DEB("MP4_SCS_SVH: status=0x%.8X 0x%.8X %.8X\n", status, cxt->current_sc, sc);
                        DEB("MP4_VIDEO_OBJECT_MIN_SC:status=0x%.8X\n", status);
                     }
                }
                else
                {
                    DEB("UNKWON Cod:0x%08X\n", sc);
                }
            }
            break;
        }
    }
    else
    {
        viddec_pm_get_bits(parent, &sc, 22);
        cxt->current_sc = sc;
        DEB("current_sc=0x%.8X, prev_sc=0x%x\n", sc, cxt->prev_sc);
        status = mp4_Parse_VideoObject_svh(parent, cxt);
        status = viddec_mp4_decodevop_and_emitwkld(parent, cxt);
        cxt->sc_seen = MP4_SC_SEEN_SVH;
        cxt->is_frame_start = true;
        DEB("SVH: MP4_SCS_SVH: status=0x%.8X 0x%.8X %.8X\n", status, cxt->current_sc, sc);
    }

    // Current sc becomes the previous sc
    cxt->prev_sc = sc;

    return VIDDEC_PARSE_SUCESS;
} // viddec_mp4_parse

uint32_t viddec_mp4_is_frame_start(void *ctxt)
{
    viddec_mp4_parser_t *parser = (viddec_mp4_parser_t *)ctxt;
    return parser->is_frame_start;
} // viddec_mp4_is_frame_start

void viddec_mp4_get_ops(viddec_parser_ops_t *ops)
{
    ops->parse_syntax = viddec_mp4_parse;
    ops->get_cxt_size = viddec_mp4_get_context_size;
    ops->is_wkld_done = viddec_mp4_wkld_done;
    ops->parse_sc = viddec_parse_sc_mp4;
    ops->is_frame_start = viddec_mp4_is_frame_start;
    ops->init = viddec_mp4_init;
    return;
} // viddec_mp4_get_ops
