#include "viddec_mp4_videoobjectlayer.h"
#ifdef ANDROID
#include "viddec_types.h"
#endif

const unsigned char mp4_DefaultIntraQuantMatrix[64] = {
    8, 17, 18, 19, 21, 23, 25, 27, 
    17, 18, 19, 21, 23, 25, 27, 28,
    20, 21, 22, 23, 24, 26, 28, 30, 
    21, 22, 23, 24, 26, 28, 30, 32,
    22, 23, 24, 26, 28, 30, 32, 35, 
    23, 24, 26, 28, 30, 32, 35, 38,
    25, 26, 28, 30, 32, 35, 38, 41, 
    27, 28, 30, 32, 35, 38, 41, 45
};
const unsigned char mp4_DefaultNonIntraQuantMatrix[64] = {
    16, 17, 18, 19, 20, 21, 22, 23, 
    17, 18, 19, 20, 21, 22, 23, 24,
    18, 19, 20, 21, 22, 23, 24, 25, 
    19, 20, 21, 22, 23, 24, 26, 27,
    20, 21, 22, 23, 25, 26, 27, 28, 
    21, 22, 23, 24, 26, 27, 28, 30,
    22, 23, 24, 26, 27, 28, 30, 31, 
    23, 24, 25, 27, 28, 30, 31, 33
};
const unsigned char mp4_ClassicalZigzag[64] = {
    0,   1,  8, 16,  9,  2,  3, 10, 17, 24, 32, 25, 18, 11,  4,  5,
    12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13,  6,  7, 14, 21, 28,
    35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
    58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
};

static inline int mp4_GetMacroBlockNumberSize(int nmb)
{
    int  nb = 0;
    nmb --;
    do {
        nmb >>= 1;
        nb ++;
    } while (nmb);
    return nb;
}

static inline void mp4_copy_default_table(const uint8_t *src, uint8_t *dst, uint32_t len)
{
    uint32_t i;
    for(i=0; i< len; i++)
        dst[i] = src[i];
}


static inline mp4_Status_t mp4_Parse_QuantMatrix(void *parent, uint8_t *pQM)
{
    uint32_t i,code=0;
    uint8_t last=0;
    int32_t                 getbits=0;
    mp4_Status_t            ret = MP4_STATUS_OK;

    for (i = 0; i < 64; i ++)
    {
        getbits = viddec_pm_get_bits(parent, &code, 8);
        BREAK_GETBITS_REQD_MISSING(getbits, ret);
        if (code == 0) break;
        pQM[mp4_ClassicalZigzag[i]] = (uint8_t)(code & 0xFF);
    }
    last = pQM[mp4_ClassicalZigzag[i-1]];
    for (; i < 64; i ++)
    {
        pQM[mp4_ClassicalZigzag[i]] = last;
    } 
    return ret;;
}

static inline uint8_t mp4_pvt_valid_object_type_indication(uint8_t val)
{
    return ((1 <= val) || (val <= 18));
}

static inline uint8_t mp4_pvt_valid_object_layer_verid(uint8_t val)
{
    uint8_t ret=false;
    switch(val)
    {
        case 1:
        case 2:
        case 4:
        case 5:
        {
            ret = true;
            break;
        }
        default:
        {
            break;
        }
    }
    return ret;
}

