/*
 * 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:
 *    Li Zeng <li.zeng@intel.com>
 */

#include "tng_vld_dec.h"
#include "psb_drv_debug.h"
#include "hwdefs/dxva_fw_ctrl.h"
#include "hwdefs/reg_io2.h"
#include "hwdefs/msvdx_offsets.h"
#include "hwdefs/msvdx_cmds_io2.h"

#include <malloc.h>

#define SURFACE(id)   ((object_surface_p) object_heap_lookup( &dec_ctx->obj_context->driver_data->surface_heap, id ))

static void tng_yuv_processor_QueryConfigAttributes(
    VAProfile __maybe_unused rofile,
    VAEntrypoint __maybe_unused entrypoint,
    VAConfigAttrib __maybe_unused * attrib_list,
    int __maybe_unused num_attribs)
{
    /* No specific attributes */
}

static VAStatus tng_yuv_processor_ValidateConfig(
    object_config_p __maybe_unused obj_config)
{
    return VA_STATUS_SUCCESS;
}

static VAStatus tng_yuv_processor_process_buffer( context_DEC_p, object_buffer_p);

static VAStatus tng_yuv_processor_CreateContext(
    object_context_p obj_context,
    object_config_p __maybe_unused obj_config)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    context_DEC_p dec_ctx = (context_DEC_p) obj_context->format_data;
    context_yuv_processor_p ctx;

    ctx = (context_yuv_processor_p) malloc(sizeof(struct context_yuv_processor_s));
    CHECK_ALLOCATION(ctx);

    /* ctx could be create in/out another dec context */
    ctx->has_dec_ctx = 0;
    ctx->src_surface = NULL;

    if (!dec_ctx) {
        dec_ctx = (context_DEC_p) malloc(sizeof(struct context_DEC_s));
        CHECK_ALLOCATION(dec_ctx);
        obj_context->format_data = (void *)dec_ctx;
        ctx->has_dec_ctx = 1;
        vaStatus = vld_dec_CreateContext(dec_ctx, obj_context);
        DEBUG_FAILURE;
    }

    dec_ctx->yuv_ctx = ctx;
    dec_ctx->process_buffer = tng_yuv_processor_process_buffer;

    return vaStatus;
}

static void tng_yuv_processor_DestroyContext(
    object_context_p obj_context)
{
    context_DEC_p dec_ctx = (context_DEC_p) obj_context->format_data;
    context_yuv_processor_p yuv_ctx = NULL;
    int has_dec_ctx = 0;

    if (dec_ctx == NULL)
        return;

    yuv_ctx = dec_ctx->yuv_ctx;

    if (yuv_ctx) {
        has_dec_ctx = yuv_ctx->has_dec_ctx;
        free(yuv_ctx);
        dec_ctx->yuv_ctx = NULL;
    }

    if (has_dec_ctx) {
        free(dec_ctx);
        obj_context->format_data = NULL;
    }
}

static VAStatus tng_yuv_processor_BeginPicture(
    object_context_p __maybe_unused obj_context)
{
    return VA_STATUS_SUCCESS;
}

static void tng__yuv_processor_process(context_DEC_p dec_ctx)
{
    context_yuv_processor_p ctx = dec_ctx->yuv_ctx;
    psb_cmdbuf_p cmdbuf = dec_ctx->obj_context->cmdbuf;
    /* psb_surface_p target_surface = dec_ctx->obj_context->current_render_target->psb_surface; */
    psb_surface_p src_surface = ctx->src_surface;
    psb_buffer_p buffer;
    uint32_t reg_value;

    psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE));

    reg_value = 0;
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, (ctx->display_height) - 1);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, (ctx->display_width) - 1);
    psb_cmdbuf_rendec_write(cmdbuf, reg_value);

    reg_value = 0;
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_HEIGHT, (ctx->coded_height) - 1);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_WIDTH, (ctx->coded_width) - 1);
    psb_cmdbuf_rendec_write(cmdbuf, reg_value);
    psb_cmdbuf_rendec_end(cmdbuf);


    /*TODO add stride and else there*/
    reg_value = 0;
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 3);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, 1);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, 1);
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, src_surface->stride_mode);

    psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_CMDS, OPERATING_MODE ));
    psb_cmdbuf_rendec_write(cmdbuf, reg_value);
    psb_cmdbuf_rendec_end(cmdbuf);

    psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES));
    buffer = &src_surface->buf;
    psb_cmdbuf_rendec_write_address(cmdbuf, buffer, buffer->buffer_ofs);
    psb_cmdbuf_rendec_write_address(cmdbuf, buffer,
                                    buffer->buffer_ofs +
                                    src_surface->chroma_offset);
    psb_cmdbuf_rendec_end(cmdbuf);

    reg_value = 0;
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, CONSTRAINED_INTRA_PRED, 0 );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, MODE_CONFIG, 0 );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, DISABLE_DEBLOCK_FILTER_IDC, 1 );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_ALPHA_CO_OFFSET_DIV2, 0 );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_BETA_OFFSET_DIV2, 0 );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_FIELD_TYPE, 2 );
    REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE, 1 ); // P
    *dec_ctx->p_slice_params = reg_value;

    psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_CMDS, SLICE_PARAMS ) );
    psb_cmdbuf_rendec_write(cmdbuf, reg_value);
    psb_cmdbuf_rendec_end(cmdbuf);

    vld_dec_setup_alternative_frame(dec_ctx->obj_context);

    *cmdbuf->cmd_idx++ = CMD_DEBLOCK | CMD_DEBLOCK_TYPE_SKIP;
    *cmdbuf->cmd_idx++ = 0;
    *cmdbuf->cmd_idx++ = ctx->coded_width / 16;
    *cmdbuf->cmd_idx++ = ctx->coded_height / 16;
    *cmdbuf->cmd_idx++ = 0;
    *cmdbuf->cmd_idx++ = 0;

}

