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