static mp4_Status_t
mp4_pvt_VOL_volcontrolparameters(void *parent, viddec_mp4_parser_t *parser)
{
    mp4_VOLControlParameters_t *cxt = &(parser->info.VisualObject.VideoObject.VOLControlParameters);
    mp4_Status_t            ret = MP4_STATUS_PARSE_ERROR;
    int32_t                 getbits=0;
    uint32_t                code=0;

    do 
    {
        getbits = viddec_pm_get_bits(parent, &(code), 4);
        BREAK_GETBITS_REQD_MISSING(getbits, ret);
        cxt->chroma_format = (code >> 2) & 0x3;
        cxt->low_delay = ((code & 0x2) > 0);
        cxt->vbv_parameters = code & 0x1;

        if (cxt->chroma_format != MP4_CHROMA_FORMAT_420)
        {
            DEB("Warning: mp4_Parse_VideoObject:vol_control_parameters.chroma_format != 4:2:0\n");
            cxt->chroma_format= MP4_CHROMA_FORMAT_420;
            parser->bitstream_error |= MP4_BS_ERROR_HDR_UNSUP;
            ret = MP4_STATUS_NOTSUPPORT;
        }
        
        if(cxt->vbv_parameters)
        {/* TODO: Check for validity of marker bits */
            getbits = viddec_pm_get_bits(parent, &(code), 32);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            /* 32 bits= firsthalf(15) + M + LatterHalf(15) + M */
            cxt->bit_rate = (code & 0xFFFE) >> 1; // Get rid of 1 marker bit
            cxt->bit_rate |= ((code & 0xFFFE0000) >> 2); // Get rid of 2 marker bits

            if(cxt->bit_rate == 0)
            {
                DEB("Error: mp4_Parse_VideoObject:vidObjLay->VOLControlParameters.bit_rate = 0\n");
                parser->bitstream_error |= MP4_BS_ERROR_HDR_UNSUP;
                ret = MP4_STATUS_NOTSUPPORT;
                // Do we need to really break here? Why not just set an error and proceed
                //break;
            }
            
            getbits = viddec_pm_get_bits(parent, &(code), 19);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            /* 19 bits= firsthalf(15) + M + LatterHalf(3)*/            
            cxt->vbv_buffer_size = code & 0x7;
            cxt->vbv_buffer_size |= ( (code >> 4) & 0x7FFF);
            if(cxt->vbv_buffer_size == 0)
            {
                DEB("Error: mp4_Parse_VideoObject:vidObjLay->VOLControlParameters.vbv_buffer_size = 0\n");
                parser->bitstream_error |= MP4_BS_ERROR_HDR_UNSUP;
                ret = MP4_STATUS_NOTSUPPORT;
                // Do we need to really break here? Why not just set an error and proceed
                //break;
            }
            
            getbits = viddec_pm_get_bits(parent, &(code), 28);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            /* 28 bits= firsthalf(11) + M + LatterHalf(15) + M */
            code = code >>1;
            cxt->vbv_occupancy = code & 0x7FFF;
            code = code >>16;
            cxt->vbv_occupancy |= (code & 0x07FF);
        }
        ret = MP4_STATUS_OK;
    } while(0);

    return ret;
}

static uint32_t mp4_pvt_count_number_of_bits(uint32_t val)
{
    uint32_t num_bits=0;
    do{
        val >>= 1;
        num_bits++;
    }while(val);
    return num_bits;
}

static mp4_Status_t
mp4_Parse_VOL_sprite(void *parent,  viddec_mp4_parser_t *parser)
{
    mp4_VideoObjectLayer_t  *vidObjLay = (&parser->info.VisualObject.VideoObject);
    mp4_VOLSpriteInfo_t     *cxt = &(vidObjLay->sprite_info);
    uint32_t                sprite_enable = vidObjLay->sprite_enable;
    uint32_t                code;
    mp4_Status_t            ret = MP4_STATUS_PARSE_ERROR;
    int32_t                 getbits=0;

    do{
        if ((sprite_enable == MP4_SPRITE_STATIC) ||
            (sprite_enable == MP4_SPRITE_GMC))
        {
            if (sprite_enable != MP4_SPRITE_GMC)
            {
                /* This is not a supported type by HW */
                DEB("ERROR: mp4_Parse_VideoObject:sprite_enable = %.2X\n", sprite_enable);
                ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                break;
            }

            getbits = viddec_pm_get_bits(parent, &(code), 9);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            cxt->sprite_brightness_change = code & 0x1;
            cxt->sprite_warping_accuracy = (code >> 1) & 0x3;
            cxt->no_of_sprite_warping_points = code >> 3;
            if(cxt->no_of_sprite_warping_points > 1)
            {
                DEB("Error: mp4_Parse_VideoObject:bad no_of_sprite_warping_points %d\n",
                    cxt->no_of_sprite_warping_points);
                ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                break;
            }

            if((vidObjLay->sprite_enable == MP4_SPRITE_GMC) && (cxt->sprite_brightness_change))
            {
                DEB("Error: mp4_Parse_VideoObject:sprite_brightness_change should be 0 for GMC sprites\n");
                ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                break;
            }

            if (vidObjLay->sprite_enable != MP4_SPRITE_GMC)
            {
                DEB("ERROR: mp4_Parse_VideoObject:sprite_enable = %.2X\n", sprite_enable);
                ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                break;
            }
        }
        ret = MP4_STATUS_OK;
    }while(0);

    return ret;
}