static VAStatus tng__yuv_processor_execute(context_DEC_p dec_ctx, object_buffer_p obj_buffer)
{
    /* psb_surface_p target_surface = dec_ctx->obj_context->current_render_target->psb_surface; */
    context_yuv_processor_p ctx = dec_ctx->yuv_ctx;
    uint32_t reg_value;
    VAStatus vaStatus;

    ASSERT(obj_buffer->type == YUVProcessorSurfaceType ||
           obj_buffer->type == VAProcPipelineParameterBufferType);
    ASSERT(obj_buffer->num_elements == 1);
    ASSERT(obj_buffer->size == sizeof(struct surface_param_s));

    if ((obj_buffer->num_elements != 1) ||
        ((obj_buffer->size != sizeof(struct surface_param_s)) &&
        (obj_buffer->size != sizeof(VAProcPipelineParameterBuffer)))) {
        return VA_STATUS_ERROR_UNKNOWN;
    }

    /* yuv rotation issued from dec driver, TODO removed later */
    if (obj_buffer->type == YUVProcessorSurfaceType) {
        surface_param_p surface_params = (surface_param_p) obj_buffer->buffer_data;
        psb_surface_p rotate_surface = dec_ctx->obj_context->current_render_target->out_loop_surface;
        object_context_p obj_context = dec_ctx->obj_context;
        psb_driver_data_p driver_data = obj_context->driver_data;

        ctx->display_width = (surface_params->display_width + 0xf) & ~0xf;
        ctx->display_height = (surface_params->display_height + 0xf) & ~0xf;
        ctx->coded_width = (surface_params->coded_width + 0xf) & ~0xf;
        ctx->coded_height = (surface_params->coded_height + 0xf) & ~0xf;
        ctx->src_surface = surface_params->src_surface;

        ctx->proc_param = NULL;
        dec_ctx->obj_context->msvdx_rotate = obj_context->msvdx_rotate;
        SET_SURFACE_INFO_rotate(rotate_surface, dec_ctx->obj_context->msvdx_rotate);

        obj_buffer->buffer_data = NULL;
        obj_buffer->size = 0;

#ifdef PSBVIDEO_MSVDX_DEC_TILING
        if (GET_SURFACE_INFO_tiling(ctx->src_surface)) {
            unsigned long msvdx_tile = psb__tile_stride_log2_256(rotate_surface->stride);
            obj_context->msvdx_tile &= 0xf; /* clear rotate tile */
            obj_context->msvdx_tile |= (msvdx_tile << 4);
            obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */
            obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
            psb_update_context(driver_data, obj_context->ctp_type);
            drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context, msvdx_tiled is 0x%08x \n", obj_context->msvdx_tile);
        }
#endif
    } else if (obj_buffer->type == VAProcPipelineParameterBufferType) {
        VAProcPipelineParameterBuffer *vpp_params = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data;
        object_surface_p obj_surface = SURFACE(vpp_params->surface);
        psb_surface_p rotate_surface = dec_ctx->obj_context->current_render_target->psb_surface;

        if (obj_surface == NULL){
            vaStatus = VA_STATUS_ERROR_UNKNOWN;
            return vaStatus;
        }

        //ctx->display_width = ((vpp_params->surface_region->width + 0xf) & ~0xf);
        //ctx->display_height = ((vpp_params->surface_region->height + 0x1f) & ~0x1f);
        ctx->display_width = ((obj_surface->width + 0xf) & ~0xf);
        ctx->display_height = ((obj_surface->height + 0xf) & ~0xf);
        ctx->coded_width = ctx->display_width;
        ctx->coded_height = ctx->display_height;

        ctx->src_surface = obj_surface->psb_surface;
        dec_ctx->obj_context->msvdx_rotate = vpp_params->rotation_state;
        SET_SURFACE_INFO_rotate(rotate_surface, dec_ctx->obj_context->msvdx_rotate);

        ctx->proc_param = vpp_params;
        obj_buffer->buffer_data = NULL;
        obj_buffer->size = 0;

#ifdef PSBVIDEO_MSVDX_DEC_TILING
        object_context_p obj_context = dec_ctx->obj_context;
	psb_driver_data_p driver_data = obj_context->driver_data;
        drv_debug_msg(VIDEO_DEBUG_GENERAL, "attempt to update tile context\n");
        if (GET_SURFACE_INFO_tiling(ctx->src_surface)) {
            drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context\n");

            unsigned long msvdx_tile = psb__tile_stride_log2_256(rotate_surface->stride);
            obj_context->msvdx_tile &= 0xf; /* clear rotate tile */
            obj_context->msvdx_tile |= (msvdx_tile << 4);
            obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */
            obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
            psb_update_context(driver_data, obj_context->ctp_type);
            drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context, msvdx_tiled is 0x%08x \n", obj_context->msvdx_tile);
        }
#endif
    }

#ifdef ADNROID
        LOGV("%s, %d %d %d %d***************************************************\n",
                  __func__, ctx->display_width, ctx->display_height, ctx->coded_width, ctx->coded_height);
#endif

    vaStatus = VA_STATUS_SUCCESS;

    if (psb_context_get_next_cmdbuf(dec_ctx->obj_context)) {
        vaStatus = VA_STATUS_ERROR_UNKNOWN;
        DEBUG_FAILURE;
        return vaStatus;
    }
    /* ctx->begin_slice(ctx, slice_param); */
    vld_dec_FE_state(dec_ctx->obj_context, NULL);

    tng__yuv_processor_process(dec_ctx);
    /* ctx->process_slice(ctx, slice_param); */
    vld_dec_write_kick(dec_ctx->obj_context);

    dec_ctx->obj_context->video_op = psb_video_vld;
    dec_ctx->obj_context->flags = 0;

    /* ctx->end_slice(ctx); */
    dec_ctx->obj_context->flags = FW_VA_RENDER_IS_FIRST_SLICE | FW_VA_RENDER_IS_LAST_SLICE | FW_INTERNAL_CONTEXT_SWITCH;

    if (psb_context_submit_cmdbuf(dec_ctx->obj_context)) {
        vaStatus = VA_STATUS_ERROR_UNKNOWN;
    }
    return vaStatus;
}

