/*
 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
 * Copyright (c) Imagination Technologies Limited, UK
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *    Elaine Wang <elaine.wang@intel.com>
 *    Zeng Li <zeng.li@intel.com>
 *
 */


#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>

#include "psb_def.h"
#include "psb_drv_debug.h"
#include "psb_surface.h"
#include "psb_cmdbuf.h"
#include "pnw_hostcode.h"
#include "pnw_H264ES.h"
#include "pnw_hostheader.h"
#include "va/va_enc_h264.h"
#define TOPAZ_H264_MAX_BITRATE 50000000

#define INIT_CONTEXT_H264ES     context_ENC_p ctx = (context_ENC_p) obj_context->format_data
#define SURFACE(id)    ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
#define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &ctx->obj_context->driver_data->buffer_heap, id ))
static void pnw_H264ES_QueryConfigAttributes(
        VAProfile __maybe_unused profile,
        VAEntrypoint __maybe_unused entrypoint,
        VAConfigAttrib *attrib_list,
        int num_attribs)
{
    int i;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264ES_QueryConfigAttributes\n");

    /* RateControl attributes */
    for (i = 0; i < num_attribs; i++) {
        switch (attrib_list[i].type) {
            case VAConfigAttribRTFormat:
                break;

            case VAConfigAttribRateControl:
                attrib_list[i].value = VA_RC_NONE | VA_RC_CBR | VA_RC_VBR | VA_RC_VCM;
	        break;

            case VAConfigAttribEncMaxRefFrames:
                attrib_list[i].value = 1;
                break;

	    default:
		attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
		break;
	}
    }
}


static VAStatus pnw_H264ES_ValidateConfig(
        object_config_p obj_config)
{
    int i;
    /* Check all attributes */
    for (i = 0; i < obj_config->attrib_count; i++) {
        switch (obj_config->attrib_list[i].type) {
            case VAConfigAttribRTFormat:
                /* Ignore */
                break;
            case VAConfigAttribRateControl:
                break;
            default:
                return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
        }
    }

    return VA_STATUS_SUCCESS;
}


static VAStatus pnw_H264ES_CreateContext(
        object_context_p obj_context,
        object_config_p obj_config)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    context_ENC_p ctx;
    int i;
    unsigned int eRCmode;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264ES_CreateContext\n");

    vaStatus = pnw_CreateContext(obj_context, obj_config, 0);

    if (VA_STATUS_SUCCESS != vaStatus)
        return VA_STATUS_ERROR_ALLOCATION_FAILED;

    ctx = (context_ENC_p) obj_context->format_data;

    for (i = 0; i < obj_config->attrib_count; i++) {
        if (obj_config->attrib_list[i].type == VAConfigAttribRateControl)
            break;
    }

    if (i >= obj_config->attrib_count)
        eRCmode = VA_RC_NONE;
    else
        eRCmode = obj_config->attrib_list[i].value;


    if (eRCmode == VA_RC_VBR) {
        ctx->eCodec = IMG_CODEC_H264_VBR;
        ctx->sRCParams.RCEnable = IMG_TRUE;
        ctx->sRCParams.bDisableBitStuffing = IMG_FALSE;
    } else if (eRCmode == VA_RC_CBR) {
        ctx->eCodec = IMG_CODEC_H264_CBR;
        ctx->sRCParams.RCEnable = IMG_TRUE;
        ctx->sRCParams.bDisableBitStuffing = IMG_TRUE;
    } else if (eRCmode == VA_RC_NONE) {
        ctx->eCodec = IMG_CODEC_H264_NO_RC;
        ctx->sRCParams.RCEnable = IMG_FALSE;
        ctx->sRCParams.bDisableBitStuffing = IMG_FALSE;
    } else if (eRCmode == VA_RC_VCM) {
        ctx->eCodec = IMG_CODEC_H264_VCM;
        ctx->sRCParams.RCEnable = IMG_TRUE;
        ctx->sRCParams.bDisableBitStuffing = IMG_FALSE;
    } else
        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "eCodec is %d\n", ctx->eCodec);
    ctx->eFormat = IMG_CODEC_PL12;      /* use default */

    ctx->Slices = 1;
    ctx->idr_pic_id = 1;
    ctx->buffer_size = 0;
    ctx->initial_buffer_fullness = 0;
    //initialize the frame_rate and qp
    ctx->sRCParams.FrameRate = 30;

    if (getenv("PSB_VIDEO_SIG_CORE") == NULL) {
        ctx->Slices = 2;
        ctx->NumCores = 2;
    }

    ctx->ParallelCores = min(ctx->NumCores, ctx->Slices);

    ctx->IPEControl = pnw__get_ipe_control(ctx->eCodec);

    switch (obj_config->profile) {
        case VAProfileH264Baseline:
            ctx->profile_idc = 5;
            break;
        case VAProfileH264Main:
            ctx->profile_idc = 6;
            break;
        default:
            ctx->profile_idc = 6;
            break;
    }

    return vaStatus;
}

static void pnw_H264ES_DestroyContext(
        object_context_p obj_context)
{
    drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264ES_DestroyPicture\n");

    pnw_DestroyContext(obj_context);
}

static VAStatus pnw_H264ES_BeginPicture(
        object_context_p obj_context)
{
    INIT_CONTEXT_H264ES;
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264ES_BeginPicture\n");

    vaStatus = pnw_BeginPicture(ctx);

    return vaStatus;
}