static mp4_Status_t mp4_Parse_VOL_quant_mat(void *parent, mp4_VideoObjectLayer_t  *vidObjLay)
{
    uint32_t                code;
    mp4_Status_t            ret = MP4_STATUS_PARSE_ERROR;
    int32_t                 getbits=0;
    mp4_VOLQuant_mat_t      *quant = &(vidObjLay->quant_mat_info);

    do{
        getbits = viddec_pm_get_bits(parent, &(code), 1);
        BREAK_GETBITS_REQD_MISSING(getbits, ret);
        quant->load_intra_quant_mat = code;
        if (quant->load_intra_quant_mat)
        {
            mp4_Parse_QuantMatrix(parent, &(quant->intra_quant_mat[0]));
        }
        else
        {
            mp4_copy_default_table((const uint8_t *)&mp4_DefaultIntraQuantMatrix[0], (uint8_t *)&(quant->intra_quant_mat[0]), 64);
        }
        
        getbits = viddec_pm_get_bits(parent, &(code), 1);
        BREAK_GETBITS_REQD_MISSING(getbits, ret);
        quant->load_nonintra_quant_mat = code;
        if (quant->load_nonintra_quant_mat)
        {
            mp4_Parse_QuantMatrix(parent, &(quant->nonintra_quant_mat[0]));
        }
        else
        {
            mp4_copy_default_table((const uint8_t *)&mp4_DefaultNonIntraQuantMatrix[0], (uint8_t *)&(quant->nonintra_quant_mat[0]), 64);
        }
        ret = MP4_STATUS_OK;
    }while(0);
    return ret;
}

