#include "viddec_fw_workload.h"
#include "viddec_parser_ops.h"
#include "viddec_fw_mp4.h"
#include "viddec_mp4_parse.h"
#include "viddec_types.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 = 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);

    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 = 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);

    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 = 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);

    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 = 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);
    }

    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 = 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);

    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 = VIDDEC_WORKLOAD_MP4_IQUANT;
        else
            wi.vwi_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);
    }

    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 = 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);

    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 = 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);

    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);

    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