static VAStatus pnw__H264ES_process_sequence_param(context_ENC_p ctx, object_buffer_p obj_buffer)
{
    VAEncSequenceParameterBufferH264 *pSequenceParams;
    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;
    H264_VUI_PARAMS *pVUI_Params = &(ctx->VUI_Params);
    H264_CROP_PARAMS sCrop;
    int i;
    unsigned int frame_size;
    unsigned int max_bps;

    ASSERT(obj_buffer->type == VAEncSequenceParameterBufferType);
    ASSERT(obj_buffer->num_elements == 1);
    ASSERT(obj_buffer->size == sizeof(VAEncSequenceParameterBufferH264));

    if ((obj_buffer->num_elements != 1) ||
            (obj_buffer->size != sizeof(VAEncSequenceParameterBufferH264))) {
        return VA_STATUS_ERROR_UNKNOWN;
    }

    if(ctx->sRCParams.FrameRate == 0)
        ctx->sRCParams.FrameRate = 30;
    ctx->obj_context->frame_count = 0;

    pSequenceParams = (VAEncSequenceParameterBufferH264 *) obj_buffer->buffer_data;
    obj_buffer->buffer_data = NULL;
    obj_buffer->size = 0;

    if (!pSequenceParams->bits_per_second) {
        pSequenceParams->bits_per_second = ctx->Height * ctx->Width * 30 * 12;
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "bits_per_second is 0, set to %d\n",
                pSequenceParams->bits_per_second);
    }
    ctx->sRCParams.bBitrateChanged =
        (pSequenceParams->bits_per_second == ctx->sRCParams.BitsPerSecond ?
         IMG_FALSE : IMG_TRUE);

    if (pSequenceParams->bits_per_second > TOPAZ_H264_MAX_BITRATE) {
        ctx->sRCParams.BitsPerSecond = TOPAZ_H264_MAX_BITRATE;
        drv_debug_msg(VIDEO_DEBUG_GENERAL, " bits_per_second(%d) exceeds \
                the maximum bitrate, set it with %d\n",
                pSequenceParams->bits_per_second,
                TOPAZ_H264_MAX_BITRATE);
    }

    /* According to Table A-1 Level limits, if resolution is bigger than 625SD,
       min compression ratio is 4, otherwise min compression ratio is 2 */
    max_bps =  (ctx->Width * ctx->Height * 3 / 2 ) * 8 * ctx->sRCParams.FrameRate;
    if (ctx->Width > 720)
        max_bps /= 4;
    else
        max_bps /= 2;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, " width %d height %d, frame rate %d\n",
            ctx->Width, ctx->Height, ctx->sRCParams.FrameRate);
    if (pSequenceParams->bits_per_second > max_bps) {
        drv_debug_msg(VIDEO_DEBUG_ERROR,
                "Invalid bitrate %d, violate ITU-T Rec. H.264 (03/2005) A.3.1"
                "\n clip to %d bps\n", pSequenceParams->bits_per_second, max_bps);
        ctx->sRCParams.BitsPerSecond = max_bps;
    } else {
        /* See 110% target bitrate for VCM. Otherwise, the resulted bitrate is much lower
           than target bitrate */
        if (ctx->eCodec == IMG_CODEC_H264_VCM)
            pSequenceParams->bits_per_second =
                pSequenceParams->bits_per_second / 100 * 110;

        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Bitrate is set to %d\n",
                pSequenceParams->bits_per_second);
        ctx->sRCParams.BitsPerSecond = pSequenceParams->bits_per_second;
    }

    /*if (ctx->sRCParams.IntraFreq != pSequenceParams->intra_period)
      ctx->sRCParams.bBitrateChanged = IMG_TRUE;*/
    ctx->sRCParams.IDRFreq = pSequenceParams->intra_idr_period;

    ctx->sRCParams.Slices = ctx->Slices;
    ctx->sRCParams.QCPOffset = 0;

    if (ctx->sRCParams.IntraFreq != pSequenceParams->intra_period
            && ctx->raw_frame_count != 0
            && ctx->sRCParams.IntraFreq != 0
            && ((ctx->obj_context->frame_count + 1) % ctx->sRCParams.IntraFreq) != 0
            && (!ctx->sRCParams.bDisableFrameSkipping)) {
        drv_debug_msg(VIDEO_DEBUG_ERROR,
                "Changing intra period value in the middle of a GOP is\n"
                "not allowed if frame skip isn't disabled.\n"
                "it can cause I frame been skipped\n");
        free(pSequenceParams);
        return VA_STATUS_ERROR_INVALID_PARAMETER;
    }
    else
        ctx->sRCParams.IntraFreq = pSequenceParams->intra_period;

    frame_size = ctx->sRCParams.BitsPerSecond / ctx->sRCParams.FrameRate;

    if (ctx->bInserHRDParams &&
            ctx->buffer_size != 0 && ctx->initial_buffer_fullness != 0) {
        ctx->sRCParams.BufferSize = ctx->buffer_size;
        ctx->sRCParams.InitialLevel = ctx->buffer_size - ctx->initial_buffer_fullness;
        ctx->sRCParams.InitialDelay = ctx->initial_buffer_fullness;
    }
    else {
        ctx->buffer_size = ctx->sRCParams.BitsPerSecond;
        ctx->initial_buffer_fullness = ctx->sRCParams.BitsPerSecond;
        ctx->sRCParams.BufferSize = ctx->buffer_size;
        ctx->sRCParams.InitialLevel = (3 * ctx->sRCParams.BufferSize) >> 4;
        /* Aligned with target frame size */
        ctx->sRCParams.InitialLevel += (frame_size / 2);
        ctx->sRCParams.InitialLevel /= frame_size;
        ctx->sRCParams.InitialLevel *= frame_size;
        ctx->sRCParams.InitialDelay = ctx->buffer_size - ctx->sRCParams.InitialLevel;
    }

    if (ctx->raw_frame_count == 0) {
        for (i = (ctx->ParallelCores - 1); i >= 0; i--)
            pnw_set_bias(ctx, i);
    }

    pVUI_Params->bit_rate_value_minus1 = ctx->sRCParams.BitsPerSecond / 64 - 1;
    pVUI_Params->cbp_size_value_minus1 = ctx->sRCParams.BufferSize / 64 - 1;
    if (IMG_CODEC_H264_CBR != ctx->eCodec ||
            ctx->sRCParams.bDisableBitStuffing ||
            ctx->sRCParams.bDisableFrameSkipping)
        pVUI_Params->CBR = 0;
    else
        pVUI_Params->CBR = 1;

    pVUI_Params->initial_cpb_removal_delay_length_minus1 = BPH_SEI_NAL_INITIAL_CPB_REMOVAL_DELAY_SIZE - 1;
    pVUI_Params->cpb_removal_delay_length_minus1 = PTH_SEI_NAL_CPB_REMOVAL_DELAY_SIZE - 1;
    pVUI_Params->dpb_output_delay_length_minus1 = PTH_SEI_NAL_DPB_OUTPUT_DELAY_SIZE - 1;
    pVUI_Params->time_offset_length = 24;
    ctx->bInsertVUI = pSequenceParams->vui_parameters_present_flag ? IMG_TRUE: IMG_FALSE;
    if (ctx->bInsertVUI) {
        if (pSequenceParams->num_units_in_tick !=0 && pSequenceParams->time_scale !=0
                && (pSequenceParams->time_scale > pSequenceParams->num_units_in_tick) ) {
            pVUI_Params->Time_Scale = pSequenceParams->time_scale;
            pVUI_Params->num_units_in_tick = pSequenceParams->num_units_in_tick;
        }
        else {
            pVUI_Params->num_units_in_tick = 1;
            pVUI_Params->Time_Scale = ctx->sRCParams.FrameRate * 2;
        }
    }

    if (ctx->bInsertVUI && pSequenceParams->vui_fields.bits.aspect_ratio_info_present_flag &&
            (pSequenceParams->aspect_ratio_idc == 0xff /* Extended_SAR */)) {
        pVUI_Params->aspect_ratio_info_present_flag = IMG_TRUE;
        pVUI_Params->aspect_ratio_idc = 0xff;
        pVUI_Params->sar_width = pSequenceParams->sar_width;
        pVUI_Params->sar_height = pSequenceParams->sar_height;
    }

    sCrop.bClip = pSequenceParams->frame_cropping_flag;
    sCrop.LeftCropOffset = 0;
    sCrop.RightCropOffset = 0;
    sCrop.TopCropOffset = 0;
    sCrop.BottomCropOffset = 0;

    if (!sCrop.bClip) {
        if (ctx->RawHeight & 0xf) {
            sCrop.bClip = IMG_TRUE;
            sCrop.BottomCropOffset = (((ctx->RawHeight + 0xf) & (~0xf)) - ctx->RawHeight) / 2;
        }
        if (ctx->RawWidth & 0xf) {
            sCrop.bClip = IMG_TRUE;
            sCrop.RightCropOffset = (((ctx->RawWidth + 0xf) & (~0xf)) - ctx->RawWidth) / 2;
        }
    } else {
        sCrop.LeftCropOffset = pSequenceParams->frame_crop_left_offset;
        sCrop.RightCropOffset = pSequenceParams->frame_crop_right_offset;
        sCrop.TopCropOffset = pSequenceParams->frame_crop_top_offset;
        sCrop.BottomCropOffset = pSequenceParams->frame_crop_bottom_offset;
    }
    /* sequence header is always inserted */

    memset(cmdbuf->header_mem_p + ctx->seq_header_ofs,
            0,
            HEADER_SIZE);

    /*
       if (ctx->bInserHRDParams) {
       memset(cmdbuf->header_mem_p + ctx->aud_header_ofs,
       0,
       HEADER_SIZE);

       pnw__H264_prepare_AUD_header(cmdbuf->header_mem_p + ctx->aud_header_ofs);
       pnw_cmdbuf_insert_command_package(ctx->obj_context,
       ctx->ParallelCores - 1,
       MTX_CMDID_DO_HEADER,
       &cmdbuf->header_mem,
       ctx->aud_header_ofs);
       }
     */
    if (ctx->eCodec == IMG_CODEC_H264_NO_RC)
        pnw__H264_prepare_sequence_header(cmdbuf->header_mem_p + ctx->seq_header_ofs,
                pSequenceParams->picture_width_in_mbs,
                pSequenceParams->picture_height_in_mbs,
                pSequenceParams->vui_parameters_present_flag,
                pSequenceParams->vui_parameters_present_flag ? (pVUI_Params) : NULL,
                &sCrop,
                pSequenceParams->level_idc, ctx->profile_idc);
    else
        pnw__H264_prepare_sequence_header(cmdbuf->header_mem_p + ctx->seq_header_ofs,
                pSequenceParams->picture_width_in_mbs,
                pSequenceParams->picture_height_in_mbs,
                pSequenceParams->vui_parameters_present_flag,
                pSequenceParams->vui_parameters_present_flag ? (pVUI_Params) : NULL,
                &sCrop,
                pSequenceParams->level_idc, ctx->profile_idc);

    /*Periodic IDR need SPS. We save the sequence header here*/
    if (ctx->sRCParams.IDRFreq != 0) {
        if (NULL == ctx->save_seq_header_p) {
            ctx->save_seq_header_p = malloc(HEADER_SIZE);
            if (NULL == ctx->save_seq_header_p) {
                drv_debug_msg(VIDEO_DEBUG_ERROR, "Ran out of memory!\n");
                free(pSequenceParams);
                return VA_STATUS_ERROR_ALLOCATION_FAILED;
            }
            memcpy((unsigned char *)ctx->save_seq_header_p,
                    (unsigned char *)(cmdbuf->header_mem_p + ctx->seq_header_ofs),
                    HEADER_SIZE);
        }
    }
    ctx->none_vcl_nal++;
    cmdbuf->cmd_idx_saved[PNW_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx;
    /* Send to the last core as this will complete first */
    pnw_cmdbuf_insert_command_package(ctx->obj_context,
            ctx->ParallelCores - 1,
            MTX_CMDID_DO_HEADER,
            &cmdbuf->header_mem,
            ctx->seq_header_ofs);
    free(pSequenceParams);

    return VA_STATUS_SUCCESS;
}


