#include <string.h>

#include "viddec_fw_workload.h"
#include "viddec_parser_ops.h"
#include "viddec_fw_mp4.h"
#include "viddec_mp4_parse.h"

uint32_t viddec_fw_mp4_populate_attr(viddec_workload_t *wl, viddec_mp4_parser_t *parser)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_frame_attributes_t *attr = &(wl->attrs);
    mp4_VideoObjectLayer_t *vol = &(parser->info.VisualObject.VideoObject);

    memset(attr, 0, sizeof(viddec_frame_attributes_t));

    attr->cont_size.width = vol->video_object_layer_width;
    attr->cont_size.height = vol->video_object_layer_height;
 
    // Translate vop_coding_type
    switch(vol->VideoObjectPlane.vop_coding_type)
    {
        case MP4_VOP_TYPE_B:
            attr->frame_type = VIDDEC_FRAME_TYPE_B;
            break;
        case MP4_VOP_TYPE_P:
            attr->frame_type = VIDDEC_FRAME_TYPE_P;
            break;
        case MP4_VOP_TYPE_S:
            attr->frame_type = VIDDEC_FRAME_TYPE_S;
            break;
        case MP4_VOP_TYPE_I:
            attr->frame_type = VIDDEC_FRAME_TYPE_I;
            break;
        default:
            break;
    } // switch on vop_coding_type

    attr->mpeg4.top_field_first = vol->VideoObjectPlane.top_field_first;

    return result;
} // viddec_fw_mp4_populate_attr

uint32_t viddec_fw_mp4_insert_vol_workitem(void *parent, viddec_mp4_parser_t *parser)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_workload_item_t wi;
    viddec_fw_mp4_vol_info_t vol_info;
    mp4_VideoObjectLayer_t *vol = &(parser->info.VisualObject.VideoObject);

    memset(&vol_info, 0, sizeof(viddec_fw_mp4_vol_info_t));

    // Get vol_flags
    viddec_fw_mp4_set_reversible_vlc(&vol_info, vol->reversible_vlc);
    viddec_fw_mp4_set_data_partitioned(&vol_info, vol->data_partitioned);
    viddec_fw_mp4_set_resync_marker_disable(&vol_info, vol->resync_marker_disable);
    viddec_fw_mp4_set_quarter_sample(&vol_info, vol->quarter_sample);
    viddec_fw_mp4_set_obmc_disable(&vol_info, vol->obmc_disable);
    viddec_fw_mp4_set_interlaced(&vol_info, vol->interlaced);
    viddec_fw_mp4_set_vol_shape(&vol_info, vol->video_object_layer_shape);
    viddec_fw_mp4_set_short_video_header_flag(&vol_info, vol->short_video_header);

    // Get vol_size
    viddec_fw_mp4_set_vol_width(&vol_info, vol->video_object_layer_width);
    viddec_fw_mp4_set_vol_height(&vol_info, vol->video_object_layer_height);

    // Get vol_item
    viddec_fw_mp4_set_quant_type(&vol_info, vol->quant_type);
    viddec_fw_mp4_set_quant_precision(&vol_info, vol->quant_precision);
    viddec_fw_mp4_set_sprite_warping_accuracy(&vol_info, vol->sprite_info.sprite_warping_accuracy);
    viddec_fw_mp4_set_sprite_warping_points(&vol_info, vol->sprite_info.no_of_sprite_warping_points);
    viddec_fw_mp4_set_sprite_enable(&vol_info, vol->sprite_enable);
    viddec_fw_mp4_set_vop_time_increment_resolution(&vol_info, vol->vop_time_increment_resolution);


    wi.vwi_type = (workload_item_type)VIDDEC_WORKLOAD_MP4_VOL_INFO;
    wi.vwi_payload[0] = vol_info.vol_flags;
    wi.vwi_payload[1] = vol_info.vol_size;
    wi.vwi_payload[2] = vol_info.vol_item;

    result = viddec_pm_append_workitem(parent, &wi, false);

    return result;
} // viddec_fw_mp4_insert_vol_workitem