static VAStatus tng_yuv_processor_process_buffer(
    context_DEC_p dec_ctx,
    object_buffer_p buffer)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    object_buffer_p obj_buffer = buffer;
    unsigned int type = obj_buffer->type;
    {
        switch (type) {
        case YUVProcessorSurfaceType:
        case VAProcPipelineParameterBufferType:
            vaStatus = tng__yuv_processor_execute(dec_ctx, obj_buffer);
            DEBUG_FAILURE;
            break;

        default:
            vaStatus = VA_STATUS_ERROR_UNKNOWN;
            DEBUG_FAILURE;
        }
    }

    return vaStatus;
}

static VAStatus tng_yuv_processor_EndPicture(
    object_context_p obj_context)
{
    context_DEC_p dec_ctx = (context_DEC_p) obj_context->format_data;
    context_yuv_processor_p ctx = dec_ctx->yuv_ctx;

    if (psb_context_flush_cmdbuf(obj_context)) {
        return VA_STATUS_ERROR_UNKNOWN;
    }

    if (ctx->proc_param) {
        free(ctx->proc_param);
        ctx->proc_param = NULL;
    }

    return VA_STATUS_SUCCESS;
}

struct format_vtable_s tng_yuv_processor_vtable = {
queryConfigAttributes:
    tng_yuv_processor_QueryConfigAttributes,
validateConfig:
    tng_yuv_processor_ValidateConfig,
createContext:
    tng_yuv_processor_CreateContext,
destroyContext:
    tng_yuv_processor_DestroyContext,
beginPicture:
    tng_yuv_processor_BeginPicture,
renderPicture:
    vld_dec_RenderPicture,
endPicture:
    tng_yuv_processor_EndPicture
};

#define VED_SUPPORTED_FILTERS_NUM 1
#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
#define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
#define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))