static VAStatus pnw__H264ES_insert_SEI_buffer_period(context_ENC_p ctx)
{
    unsigned int ui32nal_initial_cpb_removal_delay;
    unsigned int ui32nal_initial_cpb_removal_delay_offset;
    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;

    ui32nal_initial_cpb_removal_delay =
        90000 * (1.0 * ctx->sRCParams.InitialDelay / ctx->sRCParams.BitsPerSecond);
    ui32nal_initial_cpb_removal_delay_offset =
        90000 * (1.0 * ctx->buffer_size / ctx->sRCParams.BitsPerSecond)
        - ui32nal_initial_cpb_removal_delay;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert SEI buffer period message with "
            "ui32nal_initial_cpb_removal_delay(%d) and "
            "ui32nal_initial_cpb_removal_delay_offset(%d)\n",
            ui32nal_initial_cpb_removal_delay,
            ui32nal_initial_cpb_removal_delay_offset);

    memset(cmdbuf->header_mem_p + ctx->sei_buf_prd_ofs,
            0,
            HEADER_SIZE);

    pnw__H264_prepare_SEI_buffering_period_header(
            (MTX_HEADER_PARAMS *)(cmdbuf->header_mem_p + ctx->sei_buf_prd_ofs),
            1, //ui8NalHrdBpPresentFlag,
            0, //ui8nal_cpb_cnt_minus1,
            1 + ctx->VUI_Params.initial_cpb_removal_delay_length_minus1, //ui8nal_initial_cpb_removal_delay_length,
            ui32nal_initial_cpb_removal_delay, //ui32nal_initial_cpb_removal_delay,
            ui32nal_initial_cpb_removal_delay_offset, //ui32nal_initial_cpb_removal_delay_offset,
            0, //ui8VclHrdBpPresentFlag,
            NOT_USED_BY_TOPAZ, //ui8vcl_cpb_cnt_minus1,
            0, //ui32vcl_initial_cpb_removal_delay,
            0 //ui32vcl_initial_cpb_removal_delay_offset
            );
    cmdbuf->cmd_idx_saved[PNW_CMDBUF_SEI_BUF_PERIOD_IDX] = cmdbuf->cmd_idx;
    pnw_cmdbuf_insert_command_package(ctx->obj_context,
            ctx->ParallelCores - 1,
            MTX_CMDID_DO_HEADER,
            &cmdbuf->header_mem,
            ctx->sei_buf_prd_ofs);

    ctx->none_vcl_nal++;
    return VA_STATUS_SUCCESS;
}


static VAStatus pnw__H264ES_insert_SEI_pic_timing(context_ENC_p ctx)
{
    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;
    uint32_t ui32cpb_removal_delay;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert SEI picture timing message. \n");

    memset(cmdbuf->header_mem_p + ctx->sei_pic_tm_ofs,
            0,
            HEADER_SIZE);

    /* ui32cpb_removal_delay is zero for 1st frame and will be reset
     * after a IDR frame */
    if (ctx->obj_context->frame_count == 0) {
        if (ctx->raw_frame_count == 0)
            ui32cpb_removal_delay = 0;
        else
            ui32cpb_removal_delay =
                ctx->sRCParams.IDRFreq * ctx->sRCParams.IntraFreq * 2;
    } else
        ui32cpb_removal_delay = 2 * ctx->obj_context->frame_count;

    pnw__H264_prepare_SEI_picture_timing_header(
            (MTX_HEADER_PARAMS *)(cmdbuf->header_mem_p + ctx->sei_pic_tm_ofs),
            1,
            ctx->VUI_Params.cpb_removal_delay_length_minus1,
            ctx->VUI_Params.dpb_output_delay_length_minus1,
            ui32cpb_removal_delay, //ui32cpb_removal_delay,
            2, //ui32dpb_output_delay,
            0, //ui8pic_struct_present_flag,
            0, //ui8pic_struct,
            0, //ui8NumClockTS,
            0, //*aui8clock_timestamp_flag,
            0, //ui8full_timestamp_flag,
            0, //ui8seconds_flag,
            0, //ui8minutes_flag,
            0, //ui8hours_flag,
            0, //ui8seconds_value,
            0, //ui8minutes_value,
            0, //ui8hours_value,
            0, //ui8ct_type,
            0, //ui8nuit_field_based_flag,
            0, //ui8counting_type,
            0, //ui8discontinuity_flag,
            0, //ui8cnt_dropped_flag,
            0, //ui8n_frames,
            0, //ui8time_offset_length,
            0 //i32time_offset)
                );

    cmdbuf->cmd_idx_saved[PNW_CMDBUF_SEI_PIC_TIMING_IDX] = cmdbuf->cmd_idx;
    pnw_cmdbuf_insert_command_package(ctx->obj_context,
            ctx->ParallelCores - 1,
            MTX_CMDID_DO_HEADER,
            &cmdbuf->header_mem,
            ctx->sei_pic_tm_ofs);

    ctx->none_vcl_nal++;
    return VA_STATUS_SUCCESS;
}