static mp4_Status_t mp4_Parse_VOL_notbinaryonly(void *parent, viddec_mp4_parser_t *parser)
{
    uint32_t                code;
    mp4_Info_t              *pInfo = &(parser->info);
    mp4_VideoObjectLayer_t  *vidObjLay = &(pInfo->VisualObject.VideoObject);
    mp4_Status_t            ret = MP4_STATUS_PARSE_ERROR;
    int32_t                 getbits=0;

    do{
        if (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_RECTANGULAR)
        {
            /* TODO: check for validity of marker bits */
            getbits = viddec_pm_get_bits(parent, &(code), 29);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            vidObjLay->video_object_layer_height = (code >> 1) & 0x1FFF;
            vidObjLay->video_object_layer_width = (code >> 15) & 0x1FFF;
        }

        getbits = viddec_pm_get_bits(parent, &(code), 2);
        BREAK_GETBITS_REQD_MISSING(getbits, ret);
        vidObjLay->interlaced = ((code & 0x2) > 0);
        vidObjLay->obmc_disable = ((code & 0x1) > 0);

        {
            uint32_t num_bits=1;
            if(vidObjLay->video_object_layer_verid != 1) num_bits=2;
            getbits = viddec_pm_get_bits(parent, &(code), num_bits);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            vidObjLay->sprite_enable = code;
        }

        ret = mp4_Parse_VOL_sprite(parent, parser);
        if(ret != MP4_STATUS_OK)
        {
            break;
        }

        if ((vidObjLay->video_object_layer_verid != 1) &&
            (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_RECTANGULAR))
        {
            /*  not supported shape*/
            DEB("Error: mp4_Parse_VideoObject: sadct_disable, not supp\n");
            ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
            break;
        }

        getbits = viddec_pm_get_bits(parent, &(code), 1);
        BREAK_GETBITS_FAIL(getbits, ret);
        vidObjLay->not_8_bit = (code  > 0 );
        if(vidObjLay->not_8_bit)
        {
            /*  8 bit is only supported mode*/
            DEB("Error: mp4_Parse_VideoObject: not_8_bit, not supp\n");
            ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
            break;
        }
        else
        {/* We use default values since only 8 bit mode is supported */
            vidObjLay->quant_precision = 5;
            vidObjLay->bits_per_pixel = 8;
        }

        if (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_GRAYSCALE)
        {
            /* Should not get here as shape is checked earlier */
            DEB("Error: mp4_Parse_VideoObject: GRAYSCALE, not supp\n");
            ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
            break;
        }

        getbits = viddec_pm_get_bits(parent, &(code), 1);
        BREAK_GETBITS_REQD_MISSING(getbits, ret);
        vidObjLay->quant_type = code;
        if (vidObjLay->quant_type)
        {
            ret = mp4_Parse_VOL_quant_mat(parent, vidObjLay);
            if(ret != MP4_STATUS_OK)
            {
                break;
            }
        }

        if (vidObjLay->video_object_layer_verid != 1)
        {
            getbits = viddec_pm_get_bits(parent, &(code), 1);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            vidObjLay->quarter_sample = code;
        }
        
        getbits = viddec_pm_get_bits(parent, &(code), 1);
        BREAK_GETBITS_REQD_MISSING(getbits, ret);
        vidObjLay->complexity_estimation_disable = code;
        if(!vidObjLay->complexity_estimation_disable)
        {/*  complexity estimation not supported */
            DEB("Error: mp4_Parse_VideoObject: vidObjLay->complexity_estimation_disable, not supp\n");
            ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
            break;
        }

        getbits = viddec_pm_get_bits(parent, &(code), 2);
        BREAK_GETBITS_REQD_MISSING(getbits, ret);
        vidObjLay->resync_marker_disable = ((code & 0x2) > 0);
        vidObjLay->data_partitioned = code & 0x1;
        if(vidObjLay->data_partitioned)
        {
            getbits = viddec_pm_get_bits(parent, &(code), 1);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            vidObjLay->reversible_vlc = code;
        }
        
        if (vidObjLay->video_object_layer_verid != 1)
        {
            getbits = viddec_pm_get_bits(parent, &(code), 1);
            BREAK_GETBITS_FAIL(getbits, ret);
            vidObjLay->newpred_enable = code;
            if(vidObjLay->newpred_enable)
            {
                DEB("Error: NEWPRED mode is not supported\n");
                ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                break;
            }
            getbits = viddec_pm_get_bits(parent, &(code), 1);
            BREAK_GETBITS_FAIL(getbits, ret);
            vidObjLay->reduced_resolution_vop_enable = code;
        }

        getbits = viddec_pm_get_bits(parent, &(code), 1);
        BREAK_GETBITS_FAIL(getbits, ret);
        vidObjLay->scalability = code;
        if(vidObjLay->scalability)
        {
            DEB("Error: VOL scalability is not supported\n");
            ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
            break;
        }

        // No need to parse further - none of the fields are interesting to parser/decoder/user
        ret = MP4_STATUS_OK;
    }while(0);
    return ret;
}