uint32_t viddec_fw_mp4_insert_vop_workitem(void *parent, viddec_mp4_parser_t *parser)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_workload_item_t wi;
    viddec_fw_mp4_vop_info_t vop_info;
    mp4_VideoObjectPlane_t *vop = &(parser->info.VisualObject.VideoObject.VideoObjectPlane);
    uint32_t byte = 0;
    unsigned char is_emul;

    memset(&vop_info, 0, sizeof(viddec_fw_mp4_vop_info_t));

    // Get frame_info
    viddec_fw_mp4_set_past_field_frame(&vop_info, parser->ref_frame[VIDDEC_MP4_INDX_2].is_field);
    viddec_fw_mp4_set_past_frame_id(&vop_info, VIDDEC_MP4_FRAME_PAST);
    viddec_fw_mp4_set_future_field_frame(&vop_info, parser->ref_frame[VIDDEC_MP4_INDX_1].is_field);
    viddec_fw_mp4_set_future_frame_id(&vop_info, VIDDEC_MP4_FRAME_FUTURE);
    viddec_fw_mp4_set_current_field_frame(&vop_info, parser->ref_frame[VIDDEC_MP4_INDX_0].is_field);
    viddec_fw_mp4_set_current_frame_id(&vop_info, VIDDEC_MP4_FRAME_CURRENT);

    // HW has a limitation that the enums for PAST(1), FUTURE(2) and CURRENT(0) cannot be changed and
    // the spec does not support field pictures. Hence the field_frame bits are always zero.
    // This gives us the constant 0x10200.
    vop_info.frame_info = 0x10200;

    // Get vop_data
    // Quant scale is in the video_packet_header or the gob_layer - both of which are parsed by the BSP
    viddec_fw_mp4_set_vop_quant_scale(&vop_info, 0);
    viddec_fw_mp4_set_vop_fcode_backward(&vop_info, vop->vop_fcode_backward);
    viddec_fw_mp4_set_vop_fcode_forward(&vop_info, vop->vop_fcode_forward);
    viddec_fw_mp4_set_vop_quant(&vop_info, vop->vop_quant);
    viddec_fw_mp4_set_alternate_vertical_scan_flag(&vop_info, vop->alternate_vertical_scan_flag);
    viddec_fw_mp4_set_top_field_first(&vop_info, vop->top_field_first);
    viddec_fw_mp4_set_intra_dc_vlc_thr(&vop_info, vop->intra_dc_vlc_thr);
    viddec_fw_mp4_set_vop_rounding_type(&vop_info, vop->vop_rounding_type);
    viddec_fw_mp4_set_vop_coding_type(&vop_info, vop->vop_coding_type);

    // Get vol_item
    result = viddec_pm_get_au_pos(parent, &vop_info.bit_offset, &byte, &is_emul);

    wi.vwi_type = (workload_item_type)VIDDEC_WORKLOAD_MP4_VOP_INFO;
    wi.vwi_payload[0] = vop_info.frame_info;
    wi.vwi_payload[1] = vop_info.vop_data;
    wi.vwi_payload[2] = vop_info.bit_offset;

    result = viddec_pm_append_workitem(parent, &wi, false);

    return result;
} // viddec_fw_mp4_insert_vop_workitem

uint32_t viddec_fw_mp4_insert_vpsh_workitem(void *parent, viddec_mp4_parser_t *parser)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_workload_item_t wi;
    viddec_fw_mp4_svh_t svh_info;
    mp4_VideoObjectPlaneH263 *svh = &(parser->info.VisualObject.VideoObject.VideoObjectPlaneH263);

    memset(&svh_info, 0, sizeof(viddec_fw_mp4_svh_t));

    // Get svh_data
    viddec_fw_mp4_set_temporal_reference(&svh_info, svh->temporal_reference);
    viddec_fw_mp4_set_num_macroblocks_in_gob(&svh_info, svh->num_macroblocks_in_gob);
    viddec_fw_mp4_set_num_gobs_in_vop(&svh_info, svh->num_gobs_in_vop);
    viddec_fw_mp4_set_num_rows_in_gob(&svh_info, svh->num_rows_in_gob);

    wi.vwi_type = (workload_item_type)VIDDEC_WORKLOAD_MP4_SVH;
    wi.vwi_payload[0] = svh_info.svh_data;
    wi.vwi_payload[1] = svh_info.pad1;
    wi.vwi_payload[2] = svh_info.pad2;

    result = viddec_pm_append_workitem(parent, &wi, false);

    return result;
} // viddec_fw_mp4_insert_vpsh_workitem