#if PSB_MFLD_DUMMY_CODE
static VAStatus pnw__H264ES_insert_SEI_FPA_param(context_ENC_p ctx, object_buffer_p obj_buffer)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;
    VAEncPackedHeaderParameterBuffer *sei_param_buf = (VAEncPackedHeaderParameterBuffer *)obj_buffer->buffer_data;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert SEI frame packing arrangement message. \n");
    ctx->sei_pic_data_size = sei_param_buf->bit_length/8;

    return VA_STATUS_SUCCESS;
}

static VAStatus pnw__H264ES_insert_SEI_FPA_data(context_ENC_p ctx, object_buffer_p obj_buffer)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;
    char *sei_data_buf;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Insert SEI frame packing arrangement message. \n");

    memset(cmdbuf->header_mem_p + ctx->sei_pic_fpa_ofs,
            0,
            HEADER_SIZE);
    sei_data_buf = (char *)obj_buffer->buffer_data;

    pnw__H264_prepare_SEI_FPA_header((MTX_HEADER_PARAMS *)(cmdbuf->header_mem_p + ctx->sei_pic_fpa_ofs), sei_data_buf, ctx->sei_pic_data_size);
    pnw_cmdbuf_insert_command_package(ctx->obj_context,
            ctx->ParallelCores - 1,
            MTX_CMDID_DO_HEADER,
            &cmdbuf->header_mem,
            ctx->sei_pic_fpa_ofs);

    return VA_STATUS_SUCCESS;
}
#endif

static VAStatus pnw__H264ES_process_picture_param(context_ENC_p ctx, object_buffer_p obj_buffer)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    int i;
    VAEncPictureParameterBufferH264 *pBuffer;
    int need_sps = 0;
    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;

    ASSERT(obj_buffer->type == VAEncPictureParameterBufferType);

    if ((obj_buffer->num_elements != 1) ||
            (obj_buffer->size != sizeof(VAEncPictureParameterBufferH264))) {
        return VA_STATUS_ERROR_UNKNOWN;
    }

    /* Transfer ownership of VAEncPictureParameterBufferH264 data */
    pBuffer = (VAEncPictureParameterBufferH264 *) obj_buffer->buffer_data;
    obj_buffer->buffer_data = NULL;
    obj_buffer->size = 0;

    ctx->ref_surface = SURFACE(pBuffer->ReferenceFrames[0].picture_id);
    ctx->dest_surface = SURFACE(pBuffer->CurrPic.picture_id);
    ctx->coded_buf = BUFFER(pBuffer->coded_buf);

    //ASSERT(ctx->Width == pBuffer->picture_width);
    //ASSERT(ctx->Height == pBuffer->picture_height);

    if (NULL == ctx->coded_buf) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid coded buffer handle\n", __FUNCTION__, __LINE__);
        free(pBuffer);
        return VA_STATUS_ERROR_INVALID_BUFFER;
    }
    if ((ctx->sRCParams.IntraFreq != 0) && (ctx->sRCParams.IDRFreq != 0)) { /* period IDR is desired */
        unsigned int is_intra = 0;
        unsigned int intra_cnt = 0;

        ctx->force_idr_h264 = 0;

        if ((ctx->obj_context->frame_count % ctx->sRCParams.IntraFreq) == 0) {
            is_intra = 1; /* suppose current frame is I frame */
            intra_cnt = ctx->obj_context->frame_count / ctx->sRCParams.IntraFreq;
        }

        /* current frame is I frame (suppose), and an IDR frame is desired*/
        if ((is_intra) && ((intra_cnt % ctx->sRCParams.IDRFreq) == 0)) {
            ctx->force_idr_h264 = 1;
            /*When two consecutive access units in decoding order are both IDR access
             * units, the value of idr_pic_id in the slices of the first such IDR
             * access unit shall differ from the idr_pic_id in the second such IDR
             * access unit. We set it with 1 or 0 alternately.*/
            ctx->idr_pic_id = 1 - ctx->idr_pic_id;

            /* it is periodic IDR in the middle of one sequence encoding, need SPS */
            if (ctx->obj_context->frame_count > 0)
                need_sps = 1;

            ctx->obj_context->frame_count = 0;
        }
    }

    /* If VUI header isn't enabled, we'll igore the request for HRD header insertion */
    if (ctx->bInserHRDParams)
        ctx->bInserHRDParams = ctx->bInsertVUI;

    /* For H264, PicHeader only needed in the first picture*/
    if (!(ctx->obj_context->frame_count)) {
        cmdbuf = ctx->obj_context->pnw_cmdbuf;

        if (need_sps) {
            drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ: insert a SPS before IDR frame\n");
            /* reuse the previous SPS */
            memcpy((unsigned char *)(cmdbuf->header_mem_p + ctx->seq_header_ofs),
                    (unsigned char *)ctx->save_seq_header_p,
                    HEADER_SIZE);

            cmdbuf->cmd_idx_saved[PNW_CMDBUF_SEQ_HEADER_IDX] = cmdbuf->cmd_idx;
            /* Send to the last core as this will complete first */
            pnw_cmdbuf_insert_command_package(ctx->obj_context,
                    ctx->ParallelCores - 1,
                    MTX_CMDID_DO_HEADER,
                    &cmdbuf->header_mem,
                    ctx->seq_header_ofs);
            ctx->none_vcl_nal++;
        }

        if (ctx->bInserHRDParams) {
            pnw__H264ES_insert_SEI_buffer_period(ctx);
            pnw__H264ES_insert_SEI_pic_timing(ctx);
        }

        pnw__H264_prepare_picture_header(cmdbuf->header_mem_p + ctx->pic_header_ofs, IMG_FALSE, ctx->sRCParams.QCPOffset);

        cmdbuf->cmd_idx_saved[PNW_CMDBUF_PIC_HEADER_IDX] = cmdbuf->cmd_idx;
        /* Send to the last core as this will complete first */
        pnw_cmdbuf_insert_command_package(ctx->obj_context,
                ctx->ParallelCores - 1,
                MTX_CMDID_DO_HEADER,
                &cmdbuf->header_mem,
                ctx->pic_header_ofs);
        ctx->none_vcl_nal++;
    }
    else if (ctx->bInserHRDParams)
        pnw__H264ES_insert_SEI_pic_timing(ctx);

    if (ctx->ParallelCores == 1) {
        ctx->coded_buf_per_slice = 0;
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ: won't splite coded buffer(%d) since only one slice being encoded\n",
                ctx->coded_buf->size);
    } else {
        /*Make sure DMA start is 128bits alignment*/
        ctx->coded_buf_per_slice = (ctx->coded_buf->size / ctx->ParallelCores) & (~0xf) ;
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "TOPAZ: the size of coded_buf per slice %d( Total %d) \n", ctx->coded_buf_per_slice,
                ctx->coded_buf->size);
    }

    /* Prepare START_PICTURE params */
    /* FIXME is really need multiple picParams? Need multiple calculate for each? */
    for (i = (ctx->ParallelCores - 1); i >= 0; i--)
        vaStatus = pnw_RenderPictureParameter(ctx, i);

    free(pBuffer);
    return vaStatus;
}