mp4_Status_t mp4_Parse_VideoObjectLayer(void *parent, viddec_mp4_parser_t *parser)
{
    uint32_t                code;
    mp4_Info_t              *pInfo = &(parser->info);
    mp4_VisualObject_t      *visObj = &(pInfo->VisualObject);
    mp4_VideoObjectLayer_t  *vidObjLay = &(pInfo->VisualObject.VideoObject);
    mp4_Status_t            ret = MP4_STATUS_PARSE_ERROR;
    int32_t                 getbits=0; 

//DEB("entering mp4_Parse_VideoObjectLayer: bs_err: %d, ret: %d\n", parser->bitstream_error, ret);
    do{
        vidObjLay->VideoObjectPlane.sprite_transmit_mode = MP4_SPRITE_TRANSMIT_MODE_PIECE;

        vidObjLay->short_video_header = 0;
        vidObjLay->video_object_layer_id = (parser->current_sc & 0xF);
    
        getbits = viddec_pm_get_bits(parent, &code, 9);
        BREAK_GETBITS_REQD_MISSING(getbits, ret);
        vidObjLay->video_object_type_indication = code & 0xFF;
        vidObjLay->random_accessible_vol = ((code & 0x100) > 0);

        if(!mp4_pvt_valid_object_type_indication(vidObjLay->video_object_type_indication))
        {        /* Streams with "unknown" type mismatch with ref */
            DEB("Warning: video_object_type_indication = %d, forcing to 1\n",
                vidObjLay->video_object_type_indication);
            vidObjLay->video_object_type_indication = 1;
        }

        if(vidObjLay->video_object_type_indication == MP4_VIDEO_OBJECT_TYPE_FINE_GRANULARITY_SCALABLE)
        {/* This is not a supported type by HW */
            DEB("ERROR: mp4_Parse_VideoObject:video_object_type_indication = %.2X\n",
                vidObjLay->video_object_type_indication);
            ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
            break;
        }
        else
        {
            getbits = viddec_pm_get_bits(parent, &(code), 1);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            vidObjLay->is_object_layer_identifier = code;
            vidObjLay->video_object_layer_verid =
                (mp4_pvt_valid_object_layer_verid(visObj->visual_object_verid)) ? visObj->visual_object_verid : 1;
                
            if (vidObjLay->is_object_layer_identifier)
            {
                getbits = viddec_pm_get_bits(parent, &(code), 7);
                BREAK_GETBITS_REQD_MISSING(getbits, ret);
                vidObjLay->video_object_layer_priority = code & 0x7;
                vidObjLay->video_object_layer_verid = (code >> 3) & 0xF;
                if(!mp4_pvt_valid_object_layer_verid(vidObjLay->video_object_layer_verid))
                {
                    DEB("Error: mp4_Parse_VideoObject:is_identifier = %d, expected[1,5]\n",
                        vidObjLay->video_object_layer_verid);
                    ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                    break;
                }
                /* Video object layer ID supercedes visual object ID */
                visObj->visual_object_verid = vidObjLay->video_object_layer_verid;
            }

            getbits = viddec_pm_get_bits(parent, &(code), 4);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            vidObjLay->aspect_ratio_info = code & 0xF;
            if(vidObjLay->aspect_ratio_info == MP4_ASPECT_RATIO_EXTPAR)
            {
                getbits = viddec_pm_get_bits(parent, &(code), 16);
                BREAK_GETBITS_REQD_MISSING(getbits, ret);
                vidObjLay->aspect_ratio_info_par_width = (code >> 8) & 0xFF;
                vidObjLay->aspect_ratio_info_par_height = code & 0xFF;
            }
        
            getbits = viddec_pm_get_bits(parent, &(code), 1);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            vidObjLay->is_vol_control_parameters = code;
            if(vidObjLay->is_vol_control_parameters)
            {
                ret = mp4_pvt_VOL_volcontrolparameters(parent, parser);
                if(ret != MP4_STATUS_OK)
                {
                    break;
                }
            }

            getbits = viddec_pm_get_bits(parent, &(code), 2);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            vidObjLay->video_object_layer_shape = code;
            /* If shape is not rectangluar exit early without parsing */
            if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_RECTANGULAR)
            {
                DEB("Error: mp4_Parse_VideoObject: shape not rectangluar(%d):%d\n",
                    MP4_SHAPE_TYPE_RECTANGULAR, vidObjLay->video_object_layer_shape);
                ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                break;
            }

            if ((vidObjLay->video_object_layer_verid != 1) &&
                (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_GRAYSCALE))
            {/* Grayscale not supported */
                DEB("Error: MP4_SHAPE_TYPE_GRAYSCALE not supported\n");
                ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                break;
            }
        
            getbits = viddec_pm_get_bits(parent, &(code), 19);
            BREAK_GETBITS_REQD_MISSING(getbits, ret);
            /* TODO: check validity of marker */
            vidObjLay->vop_time_increment_resolution = (code >> 2) & 0xFFFF;            
            vidObjLay->fixed_vop_rate = code & 0x1;

            if(vidObjLay->vop_time_increment_resolution == 0)
            {
                DEB("Error: 0 value for vop_time_increment_resolution\n");
                ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                break;
            }
            /* calculate number bits in vop_time_increment_resolution */
            vidObjLay->vop_time_increment_resolution_bits = (uint8_t)mp4_pvt_count_number_of_bits(
                (uint32_t)(vidObjLay->vop_time_increment_resolution -1));

            if(vidObjLay->fixed_vop_rate)
            {
                getbits = viddec_pm_get_bits(parent, &(code), vidObjLay->vop_time_increment_resolution_bits);
                BREAK_GETBITS_REQD_MISSING(getbits, ret);
                vidObjLay->fixed_vop_time_increment = code;
            }

            if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY)
            {
                ret = mp4_Parse_VOL_notbinaryonly(parent, parser);
                if(ret != MP4_STATUS_OK)
                {
                    break;
                }
            }
            else
            {
                DEB("Error: MP4_SHAPE_TYPE_BINARYONLY not supported\n");
                ret = MP4_STATUS_NOTSUPPORT | MP4_STATUS_REQD_DATA_ERROR;
                break;
            }
        }

        vidObjLay->VideoObjectPlane.sprite_transmit_mode = MP4_SPRITE_TRANSMIT_MODE_PIECE;
        ret = MP4_STATUS_OK;
    } while(0);

    mp4_set_hdr_bitstream_error(parser, true, ret);
    if(ret != MP4_STATUS_OK)
        parser->bitstream_error |= MP4_BS_ERROR_HDR_NONDEC;
