Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
      3  * Copyright (c) Imagination Technologies Limited, UK
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sub license, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial portions
     15  * of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     20  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
     21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 /*
     27  * Authors:
     28  *    Li Zeng <li.zeng (at) intel.com>
     29  */
     30 
     31 #include "tng_vld_dec.h"
     32 #include "psb_drv_debug.h"
     33 #include "hwdefs/dxva_fw_ctrl.h"
     34 #include "hwdefs/reg_io2.h"
     35 #include "hwdefs/msvdx_offsets.h"
     36 #include "hwdefs/msvdx_cmds_io2.h"
     37 
     38 #define SURFACE(id)   ((object_surface_p) object_heap_lookup( &dec_ctx->obj_context->driver_data->surface_heap, id ))
     39 
     40 static void tng_yuv_processor_QueryConfigAttributes(
     41     VAProfile __maybe_unused rofile,
     42     VAEntrypoint __maybe_unused entrypoint,
     43     VAConfigAttrib __maybe_unused * attrib_list,
     44     int __maybe_unused num_attribs)
     45 {
     46     /* No specific attributes */
     47 }
     48 
     49 static VAStatus tng_yuv_processor_ValidateConfig(
     50     object_config_p __maybe_unused obj_config)
     51 {
     52     return VA_STATUS_SUCCESS;
     53 }
     54 
     55 static VAStatus tng_yuv_processor_process_buffer( context_DEC_p, object_buffer_p);
     56 
     57 static VAStatus tng_yuv_processor_CreateContext(
     58     object_context_p obj_context,
     59     object_config_p __maybe_unused obj_config)
     60 {
     61     VAStatus vaStatus = VA_STATUS_SUCCESS;
     62     context_DEC_p dec_ctx = (context_DEC_p) obj_context->format_data;
     63     context_yuv_processor_p ctx;
     64 
     65     ctx = (context_yuv_processor_p) malloc(sizeof(struct context_yuv_processor_s));
     66     CHECK_ALLOCATION(ctx);
     67 
     68     /* ctx could be create in/out another dec context */
     69     ctx->has_dec_ctx = 0;
     70     ctx->src_surface = NULL;
     71 
     72     if (!dec_ctx) {
     73         dec_ctx = (context_DEC_p) malloc(sizeof(struct context_DEC_s));
     74         CHECK_ALLOCATION(dec_ctx);
     75         obj_context->format_data = (void *)dec_ctx;
     76         ctx->has_dec_ctx = 1;
     77         vaStatus = vld_dec_CreateContext(dec_ctx, obj_context);
     78         DEBUG_FAILURE;
     79     }
     80 
     81     dec_ctx->yuv_ctx = ctx;
     82     dec_ctx->process_buffer = tng_yuv_processor_process_buffer;
     83 
     84     return vaStatus;
     85 }
     86 
     87 static void tng_yuv_processor_DestroyContext(
     88     object_context_p obj_context)
     89 {
     90     context_DEC_p dec_ctx = (context_DEC_p) obj_context->format_data;
     91     context_yuv_processor_p yuv_ctx = NULL;
     92     int has_dec_ctx = 0;
     93 
     94     if (dec_ctx == NULL)
     95         return;
     96 
     97     yuv_ctx = dec_ctx->yuv_ctx;
     98 
     99     if (yuv_ctx) {
    100         has_dec_ctx = yuv_ctx->has_dec_ctx;
    101         free(yuv_ctx);
    102         dec_ctx->yuv_ctx = NULL;
    103     }
    104 
    105     if (has_dec_ctx) {
    106         free(dec_ctx);
    107         obj_context->format_data = NULL;
    108     }
    109 }
    110 
    111 static VAStatus tng_yuv_processor_BeginPicture(
    112     object_context_p __maybe_unused obj_context)
    113 {
    114     return VA_STATUS_SUCCESS;
    115 }
    116 
    117 static void tng__yuv_processor_process(context_DEC_p dec_ctx)
    118 {
    119     context_yuv_processor_p ctx = dec_ctx->yuv_ctx;
    120     psb_cmdbuf_p cmdbuf = dec_ctx->obj_context->cmdbuf;
    121     /* psb_surface_p target_surface = dec_ctx->obj_context->current_render_target->psb_surface; */
    122     psb_surface_p src_surface = ctx->src_surface;
    123     psb_buffer_p buffer;
    124     uint32_t reg_value;
    125 
    126     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE));
    127 
    128     reg_value = 0;
    129     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, (ctx->display_height) - 1);
    130     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, (ctx->display_width) - 1);
    131     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
    132 
    133     reg_value = 0;
    134     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_HEIGHT, (ctx->coded_height) - 1);
    135     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_WIDTH, (ctx->coded_width) - 1);
    136     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
    137     psb_cmdbuf_rendec_end(cmdbuf);
    138 
    139 
    140     /*TODO add stride and else there*/
    141     reg_value = 0;
    142     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 3);
    143     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1);
    144     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, 1);
    145     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, 1);
    146     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, src_surface->stride_mode);
    147 
    148     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_CMDS, OPERATING_MODE ));
    149     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
    150     psb_cmdbuf_rendec_end(cmdbuf);
    151 
    152     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES));
    153     buffer = &src_surface->buf;
    154     psb_cmdbuf_rendec_write_address(cmdbuf, buffer, buffer->buffer_ofs);
    155     psb_cmdbuf_rendec_write_address(cmdbuf, buffer,
    156                                     buffer->buffer_ofs +
    157                                     src_surface->chroma_offset);
    158     psb_cmdbuf_rendec_end(cmdbuf);
    159 
    160     reg_value = 0;
    161     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, CONSTRAINED_INTRA_PRED, 0 );
    162     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, MODE_CONFIG, 0 );
    163     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, DISABLE_DEBLOCK_FILTER_IDC, 1 );
    164     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_ALPHA_CO_OFFSET_DIV2, 0 );
    165     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_BETA_OFFSET_DIV2, 0 );
    166     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_FIELD_TYPE, 2 );
    167     REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE, 1 ); // P
    168     *dec_ctx->p_slice_params = reg_value;
    169 
    170     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET( MSVDX_CMDS, SLICE_PARAMS ) );
    171     psb_cmdbuf_rendec_write(cmdbuf, reg_value);
    172     psb_cmdbuf_rendec_end(cmdbuf);
    173 
    174     vld_dec_setup_alternative_frame(dec_ctx->obj_context);
    175 
    176     *cmdbuf->cmd_idx++ = CMD_DEBLOCK | CMD_DEBLOCK_TYPE_SKIP;
    177     *cmdbuf->cmd_idx++ = 0;
    178     *cmdbuf->cmd_idx++ = ctx->coded_width / 16;
    179     *cmdbuf->cmd_idx++ = ctx->coded_height / 16;
    180     *cmdbuf->cmd_idx++ = 0;
    181     *cmdbuf->cmd_idx++ = 0;
    182 
    183 }
    184 
    185 static VAStatus tng__yuv_processor_execute(context_DEC_p dec_ctx, object_buffer_p obj_buffer)
    186 {
    187     /* psb_surface_p target_surface = dec_ctx->obj_context->current_render_target->psb_surface; */
    188     context_yuv_processor_p ctx = dec_ctx->yuv_ctx;
    189     uint32_t reg_value;
    190     VAStatus vaStatus;
    191 
    192     ASSERT(obj_buffer->type == YUVProcessorSurfaceType ||
    193            obj_buffer->type == VAProcPipelineParameterBufferType);
    194     ASSERT(obj_buffer->num_elements == 1);
    195     ASSERT(obj_buffer->size == sizeof(struct surface_param_s));
    196 
    197     if ((obj_buffer->num_elements != 1) ||
    198         ((obj_buffer->size != sizeof(struct surface_param_s)) &&
    199         (obj_buffer->size != sizeof(VAProcPipelineParameterBuffer)))) {
    200         return VA_STATUS_ERROR_UNKNOWN;
    201     }
    202 
    203     /* yuv rotation issued from dec driver, TODO removed later */
    204     if (obj_buffer->type == YUVProcessorSurfaceType) {
    205         surface_param_p surface_params = (surface_param_p) obj_buffer->buffer_data;
    206         psb_surface_p rotate_surface = dec_ctx->obj_context->current_render_target->out_loop_surface;
    207         object_context_p obj_context = dec_ctx->obj_context;
    208         psb_driver_data_p driver_data = obj_context->driver_data;
    209 
    210         ctx->display_width = (surface_params->display_width + 0xf) & ~0xf;
    211         ctx->display_height = (surface_params->display_height + 0xf) & ~0xf;
    212         ctx->coded_width = (surface_params->coded_width + 0xf) & ~0xf;
    213         ctx->coded_height = (surface_params->coded_height + 0xf) & ~0xf;
    214         ctx->src_surface = surface_params->src_surface;
    215 
    216         ctx->proc_param = NULL;
    217         dec_ctx->obj_context->msvdx_rotate = obj_context->msvdx_rotate;
    218         SET_SURFACE_INFO_rotate(rotate_surface, dec_ctx->obj_context->msvdx_rotate);
    219 
    220         obj_buffer->buffer_data = NULL;
    221         obj_buffer->size = 0;
    222 
    223 #ifdef PSBVIDEO_MSVDX_DEC_TILING
    224         if (GET_SURFACE_INFO_tiling(ctx->src_surface)) {
    225             unsigned long msvdx_tile = psb__tile_stride_log2_256(rotate_surface->stride);
    226             obj_context->msvdx_tile &= 0xf; /* clear rotate tile */
    227             obj_context->msvdx_tile |= (msvdx_tile << 4);
    228             obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */
    229             obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
    230             psb_update_context(driver_data, obj_context->ctp_type);
    231             drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context, msvdx_tiled is 0x%08x \n", obj_context->msvdx_tile);
    232         }
    233 #endif
    234     } else if (obj_buffer->type == VAProcPipelineParameterBufferType) {
    235         VAProcPipelineParameterBuffer *vpp_params = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data;
    236         object_surface_p obj_surface = SURFACE(vpp_params->surface);
    237         psb_surface_p rotate_surface = dec_ctx->obj_context->current_render_target->psb_surface;
    238 
    239         if (obj_surface == NULL){
    240             vaStatus = VA_STATUS_ERROR_UNKNOWN;
    241             return vaStatus;
    242         }
    243 
    244         //ctx->display_width = ((vpp_params->surface_region->width + 0xf) & ~0xf);
    245         //ctx->display_height = ((vpp_params->surface_region->height + 0x1f) & ~0x1f);
    246         ctx->display_width = ((obj_surface->width + 0xf) & ~0xf);
    247         ctx->display_height = ((obj_surface->height + 0xf) & ~0xf);
    248         ctx->coded_width = ctx->display_width;
    249         ctx->coded_height = ctx->display_height;
    250 
    251         ctx->src_surface = obj_surface->psb_surface;
    252         dec_ctx->obj_context->msvdx_rotate = vpp_params->rotation_state;
    253         SET_SURFACE_INFO_rotate(rotate_surface, dec_ctx->obj_context->msvdx_rotate);
    254 
    255         ctx->proc_param = vpp_params;
    256         obj_buffer->buffer_data = NULL;
    257         obj_buffer->size = 0;
    258 
    259 #ifdef PSBVIDEO_MSVDX_DEC_TILING
    260         object_context_p obj_context = dec_ctx->obj_context;
    261 	psb_driver_data_p driver_data = obj_context->driver_data;
    262         drv_debug_msg(VIDEO_DEBUG_GENERAL, "attempt to update tile context\n");
    263         if (GET_SURFACE_INFO_tiling(ctx->src_surface)) {
    264             drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context\n");
    265 
    266             unsigned long msvdx_tile = psb__tile_stride_log2_256(rotate_surface->stride);
    267             obj_context->msvdx_tile &= 0xf; /* clear rotate tile */
    268             obj_context->msvdx_tile |= (msvdx_tile << 4);
    269             obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */
    270             obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
    271             psb_update_context(driver_data, obj_context->ctp_type);
    272             drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context, msvdx_tiled is 0x%08x \n", obj_context->msvdx_tile);
    273         }
    274 #endif
    275     }
    276 
    277 #ifdef ADNROID
    278         LOGV("%s, %d %d %d %d***************************************************\n",
    279                   __func__, ctx->display_width, ctx->display_height, ctx->coded_width, ctx->coded_height);
    280 #endif
    281 
    282     vaStatus = VA_STATUS_SUCCESS;
    283 
    284     if (psb_context_get_next_cmdbuf(dec_ctx->obj_context)) {
    285         vaStatus = VA_STATUS_ERROR_UNKNOWN;
    286         DEBUG_FAILURE;
    287         return vaStatus;
    288     }
    289     /* ctx->begin_slice(ctx, slice_param); */
    290     vld_dec_FE_state(dec_ctx->obj_context, NULL);
    291 
    292     tng__yuv_processor_process(dec_ctx);
    293     /* ctx->process_slice(ctx, slice_param); */
    294     vld_dec_write_kick(dec_ctx->obj_context);
    295 
    296     dec_ctx->obj_context->video_op = psb_video_vld;
    297     dec_ctx->obj_context->flags = 0;
    298 
    299     /* ctx->end_slice(ctx); */
    300     dec_ctx->obj_context->flags = FW_VA_RENDER_IS_FIRST_SLICE | FW_VA_RENDER_IS_LAST_SLICE | FW_INTERNAL_CONTEXT_SWITCH;
    301 
    302     if (psb_context_submit_cmdbuf(dec_ctx->obj_context)) {
    303         vaStatus = VA_STATUS_ERROR_UNKNOWN;
    304     }
    305     return vaStatus;
    306 }
    307 
    308 static VAStatus tng_yuv_processor_process_buffer(
    309     context_DEC_p dec_ctx,
    310     object_buffer_p buffer)
    311 {
    312     VAStatus vaStatus = VA_STATUS_SUCCESS;
    313     object_buffer_p obj_buffer = buffer;
    314     unsigned int type = obj_buffer->type;
    315     {
    316         switch (type) {
    317         case YUVProcessorSurfaceType:
    318         case VAProcPipelineParameterBufferType:
    319             vaStatus = tng__yuv_processor_execute(dec_ctx, obj_buffer);
    320             DEBUG_FAILURE;
    321             break;
    322 
    323         default:
    324             vaStatus = VA_STATUS_ERROR_UNKNOWN;
    325             DEBUG_FAILURE;
    326         }
    327     }
    328 
    329     return vaStatus;
    330 }
    331 
    332 static VAStatus tng_yuv_processor_EndPicture(
    333     object_context_p obj_context)
    334 {
    335     context_DEC_p dec_ctx = (context_DEC_p) obj_context->format_data;
    336     context_yuv_processor_p ctx = dec_ctx->yuv_ctx;
    337 
    338     if (psb_context_flush_cmdbuf(obj_context)) {
    339         return VA_STATUS_ERROR_UNKNOWN;
    340     }
    341 
    342     if (ctx->proc_param) {
    343         free(ctx->proc_param);
    344         ctx->proc_param = NULL;
    345     }
    346 
    347     return VA_STATUS_SUCCESS;
    348 }
    349 
    350 struct format_vtable_s tng_yuv_processor_vtable = {
    351 queryConfigAttributes:
    352     tng_yuv_processor_QueryConfigAttributes,
    353 validateConfig:
    354     tng_yuv_processor_ValidateConfig,
    355 createContext:
    356     tng_yuv_processor_CreateContext,
    357 destroyContext:
    358     tng_yuv_processor_DestroyContext,
    359 beginPicture:
    360     tng_yuv_processor_BeginPicture,
    361 renderPicture:
    362     vld_dec_RenderPicture,
    363 endPicture:
    364     tng_yuv_processor_EndPicture
    365 };
    366 
    367 #define VED_SUPPORTED_FILTERS_NUM 1
    368 #define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
    369 #define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
    370 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
    371 #define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
    372 
    373 VAStatus ved_QueryVideoProcFilters(
    374     VADriverContextP    ctx,
    375     VAContextID         context,
    376     VAProcFilterType   *filters,
    377     unsigned int       *num_filters)
    378 {
    379     INIT_DRIVER_DATA;
    380     VAStatus vaStatus = VA_STATUS_SUCCESS;
    381     object_context_p obj_context;
    382     object_config_p obj_config;
    383     VAEntrypoint tmp;
    384     int count;
    385 
    386     /* check if ctx is right */
    387     obj_context = CONTEXT(context);
    388     if (NULL == obj_context) {
    389         drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
    390         vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
    391         goto err;
    392     }
    393 
    394     obj_config = CONFIG(obj_context->config_id);
    395     if (NULL == obj_config) {
    396         drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
    397         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
    398         goto err;
    399     }
    400 
    401     tmp = obj_config->entrypoint;
    402     if (tmp != VAEntrypointVideoProc) {
    403         drv_debug_msg(VIDEO_DEBUG_ERROR, "current entrypoint is %d, not VAEntrypointVideoProc\n", tmp);
    404         vaStatus = VA_STATUS_ERROR_UNKNOWN;
    405         goto err;
    406     }
    407 
    408     /* check if filters and num_filters is valid */
    409     if (NULL == num_filters || NULL == filters) {
    410         drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filters, filters);
    411         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
    412         goto err;
    413     }
    414 
    415     /* check if the filter array size is valid */
    416     if (*num_filters < VED_SUPPORTED_FILTERS_NUM) {
    417         drv_debug_msg(VIDEO_DEBUG_ERROR, "The filters array size(%d) is NOT valid! Supported filters num is %d\n",
    418                 *num_filters, VED_SUPPORTED_FILTERS_NUM);
    419         vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
    420         *num_filters = VED_SUPPORTED_FILTERS_NUM;
    421         goto err;
    422     }
    423 
    424     count = 0;
    425     filters[count++] = VAProcFilterNone;
    426     *num_filters = count;
    427 
    428 err:
    429     return vaStatus;
    430 }
    431 
    432 VAStatus ved_QueryVideoProcFilterCaps(
    433         VADriverContextP    ctx,
    434         VAContextID         context,
    435         VAProcFilterType    type,
    436         void               *filter_caps,
    437         unsigned int       *num_filter_caps)
    438 {
    439     INIT_DRIVER_DATA;
    440     VAStatus vaStatus = VA_STATUS_SUCCESS;
    441     object_context_p obj_context;
    442     object_config_p obj_config;
    443     VAProcFilterCap *no_cap;
    444 
    445     /* check if context is right */
    446     obj_context = CONTEXT(context);
    447     if (NULL == obj_context) {
    448         drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
    449         vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
    450         goto err;
    451     }
    452 
    453     obj_config = CONFIG(obj_context->config_id);
    454     if (NULL == obj_config) {
    455         drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
    456         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
    457         goto err;
    458     }
    459 
    460     /* check if filter_caps and num_filter_caps is right */
    461     if (NULL == num_filter_caps || NULL == filter_caps){
    462         drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filter_caps, filter_caps);
    463         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
    464         goto err;
    465     }
    466 
    467     if (*num_filter_caps < 1) {
    468         drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters == %d (> 1)\n", *num_filter_caps);
    469         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
    470         goto err;
    471     }
    472 
    473     /* check if curent HW support and return corresponding caps */
    474         /* FIXME: we should use a constant table to return caps */
    475     switch (type) {
    476     case VAProcFilterNone:
    477         no_cap = filter_caps;
    478         no_cap->range.min_value = 0;
    479         no_cap->range.max_value = 0;
    480         no_cap->range.default_value = 0;
    481         no_cap->range.step = 0;
    482         *num_filter_caps = 1;
    483         break;
    484     default:
    485         drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide filter type %d\n", type);
    486         vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
    487         *num_filter_caps = 0;
    488         goto err;
    489     }
    490 
    491 err:
    492     return vaStatus;
    493 }
    494 
    495 VAStatus ved_QueryVideoProcPipelineCaps(
    496         VADriverContextP    ctx,
    497         VAContextID         context,
    498         VABufferID         *filters,
    499         unsigned int        num_filters,
    500         VAProcPipelineCaps *pipeline_caps)
    501 {
    502     INIT_DRIVER_DATA;
    503     VAStatus vaStatus = VA_STATUS_SUCCESS;
    504     object_context_p obj_context;
    505     object_config_p obj_config;
    506     VAProcFilterParameterBufferBase *base;
    507     object_buffer_p buf;
    508 
    509     /* check if ctx is right */
    510     obj_context = CONTEXT(context);
    511     if (NULL == obj_context) {
    512         drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
    513         vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
    514         goto err;
    515     }
    516 
    517     obj_config = CONFIG(obj_context->config_id);
    518     if (NULL == obj_config) {
    519         drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
    520         vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
    521         goto err;
    522     }
    523 
    524     /* check if filters and num_filters and pipeline-caps are right */
    525     if (num_filters != 1) {
    526         drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_filters %d\n", num_filters);
    527         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
    528         goto err;
    529     }
    530 
    531     if (NULL == filters || pipeline_caps == NULL) {
    532         drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filters %p or pipeline_caps %p\n", filters, pipeline_caps);
    533         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
    534         goto err;
    535     }
    536 
    537     memset(pipeline_caps, 0, sizeof(*pipeline_caps));
    538 
    539     buf = BUFFER(*(filters));
    540 
    541     if (buf == NULL){
    542         drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter buffer: NULL \n");
    543         vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
    544         goto err;
    545     }
    546 
    547     base = (VAProcFilterParameterBufferBase *)buf->buffer_data;
    548     /* check filter buffer setting */
    549     switch (base->type) {
    550     case VAProcFilterNone:
    551         pipeline_caps->rotation_flags = (1 << VA_ROTATION_NONE);
    552         pipeline_caps->rotation_flags |= (1 << VA_ROTATION_90);
    553         pipeline_caps->rotation_flags |= (1 << VA_ROTATION_180);
    554         pipeline_caps->rotation_flags |= (1 << VA_ROTATION_270);
    555         break;
    556 
    557     default:
    558         drv_debug_msg(VIDEO_DEBUG_ERROR, "Do NOT support the filter type %d\n", base->type);
    559         vaStatus = VA_STATUS_ERROR_UNKNOWN;
    560         goto err;
    561     }
    562 err:
    563     return vaStatus;
    564 }
    565