static VAStatus pnw__H264ES_encode_one_slice(context_ENC_p ctx,
        VAEncSliceParameterBuffer *pBuffer)
{
    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;
    unsigned int MBSkipRun, FirstMBAddress;
    unsigned char deblock_idc;
    unsigned char is_intra = 0;
    int slice_param_idx;
    PIC_PARAMS *psPicParams = (PIC_PARAMS *)(cmdbuf->pic_params_p);
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    /*Slice encoding Order:
     *1.Insert Do header command
     *2.setup InRowParams
     *3.setup Slice params
     *4.Insert Do slice command
     * */

    if (pBuffer->slice_height > (ctx->Height / 16) ||
           pBuffer->start_row_number > (ctx->Height / 16) ||
           (pBuffer->slice_height + pBuffer->start_row_number) > (ctx->Height / 16)) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "slice height %d or start row number %d is too large",
                pBuffer->slice_height,  pBuffer->start_row_number);
        return VA_STATUS_ERROR_INVALID_PARAMETER;
    }
    MBSkipRun = (pBuffer->slice_height * ctx->Width) / 16;
    deblock_idc = pBuffer->slice_flags.bits.disable_deblocking_filter_idc;

    /*If the frame is skipped, it shouldn't be a I frame*/
    if (ctx->force_idr_h264 || (ctx->obj_context->frame_count == 0)) {
        is_intra = 1;
    } else
        is_intra = (ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip) ? 0 : pBuffer->slice_flags.bits.is_intra;

    FirstMBAddress = (pBuffer->start_row_number * ctx->Width) / 16;

    memset(cmdbuf->header_mem_p + ctx->slice_header_ofs
            + ctx->obj_context->slice_count * HEADER_SIZE,
            0,
            HEADER_SIZE);

    /* Insert Do Header command, relocation is needed */
    pnw__H264_prepare_slice_header(cmdbuf->header_mem_p + ctx->slice_header_ofs
            + ctx->obj_context->slice_count * HEADER_SIZE,
            is_intra,
            pBuffer->slice_flags.bits.disable_deblocking_filter_idc,
            ctx->obj_context->frame_count,
            FirstMBAddress,
            MBSkipRun,
            0,
            ctx->force_idr_h264,
            IMG_FALSE,
            IMG_FALSE,
            ctx->idr_pic_id);

    /* ensure that this slice is consequtive to that last processed by the target core */
    /*
       ASSERT( -1 == ctx->LastSliceNum[ctx->SliceToCore]
       || ctx->obj_context->slice_count == 1 + ctx->LastSliceNum[ctx->SliceToCore] );
     */
    /* note the slice number the target core is now processing */
    ctx->LastSliceNum[ctx->SliceToCore] = ctx->obj_context->slice_count;

    pnw_cmdbuf_insert_command_package(ctx->obj_context,
            ctx->SliceToCore,
            MTX_CMDID_DO_HEADER,
            &cmdbuf->header_mem,
            ctx->slice_header_ofs + ctx->obj_context->slice_count * HEADER_SIZE);
    if (!(ctx->sRCParams.RCEnable && ctx->sRCParams.FrameSkip)) {
        /*Only reset on the first frame. It's more effective than DDK. Have confirmed with IMG*/
        if (ctx->obj_context->frame_count == 0)
            pnw_reset_encoder_params(ctx);
        if ((pBuffer->start_row_number == 0) && pBuffer->slice_flags.bits.is_intra) {
            ctx->BelowParamsBufIdx = (ctx->BelowParamsBufIdx + 1) & 0x1;
        }

        slice_param_idx = (pBuffer->slice_flags.bits.is_intra ? 0 : 1) * ctx->slice_param_num
            + ctx->obj_context->slice_count;
        if (VAEncSliceParameter_Equal(&ctx->slice_param_cache[slice_param_idx], pBuffer) == 0) {
            /* cache current param parameters */
            memcpy(&ctx->slice_param_cache[slice_param_idx],
                    pBuffer, sizeof(VAEncSliceParameterBuffer));

            /* Setup InParams value*/
            pnw_setup_slice_params(ctx,
                    pBuffer->start_row_number * 16,
                    pBuffer->slice_height * 16,
                    pBuffer->slice_flags.bits.is_intra,
                    ctx->obj_context->frame_count > 0,
                    psPicParams->sInParams.SeInitQP);
        }

        /* Insert do slice command and setup related buffer value */
        pnw__send_encode_slice_params(ctx,
                pBuffer->slice_flags.bits.is_intra,
                pBuffer->start_row_number * 16,
                deblock_idc,
                ctx->obj_context->frame_count,
                pBuffer->slice_height * 16,
                ctx->obj_context->slice_count);

        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Now frame_count/slice_count is %d/%d\n",
                ctx->obj_context->frame_count, ctx->obj_context->slice_count);
    }
    ctx->obj_context->slice_count++;

    return vaStatus;
}

/* convert from VAEncSliceParameterBufferH264  to VAEncSliceParameterBuffer */
static VAStatus pnw__convert_sliceparameter_buffer(VAEncSliceParameterBufferH264 *pBufferH264,
                                                   VAEncSliceParameterBuffer *pBuffer,
                                                   int picture_width_in_mbs,
                                                   unsigned int num_elemenent)
{
    unsigned int i;

    for (i = 0; i < num_elemenent; i++) {
        pBuffer->start_row_number = pBufferH264->macroblock_address / picture_width_in_mbs;
        pBuffer->slice_height =  pBufferH264->num_macroblocks / picture_width_in_mbs;
        pBuffer->slice_flags.bits.is_intra =
            (((pBufferH264->slice_type == 2) || (pBufferH264->slice_type == 7)) ? 1 : 0);
        pBuffer->slice_flags.bits.disable_deblocking_filter_idc =  pBufferH264->disable_deblocking_filter_idc;

        /* next conversion */
        pBuffer++;
        pBufferH264++;
    }

    return 0;
}