uint32_t viddec_fw_mp4_insert_sprite_workitem(void *parent, viddec_mp4_parser_t *parser)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_workload_item_t wi;
    viddec_fw_mp4_sprite_trajectory_t sprite_info;
    mp4_VideoObjectLayer_t *vol = &(parser->info.VisualObject.VideoObject);
    mp4_VideoObjectPlane_t *vop = &(parser->info.VisualObject.VideoObject.VideoObjectPlane);
    uint8_t no_of_entries_per_item = 3;
    uint8_t no_of_sprite_workitems = 0;
    uint8_t warp_index = 0;
    int i, j;

    if(!vol->sprite_info.no_of_sprite_warping_points)
        return result;

    no_of_sprite_workitems = (vol->sprite_info.no_of_sprite_warping_points > 3) ? 2 : 1;

    for(i=0; i<no_of_sprite_workitems; i++)
    {
        memset(&sprite_info, 0, sizeof(viddec_fw_mp4_sprite_trajectory_t));
    
        for(j=0; j<no_of_entries_per_item; j++)
        {
            if(warp_index < vol->sprite_info.no_of_sprite_warping_points)
            {
                viddec_fw_mp4_set_warping_point_index(sprite_info.warping_mv_code[j], warp_index);
                viddec_fw_mp4_set_warping_mv_code_du(sprite_info.warping_mv_code[j], vop->warping_mv_code_du[warp_index]);
                viddec_fw_mp4_set_warping_mv_code_dv(sprite_info.warping_mv_code[j], vop->warping_mv_code_dv[warp_index]);
            }
            else
            {
               sprite_info.warping_mv_code[j] = 0xF << 28;
            }
            warp_index++;
        }

        wi.vwi_type = (workload_item_type)VIDDEC_WORKLOAD_MP4_SPRT_TRAJ;
        wi.vwi_payload[0] = sprite_info.warping_mv_code[0];
        wi.vwi_payload[1] = sprite_info.warping_mv_code[1];
        wi.vwi_payload[2] = sprite_info.warping_mv_code[2];

        result = viddec_pm_append_workitem(parent, &wi, false);
    }

    return result;
} // viddec_fw_mp4_insert_sprite_workitem

uint32_t viddec_fw_mp4_insert_bvop_workitem(void *parent, viddec_mp4_parser_t *parser)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_workload_item_t wi;
    mp4_VideoObjectLayer_t *vol = &(parser->info.VisualObject.VideoObject);

    wi.vwi_type = (workload_item_type)VIDDEC_WORKLOAD_MP4_BVOP_INFO;
    wi.vwi_payload[0] = vol->Tframe;
    wi.vwi_payload[1] = vol->TRD;
    wi.vwi_payload[2] = vol->TRB;

    result = viddec_pm_append_workitem(parent, &wi, false);

    return result;
} // viddec_fw_mp4_insert_bvop_workitem

uint32_t viddec_fw_mp4_insert_qmat(void *parent, uint8_t intra_quant_flag, uint32_t *qmat)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_workload_item_t wi;
    uint8_t i;

    // No of items = (64/4 Dwords / 3 entries per workload item)
    // 64 8b entries => 64 * 8 / 32 DWORDS => 64/4 DWORDS => 16 DWORDS
    // Each item can store 3 DWORDS, 16 DWORDS => 16/3 items => 6 items
    for(i=0; i<6; i++)
    {
        memset(&wi, 0, sizeof(viddec_workload_item_t));

        if(intra_quant_flag)
            wi.vwi_type = (workload_item_type)VIDDEC_WORKLOAD_MP4_IQUANT;
        else
            wi.vwi_type = (workload_item_type)VIDDEC_WORKLOAD_MP4_NIQUANT;

        if(i == 6)
        {
            wi.vwi_payload[0] = qmat[0];
            wi.vwi_payload[1] = 0;
            wi.vwi_payload[2] = 0;
        }
        else
        {
            wi.vwi_payload[0] = qmat[0];
            wi.vwi_payload[1] = qmat[1];
            wi.vwi_payload[2] = qmat[2];
        }

        qmat += 3;

        result = viddec_pm_append_workitem(parent, &wi, false);
    }

    return result;
} // viddec_fw_mp4_insert_qmat

uint32_t viddec_fw_mp4_insert_inversequant_workitem(void *parent, mp4_VOLQuant_mat_t *qmat)
{
    uint32_t result = MP4_STATUS_OK;

    if(qmat->load_intra_quant_mat)
    {
        result = viddec_fw_mp4_insert_qmat(parent, true, (uint32_t *) &(qmat->intra_quant_mat));
    }

    if(qmat->load_nonintra_quant_mat)
    {
        result = viddec_fw_mp4_insert_qmat(parent, false, (uint32_t *) &(qmat->nonintra_quant_mat));
    }

    return result;
} // viddec_fw_mp4_insert_inversequant_workitem