//DEB("before wkld mp4_Parse_VideoObjectLayer: bs_err: %d, ret: %d\n", parser->bitstream_error, ret);

    // POPULATE WORKLOAD ITEM
    {
        viddec_workload_item_t wi;
        viddec_workload_t *wl = viddec_pm_get_header(parent);
    
        wi.vwi_type = VIDDEC_WORKLOAD_MPEG4_VIDEO_OBJ;

        wi.mp4_vol.vol_aspect_ratio = 0;
        wi.mp4_vol.vol_bit_rate = 0;
        wi.mp4_vol.vol_frame_rate = 0;

        viddec_fw_mp4_vol_set_aspect_ratio_info(&wi.mp4_vol, vidObjLay->aspect_ratio_info);
        viddec_fw_mp4_vol_set_par_width(&wi.mp4_vol, vidObjLay->aspect_ratio_info_par_width);
        viddec_fw_mp4_vol_set_par_height(&wi.mp4_vol, vidObjLay->aspect_ratio_info_par_height);
        viddec_fw_mp4_vol_set_control_param(&wi.mp4_vol, vidObjLay->is_vol_control_parameters);
        viddec_fw_mp4_vol_set_chroma_format(&wi.mp4_vol, vidObjLay->VOLControlParameters.chroma_format);
        viddec_fw_mp4_vol_set_interlaced(&wi.mp4_vol, vidObjLay->interlaced);
        viddec_fw_mp4_vol_set_fixed_vop_rate(&wi.mp4_vol, vidObjLay->fixed_vop_rate);

        viddec_fw_mp4_vol_set_vbv_param(&wi.mp4_vol, vidObjLay->VOLControlParameters.vbv_parameters);
        viddec_fw_mp4_vol_set_bit_rate(&wi.mp4_vol, vidObjLay->VOLControlParameters.bit_rate);

        viddec_fw_mp4_vol_set_fixed_vop_time_increment(&wi.mp4_vol, vidObjLay->fixed_vop_time_increment);
        viddec_fw_mp4_vol_set_vop_time_increment_resolution(&wi.mp4_vol, vidObjLay->vop_time_increment_resolution);

        ret = viddec_pm_append_workitem(parent, &wi, false);
        if(ret == 1)
            ret = MP4_STATUS_OK;

        memset(&(wl->attrs), 0, sizeof(viddec_frame_attributes_t));

        wl->attrs.cont_size.width = vidObjLay->video_object_layer_width;
        wl->attrs.cont_size.height = vidObjLay->video_object_layer_height;
    }
    
    return ret;    
}