static VAStatus pnw__H264ES_process_slice_param(context_ENC_p ctx, object_buffer_p obj_buffer)
{
    /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */
    VAEncSliceParameterBuffer *pBuf_per_core = NULL, *pBuffer = NULL;
    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;
    PIC_PARAMS *psPicParams = (PIC_PARAMS *)(cmdbuf->pic_params_p);
    bool pBufferAlloced = false;
    unsigned int i, j, slice_per_core;
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    ASSERT(obj_buffer->type == VAEncSliceParameterBufferType);

    if (obj_buffer->num_elements > (ctx->Height / 16)) {
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
        goto out2;
    }
    cmdbuf = ctx->obj_context->pnw_cmdbuf;
    psPicParams = (PIC_PARAMS *)cmdbuf->pic_params_p;

    /* Transfer ownership of VAEncPictureParameterBuffer data */
    if (obj_buffer->size == sizeof(VAEncSliceParameterBufferH264)) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Receive VAEncSliceParameterBufferH264 buffer");
        pBuffer = calloc(obj_buffer->num_elements, sizeof(VAEncSliceParameterBuffer));

        if (pBuffer == NULL) {
            drv_debug_msg(VIDEO_DEBUG_ERROR, "Run out of memory!\n");
            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
            goto out2;
        }

        pBufferAlloced = true;

        pnw__convert_sliceparameter_buffer((VAEncSliceParameterBufferH264 *)obj_buffer->buffer_data,
                                           pBuffer,
                                           ctx->Width / 16,
                                           obj_buffer->num_elements);
    } else if (obj_buffer->size == sizeof(VAEncSliceParameterBuffer)) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Receive VAEncSliceParameterBuffer buffer");
        pBuffer = (VAEncSliceParameterBuffer *) obj_buffer->buffer_data;
    } else {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Buffer size(%d) is wrong. It should be %d or %d\n",
                obj_buffer->size, sizeof(VAEncSliceParameterBuffer),
                sizeof(VAEncSliceParameterBufferH264));
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
        goto out2;
    }

    obj_buffer->size = 0;

    /*In case the slice number changes*/
    if ((ctx->slice_param_cache != NULL) && (obj_buffer->num_elements != ctx->slice_param_num)) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Slice number changes. Previous value is %d. Now it's %d\n",
                ctx->slice_param_num, obj_buffer->num_elements);
        free(ctx->slice_param_cache);
        ctx->slice_param_cache = NULL;
        ctx->slice_param_num = 0;
    }

    if (NULL == ctx->slice_param_cache) {
        ctx->slice_param_num = obj_buffer->num_elements;
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocate %d VAEncSliceParameterBuffer cache buffers\n", 2 * ctx->slice_param_num);
        ctx->slice_param_cache = calloc(2 * ctx->slice_param_num, sizeof(VAEncSliceParameterBuffer));
        if (NULL == ctx->slice_param_cache) {
            drv_debug_msg(VIDEO_DEBUG_ERROR, "Run out of memory!\n");

            /* free the converted VAEncSliceParameterBuffer */
            if (pBufferAlloced)
                free(pBuffer);
            free(obj_buffer->buffer_data);
            return VA_STATUS_ERROR_ALLOCATION_FAILED;
        }
    }

    ctx->sRCParams.Slices = obj_buffer->num_elements;
    if (getenv("PSB_VIDEO_SIG_CORE") == NULL) {
        if ((ctx->ParallelCores == 2) && (obj_buffer->num_elements == 1)) {
            /*Need to replace unneccesary MTX_CMDID_STARTPICs with MTX_CMDID_PAD*/
            for (i = 0; i < (ctx->ParallelCores - 1); i++) {
                *(cmdbuf->cmd_idx_saved[PNW_CMDBUF_START_PIC_IDX] + i * 4) &= (~MTX_CMDWORD_ID_MASK);
                *(cmdbuf->cmd_idx_saved[PNW_CMDBUF_START_PIC_IDX] + i * 4) |= MTX_CMDID_PAD;
            }
            drv_debug_msg(VIDEO_DEBUG_GENERAL, " Remove unneccesary %d MTX_CMDID_STARTPIC commands from cmdbuf\n",
                    ctx->ParallelCores - obj_buffer->num_elements);
            ctx->ParallelCores = obj_buffer->num_elements;

            /* All header generation commands should be send to core 0*/
            for (i = PNW_CMDBUF_SEQ_HEADER_IDX; i < PNW_CMDBUF_SAVING_MAX; i++) {
                if (cmdbuf->cmd_idx_saved[i] != 0)
                    *(cmdbuf->cmd_idx_saved[i]) &=
                        ~(MTX_CMDWORD_CORE_MASK << MTX_CMDWORD_CORE_SHIFT);
            }

            ctx->SliceToCore = ctx->ParallelCores - 1;
        }
    }

    slice_per_core = obj_buffer->num_elements / ctx->ParallelCores;
    pBuf_per_core = pBuffer;
    for (i = 0; i < slice_per_core; i++) {
        pBuffer = pBuf_per_core;
        for (j = 0; j < ctx->ParallelCores; j++) {
            vaStatus = pnw__H264ES_encode_one_slice(ctx, pBuffer);
            if (vaStatus != VA_STATUS_SUCCESS)
                goto out1;
            if (0 == ctx->SliceToCore) {
                ctx->SliceToCore = ctx->ParallelCores;
            }
            ctx->SliceToCore--;

            ASSERT(ctx->obj_context->slice_count < MAX_SLICES_PER_PICTURE);
            /*Move to the next buffer which will be sent to core j*/
            pBuffer += slice_per_core;
        }
        pBuf_per_core++; /* Move to the next buffer */
    }

    /*Cope with last slice when slice number is odd and parallelCores is even*/
    if (obj_buffer->num_elements > (slice_per_core * ctx->ParallelCores)) {
        ctx->SliceToCore = 0;
        pBuffer -= slice_per_core;
        pBuffer ++;
        vaStatus = pnw__H264ES_encode_one_slice(ctx, pBuffer);
    }
out1:
    /* free the converted VAEncSliceParameterBuffer */
    if (pBufferAlloced)
        free(pBuffer);

out2:
    free(obj_buffer->buffer_data);
    obj_buffer->buffer_data = NULL;

    return vaStatus;
}