uint32_t viddec_fw_mp4_insert_past_frame_workitem(void *parent)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_workload_item_t wi;

    wi.vwi_type = (workload_item_type)VIDDEC_WORKLOAD_MP4_PAST_FRAME;
    wi.ref_frame.reference_id = 0;
    wi.ref_frame.luma_phys_addr = 0;
    wi.ref_frame.chroma_phys_addr = 0;
    result = viddec_pm_append_workitem(parent, &wi, false);

    return result;
} // viddec_fw_mp4_insert_past_frame_workitem

uint32_t viddec_fw_mp4_insert_future_frame_workitem(void *parent)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_workload_item_t wi;

    wi.vwi_type = (workload_item_type)VIDDEC_WORKLOAD_MP4_FUTURE_FRAME;
    wi.ref_frame.reference_id = 0;
    wi.ref_frame.luma_phys_addr = 0;
    wi.ref_frame.chroma_phys_addr = 0;
    result = viddec_pm_append_workitem(parent, &wi, false);

    return result;
} // viddec_fw_mp4_insert_future_frame_workitem

uint32_t viddec_fw_mp4_insert_reorder_workitem(void *parent)
{
    uint32_t result = MP4_STATUS_OK;
    viddec_workload_item_t wi;

    // Move frame at location 1 of the reference table to location 0
    wi.vwi_type = VIDDEC_WORKLOAD_REFERENCE_FRAME_REORDER;
    wi.ref_reorder.ref_table_offset = 0;
    wi.ref_reorder.ref_reorder_00010203 = 0x01010203;
    wi.ref_reorder.ref_reorder_04050607 = 0x04050607;

    result = viddec_pm_append_workitem(parent, &wi, false);

    return result;
} // viddec_fw_mp4_insert_reorder_workitem

uint32_t viddec_fw_mp4_emit_workload(void *parent, void *ctxt)
{
    uint32_t result = 0;
    viddec_mp4_parser_t *parser = (viddec_mp4_parser_t *) ctxt;
    viddec_workload_t *wl = viddec_pm_get_header(parent);

    result = viddec_fw_mp4_populate_attr(wl, parser);
    result = viddec_fw_mp4_insert_vol_workitem(parent, parser);
    result = viddec_fw_mp4_insert_vop_workitem(parent, parser);
    result = viddec_fw_mp4_insert_sprite_workitem(parent, parser);
    result = viddec_fw_mp4_insert_inversequant_workitem(parent, &(parser->info.VisualObject.VideoObject.quant_mat_info));

    if(parser->info.VisualObject.VideoObject.short_video_header)
      result = viddec_fw_mp4_insert_vpsh_workitem(parent, parser);

    if(!parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_coded)
        wl->is_reference_frame |= WORKLOAD_SKIPPED_FRAME;
    
    // Send reference re-order tag for all reference frame types
    if (parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_coding_type != MP4_VOP_TYPE_B)
    {
        result = viddec_fw_mp4_insert_reorder_workitem(parent);
    }
    
    // Handle vop_coding_type based information
    switch(parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_coding_type)
    {
        case MP4_VOP_TYPE_B:
            result = viddec_fw_mp4_insert_bvop_workitem(parent, parser);
            result = viddec_fw_mp4_insert_past_frame_workitem(parent);
            result = viddec_fw_mp4_insert_future_frame_workitem(parent);
            break;
        case MP4_VOP_TYPE_P:
        case MP4_VOP_TYPE_S:
            result = viddec_fw_mp4_insert_past_frame_workitem(parent);
            // Deliberate fall-thru to type I
        case MP4_VOP_TYPE_I:
            wl->is_reference_frame |= WORKLOAD_REFERENCE_FRAME | (1 & WORKLOAD_REFERENCE_FRAME_BMASK);
            // Swap reference information
            parser->ref_frame[VIDDEC_MP4_INDX_2] = parser->ref_frame[VIDDEC_MP4_INDX_1];
            parser->ref_frame[VIDDEC_MP4_INDX_1] = parser->ref_frame[VIDDEC_MP4_INDX_0];
            break;
            break;
        default:
            break;
    } // switch on vop_coding_type

    result = viddec_pm_append_pixeldata(parent);

    return result;
} // viddec_fw_mp4_emit_workload