VAStatus ved_QueryVideoProcFilters(
    VADriverContextP    ctx,
    VAContextID         context,
    VAProcFilterType   *filters,
    unsigned int       *num_filters)
{
    INIT_DRIVER_DATA;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    object_context_p obj_context;
    object_config_p obj_config;
    VAEntrypoint tmp;
    int count;

    /* check if ctx is right */
    obj_context = CONTEXT(context);
    if (NULL == obj_context) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
        vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
        goto err;
    }

    obj_config = CONFIG(obj_context->config_id);
    if (NULL == obj_config) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
        goto err;
    }

    tmp = obj_config->entrypoint;
    if (tmp != VAEntrypointVideoProc) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "current entrypoint is %d, not VAEntrypointVideoProc\n", tmp);
        vaStatus = VA_STATUS_ERROR_UNKNOWN;
        goto err;
    }

    /* check if filters and num_filters is valid */
    if (NULL == num_filters || NULL == filters) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filters, filters);
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
        goto err;
    }

    /* check if the filter array size is valid */
    if (*num_filters < VED_SUPPORTED_FILTERS_NUM) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "The filters array size(%d) is NOT valid! Supported filters num is %d\n",
                *num_filters, VED_SUPPORTED_FILTERS_NUM);
        vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
        *num_filters = VED_SUPPORTED_FILTERS_NUM;
        goto err;
    }

    count = 0;
    filters[count++] = VAProcFilterNone;
    *num_filters = count;

err:
    return vaStatus;
}

VAStatus ved_QueryVideoProcFilterCaps(
        VADriverContextP    ctx,
        VAContextID         context,
        VAProcFilterType    type,
        void               *filter_caps,
        unsigned int       *num_filter_caps)
{
    INIT_DRIVER_DATA;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    object_context_p obj_context;
    object_config_p obj_config;
    VAProcFilterCap *no_cap;

    /* check if context is right */
    obj_context = CONTEXT(context);
    if (NULL == obj_context) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
        vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
        goto err;
    }

    obj_config = CONFIG(obj_context->config_id);
    if (NULL == obj_config) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
        goto err;
    }

    /* check if filter_caps and num_filter_caps is right */
    if (NULL == num_filter_caps || NULL == filter_caps){
        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filter_caps, filter_caps);
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
        goto err;
    }

    if (*num_filter_caps < 1) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters == %d (> 1)\n", *num_filter_caps);
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
        goto err;
    }

    /* check if curent HW support and return corresponding caps */
        /* FIXME: we should use a constant table to return caps */
    switch (type) {
    case VAProcFilterNone:
        no_cap = filter_caps;
        no_cap->range.min_value = 0;
        no_cap->range.max_value = 0;
        no_cap->range.default_value = 0;
        no_cap->range.step = 0;
        *num_filter_caps = 1;
        break;
    default:
        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide filter type %d\n", type);
        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
        *num_filter_caps = 0;
        goto err;
    }

err:
    return vaStatus;
}

VAStatus ved_QueryVideoProcPipelineCaps(
        VADriverContextP    ctx,
        VAContextID         context,
        VABufferID         *filters,
        unsigned int        num_filters,
        VAProcPipelineCaps *pipeline_caps)
{
    INIT_DRIVER_DATA;
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    object_context_p obj_context;
    object_config_p obj_config;
    VAProcFilterParameterBufferBase *base;
    object_buffer_p buf;

    /* check if ctx is right */
    obj_context = CONTEXT(context);
    if (NULL == obj_context) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
        vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
        goto err;
    }

    obj_config = CONFIG(obj_context->config_id);
    if (NULL == obj_config) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
        goto err;
    }

    /* check if filters and num_filters and pipeline-caps are right */
    if (num_filters != 1) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_filters %d\n", num_filters);
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
        goto err;
    }

    if (NULL == filters || pipeline_caps == NULL) {
        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filters %p or pipeline_caps %p\n", filters, pipeline_caps);
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
        goto err;
    }

    memset(pipeline_caps, 0, sizeof(*pipeline_caps));

    buf = BUFFER(*(filters));

    if (buf == NULL){
        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter buffer: NULL \n");
        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
        goto err;
    }

    base = (VAProcFilterParameterBufferBase *)buf->buffer_data;
    /* check filter buffer setting */
    switch (base->type) {
    case VAProcFilterNone:
        pipeline_caps->rotation_flags = (1 << VA_ROTATION_NONE);
        pipeline_caps->rotation_flags |= (1 << VA_ROTATION_90);
        pipeline_caps->rotation_flags |= (1 << VA_ROTATION_180);
        pipeline_caps->rotation_flags |= (1 << VA_ROTATION_270);
        break;

    default:
        drv_debug_msg(VIDEO_DEBUG_ERROR, "Do NOT support the filter type %d\n", base->type);
        vaStatus = VA_STATUS_ERROR_UNKNOWN;
        goto err;
    }
err:
    return vaStatus;
}