static VAStatus pnw__H264ES_process_misc_param(context_ENC_p ctx, object_buffer_p obj_buffer)
{
    /* Prepare InParams for macros of current slice, insert slice header, insert do slice command */
    VAEncMiscParameterBuffer *pBuffer;
    VAEncMiscParameterRateControl *rate_control_param;
    VAEncMiscParameterAIR *air_param;
    VAEncMiscParameterMaxSliceSize *max_slice_size_param;
    VAEncMiscParameterFrameRate *frame_rate_param;
    VAEncMiscParameterHRD *hrd_param;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    unsigned int max_bps;
    unsigned int frame_size;

    ASSERT(obj_buffer->type == VAEncMiscParameterBufferType);


    /* Transfer ownership of VAEncMiscParameterBuffer data */
    pBuffer = (VAEncMiscParameterBuffer *) obj_buffer->buffer_data;
    obj_buffer->size = 0;

    if (ctx->eCodec != IMG_CODEC_H264_VCM
            && (pBuffer->type != VAEncMiscParameterTypeHRD
                && pBuffer->type != VAEncMiscParameterTypeRateControl
                && pBuffer->type != VAEncMiscParameterTypeFrameRate)) {
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Buffer type %d isn't supported in none VCM mode.\n",
                pBuffer->type);
        free(obj_buffer->buffer_data);
        obj_buffer->buffer_data = NULL;
        return VA_STATUS_SUCCESS;
    }

    switch (pBuffer->type) {
        case VAEncMiscParameterTypeFrameRate:
            frame_rate_param = (VAEncMiscParameterFrameRate *)pBuffer->data;

            if (frame_rate_param->framerate < 1 || frame_rate_param->framerate > 65535) {
                vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
                break;
            }

            if (ctx->sRCParams.FrameRate == frame_rate_param->framerate)
                break;

            drv_debug_msg(VIDEO_DEBUG_GENERAL, "frame rate changed from %d to %d\n",
                    ctx->sRCParams.FrameRate,
                    frame_rate_param->framerate);
            ctx->sRCParams.FrameRate = frame_rate_param->framerate;
            ctx->sRCParams.bBitrateChanged = IMG_TRUE;

            ctx->sRCParams.FrameRate = (frame_rate_param->framerate < 1) ? 1 :
                ((65535 < frame_rate_param->framerate) ? 65535 : frame_rate_param->framerate);
            break;

        case VAEncMiscParameterTypeRateControl:
            rate_control_param = (VAEncMiscParameterRateControl *)pBuffer->data;

            /* Currently, none VCM mode only supports frame skip and bit stuffing
             * disable flag and doesn't accept other parameters in
             * buffer of VAEncMiscParameterTypeRateControl type */
            if (rate_control_param->rc_flags.value != 0 || ctx->raw_frame_count == 0) {
                if (rate_control_param->rc_flags.bits.disable_frame_skip)
                    ctx->sRCParams.bDisableFrameSkipping = IMG_TRUE;
                if (rate_control_param->rc_flags.bits.disable_bit_stuffing)
                    ctx->sRCParams.bDisableBitStuffing = IMG_TRUE;
                drv_debug_msg(VIDEO_DEBUG_GENERAL,
                        "bDisableFrameSkipping is %d and bDisableBitStuffing is %d\n",
                        ctx->sRCParams.bDisableFrameSkipping, ctx->sRCParams.bDisableBitStuffing);
            }

            if (rate_control_param->initial_qp > 51 ||
                    rate_control_param->min_qp > 51) {
                drv_debug_msg(VIDEO_DEBUG_ERROR, "Initial_qp(%d) and min_qpinitial_qp(%d) "
                        "are invalid.\nQP shouldn't be larger than 51 for H264\n",
                        rate_control_param->initial_qp, rate_control_param->min_qp);
                vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
                break;
            }

            if (rate_control_param->window_size > 2000) {
                drv_debug_msg(VIDEO_DEBUG_ERROR, "window_size is too much!\n");
                vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
                break;
            }

            /* Check if any none-zero RC parameter is changed*/
            if ((rate_control_param->bits_per_second == 0 ||
                        rate_control_param->bits_per_second == ctx->sRCParams.BitsPerSecond) &&
                    (rate_control_param->window_size == 0 ||
                    ctx->sRCParams.BufferSize == ctx->sRCParams.BitsPerSecond / 1000 * rate_control_param->window_size) &&
                    (ctx->sRCParams.MinQP == rate_control_param->min_qp) &&
                    (ctx->sRCParams.InitialQp == rate_control_param->initial_qp) &&
                    (rate_control_param->basic_unit_size == 0 ||
                     ctx->sRCParams.BUSize == rate_control_param->basic_unit_size)) {
		     drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s No RC parameter is changed\n",
				     __FUNCTION__);
                break;
	    }
            else if (ctx->raw_frame_count != 0 || ctx->eCodec == IMG_CODEC_H264_VCM)
                ctx->sRCParams.bBitrateChanged = IMG_TRUE;

            /* The initial target bitrate is set by Sequence parameter buffer.
               Here is for changed bitrate only */
            if (rate_control_param->bits_per_second > TOPAZ_H264_MAX_BITRATE) {
                drv_debug_msg(VIDEO_DEBUG_ERROR, " bits_per_second(%d) exceeds \
                        the maximum bitrate, set it with %d\n",
                        rate_control_param->bits_per_second,
                        TOPAZ_H264_MAX_BITRATE);
                break;
            }
            /* The initial target bitrate is set by Sequence parameter buffer.
               Here is for changed bitrate only */
            if (rate_control_param->bits_per_second != 0 &&
                    ctx->raw_frame_count != 0) {
                drv_debug_msg(VIDEO_DEBUG_GENERAL,
                        "bitrate is changed from %d to %d on frame %d\n",
                        ctx->sRCParams.BitsPerSecond,
                        rate_control_param->bits_per_second,
                        ctx->raw_frame_count);
                max_bps =  (ctx->Width * ctx->Height * 3 / 2 ) * 8 * ctx->sRCParams.FrameRate;
                if (ctx->Width > 720)
                    max_bps /= 4;
                else
                    max_bps /= 2;

                drv_debug_msg(VIDEO_DEBUG_GENERAL, " width %d height %d, frame rate %d\n",
                        ctx->Width, ctx->Height, ctx->sRCParams.FrameRate);
                if (rate_control_param->bits_per_second > max_bps) {
                    drv_debug_msg(VIDEO_DEBUG_ERROR,
                            "Invalid bitrate %d, violate ITU-T Rec. H.264 (03/2005) A.3.1"
                            "\n clip to %d bps\n", rate_control_param->bits_per_second, max_bps);
                    ctx->sRCParams.BitsPerSecond = max_bps;
                } else {
                    /* See 110% target bitrate for VCM. Otherwise, the resulted bitrate is much lower
                       than target bitrate */
                    if (ctx->eCodec == IMG_CODEC_H264_VCM)
                        rate_control_param->bits_per_second =
                            rate_control_param->bits_per_second / 100 * 110;
                    drv_debug_msg(VIDEO_DEBUG_GENERAL, "Bitrate is set to %d\n",
                            rate_control_param->bits_per_second);
                    ctx->sRCParams.BitsPerSecond = rate_control_param->bits_per_second;
                }
            }

            if (rate_control_param->min_qp != 0)
                ctx->sRCParams.MinQP = rate_control_param->min_qp;
            if (rate_control_param->window_size != 0) {
                ctx->sRCParams.BufferSize =
                    ctx->sRCParams.BitsPerSecond / 1000 * rate_control_param->window_size;
		if (ctx->sRCParams.FrameRate == 0) {
                    drv_debug_msg(VIDEO_DEBUG_ERROR, "frame rate can't be zero. Set it to 30");
                    ctx->sRCParams.FrameRate = 30;
                }

                frame_size = ctx->sRCParams.BitsPerSecond / ctx->sRCParams.FrameRate;
                if (frame_size == 0) {
                    drv_debug_msg(VIDEO_DEBUG_ERROR, "Bitrate is too low %d\n",
                            ctx->sRCParams.BitsPerSecond);
                    break;
                }
                ctx->sRCParams.InitialLevel = (3 * ctx->sRCParams.BufferSize) >> 4;
                ctx->sRCParams.InitialLevel += (frame_size / 2);
                ctx->sRCParams.InitialLevel /= frame_size;
                ctx->sRCParams.InitialLevel *= frame_size;
                ctx->sRCParams.InitialDelay =
                    ctx->sRCParams.BufferSize - ctx->sRCParams.InitialLevel;
            }

            if (rate_control_param->initial_qp != 0)
                ctx->sRCParams.InitialQp = rate_control_param->initial_qp;
            if (rate_control_param->basic_unit_size != 0)
                ctx->sRCParams.BUSize = rate_control_param->basic_unit_size;

            drv_debug_msg(VIDEO_DEBUG_GENERAL,
                    "Set Misc parameters(frame %d): window_size %d, initial qp %d\n" \
                    "\tmin qp %d, bunit size %d\n",
                    ctx->raw_frame_count,
                    rate_control_param->window_size,
                    rate_control_param->initial_qp,
                    rate_control_param->min_qp,
                    rate_control_param->basic_unit_size);
            break;

        case VAEncMiscParameterTypeMaxSliceSize:
            max_slice_size_param = (VAEncMiscParameterMaxSliceSize *)pBuffer->data;

            /*The max slice size should not be bigger than 1920x1080x1.5x8 */
            if (max_slice_size_param->max_slice_size > 24883200) {
                drv_debug_msg(VIDEO_DEBUG_ERROR,"Invalid max_slice_size. It should be 1~ 24883200.\n");
                vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
                break;
            }

            if (ctx->max_slice_size == max_slice_size_param->max_slice_size)
                break;

            drv_debug_msg(VIDEO_DEBUG_GENERAL, "max slice size changed to %d\n",
                    max_slice_size_param->max_slice_size);

            ctx->max_slice_size = max_slice_size_param->max_slice_size;

            break;

        case VAEncMiscParameterTypeAIR:
            air_param = (VAEncMiscParameterAIR *)pBuffer->data;

            if (air_param->air_num_mbs > 65535 ||
                    air_param->air_threshold > 65535) {
                vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
                break;
            }

            drv_debug_msg(VIDEO_DEBUG_GENERAL,"air slice size changed to num_air_mbs %d "
                    "air_threshold %d, air_auto %d\n",
                    air_param->air_num_mbs, air_param->air_threshold,
                    air_param->air_auto);

            if (((ctx->Height * ctx->Width) >> 8) < (int)air_param->air_num_mbs)
                air_param->air_num_mbs = ((ctx->Height * ctx->Width) >> 8);
            if (air_param->air_threshold == 0)
                drv_debug_msg(VIDEO_DEBUG_GENERAL,"%s: air threshold is set to zero\n",
                        __func__);
            ctx->num_air_mbs = air_param->air_num_mbs;
            ctx->air_threshold = air_param->air_threshold;
            //ctx->autotune_air_flag = air_param->air_auto;

            break;

        case VAEncMiscParameterTypeHRD:
            hrd_param = (VAEncMiscParameterHRD *)pBuffer->data;

            if (hrd_param->buffer_size == 0
                    || hrd_param->initial_buffer_fullness == 0)
                drv_debug_msg(VIDEO_DEBUG_GENERAL, "Find zero value for buffer_size "
                        "and initial_buffer_fullness.\n"
                        "Will assign default value to them later \n");

            if (ctx->initial_buffer_fullness > ctx->buffer_size) {
                drv_debug_msg(VIDEO_DEBUG_ERROR, "initial_buffer_fullnessi(%d) shouldn't be"
                        " larger that buffer_size(%d)!\n",
                        hrd_param->initial_buffer_fullness,
                        hrd_param->buffer_size);
                vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
                break;
            }

            if (!ctx->sRCParams.RCEnable) {
                drv_debug_msg(VIDEO_DEBUG_ERROR, "Only when rate control is enabled,"
                        " VAEncMiscParameterTypeHRD will take effect.\n");
                break;
            }

            ctx->buffer_size = hrd_param->buffer_size;
            ctx->initial_buffer_fullness = hrd_param->initial_buffer_fullness;
            ctx->bInserHRDParams = IMG_TRUE;
            drv_debug_msg(VIDEO_DEBUG_GENERAL, "hrd param buffer_size set to %d "
                    "initial buffer fullness set to %d\n",
                    ctx->buffer_size, ctx->initial_buffer_fullness);

            break;

        default:
            vaStatus = VA_STATUS_ERROR_UNKNOWN;
            DEBUG_FAILURE;
            break;
    }

    free(obj_buffer->buffer_data);
    obj_buffer->buffer_data = NULL;

    return vaStatus;
}



static VAStatus pnw_H264ES_RenderPicture(
        object_context_p obj_context,
        object_buffer_p *buffers,
        int num_buffers)
{
    INIT_CONTEXT_H264ES;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    int i;

    drv_debug_msg(VIDEO_DEBUG_GENERAL,"pnw_H264ES_RenderPicture\n");

    for (i = 0; i < num_buffers; i++) {
        object_buffer_p obj_buffer = buffers[i];

        switch (obj_buffer->type) {
            case VAEncSequenceParameterBufferType:
                drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_RenderPicture got VAEncSequenceParameterBufferType\n");
                vaStatus = pnw__H264ES_process_sequence_param(ctx, obj_buffer);
                DEBUG_FAILURE;
                break;

            case VAEncPictureParameterBufferType:
                drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_RenderPicture got VAEncPictureParameterBuffer\n");
                vaStatus = pnw__H264ES_process_picture_param(ctx, obj_buffer);
                DEBUG_FAILURE;
                break;

            case VAEncSliceParameterBufferType:
                drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_RenderPicture got VAEncSliceParameterBufferType\n");
                vaStatus = pnw__H264ES_process_slice_param(ctx, obj_buffer);
                DEBUG_FAILURE;
                break;

            case VAEncMiscParameterBufferType:
                drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_RenderPicture got VAEncMiscParameterBufferType\n");
                vaStatus = pnw__H264ES_process_misc_param(ctx, obj_buffer);
                DEBUG_FAILURE;
                break;
#if PSB_MFLD_DUMMY_CODE
            case VAEncPackedHeaderParameterBufferType:
                drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_RenderPicture got VAEncPackedHeaderParameterBufferType\n");
                vaStatus = pnw__H264ES_insert_SEI_FPA_param(ctx, obj_buffer);
                DEBUG_FAILURE;
                break;
            case VAEncPackedHeaderDataBufferType:
                drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_RenderPicture got VAEncPackedHeaderDataBufferType\n");
                vaStatus = pnw__H264ES_insert_SEI_FPA_data(ctx, obj_buffer);
                DEBUG_FAILURE;
                break;
#endif

            default:
                vaStatus = VA_STATUS_ERROR_UNKNOWN;
                DEBUG_FAILURE;
        }
        if (vaStatus != VA_STATUS_SUCCESS) {
            break;
        }
    }

    return vaStatus;
}

static VAStatus pnw_H264ES_EndPicture(
        object_context_p obj_context)
{
    INIT_CONTEXT_H264ES;
    pnw_cmdbuf_p cmdbuf = ctx->obj_context->pnw_cmdbuf;
    PIC_PARAMS *psPicParams = (PIC_PARAMS *)cmdbuf->pic_params_p;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    unsigned char core = 0;

    drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264ES_EndPicture\n");

    /* Unlike MPEG4 and H263, slices number is defined by user */
    for (core = 0; core < ctx->ParallelCores; core++) {
        psPicParams = (PIC_PARAMS *)
            (cmdbuf->pic_params_p +  ctx->pic_params_size * core);
        psPicParams->NumSlices =  ctx->sRCParams.Slices;
    }

    vaStatus = pnw_EndPicture(ctx);

    return vaStatus;
}


struct format_vtable_s pnw_H264ES_vtable = {
queryConfigAttributes:
    pnw_H264ES_QueryConfigAttributes,
    validateConfig:
        pnw_H264ES_ValidateConfig,
    createContext:
        pnw_H264ES_CreateContext,
    destroyContext:
        pnw_H264ES_DestroyContext,
    beginPicture:
        pnw_H264ES_BeginPicture,
    renderPicture:
        pnw_H264ES_RenderPicture,
    endPicture:
        pnw_H264ES_EndPicture
};

VAStatus pnw_set_frame_skip_flag(
        object_context_p obj_context)
{
    INIT_CONTEXT_H264ES;
    VAStatus vaStatus = VA_STATUS_SUCCESS;


    if (ctx && ctx->previous_src_surface) {
        SET_SURFACE_INFO_skipped_flag(ctx->previous_src_surface->psb_surface, 1);
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "Detected a skipped frame for surface 0x%08x.\n",
            ctx->previous_src_surface->psb_surface);
    }

    return vaStatus;
}


