tng_yuv_processor.c revision dbf2ee864763f6da009b5455943917c72e31e9ec
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@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
40static void tng_yuv_processor_QueryConfigAttributes(
41    VAProfile profile,
42    VAEntrypoint entrypoint,
43    VAConfigAttrib *attrib_list,
44    int num_attribs)
45{
46    /* No specific attributes */
47}
48
49static VAStatus tng_yuv_processor_ValidateConfig(
50    object_config_p obj_config)
51{
52    return VA_STATUS_SUCCESS;
53}
54
55static VAStatus tng_yuv_processor_process_buffer( context_DEC_p, object_buffer_p);
56
57static VAStatus tng_yuv_processor_CreateContext(
58    object_context_p obj_context,
59    object_config_p 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
87static 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
111static VAStatus tng_yuv_processor_BeginPicture(
112    object_context_p obj_context)
113{
114    return VA_STATUS_SUCCESS;
115}
116
117static 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
185static 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        ctx->display_width = surface_params->display_width;
207        ctx->display_height = surface_params->display_height;
208        ctx->coded_width = surface_params->coded_width;
209        ctx->coded_height = surface_params->coded_height;
210        ctx->src_surface = dec_ctx->obj_context->current_render_target->psb_surface;
211        ctx->proc_param = NULL;
212    } else if (obj_buffer->type == VAProcPipelineParameterBufferType) {
213        VAProcPipelineParameterBuffer *vpp_params = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data;
214        object_surface_p obj_surface = SURFACE(vpp_params->surface);
215        psb_surface_p rotate_surface = dec_ctx->obj_context->current_render_target->psb_surface;
216
217        if (obj_surface == NULL){
218            vaStatus = VA_STATUS_ERROR_UNKNOWN;
219            return vaStatus;
220        }
221
222        //ctx->display_width = ((vpp_params->surface_region->width + 0xf) & ~0xf);
223        //ctx->display_height = ((vpp_params->surface_region->height + 0x1f) & ~0x1f);
224        ctx->display_width = ((obj_surface->width + 0xf) & ~0xf);
225        ctx->display_height = ((obj_surface->height + 0xf) & ~0xf);
226        ctx->coded_width = ctx->display_width;
227        ctx->coded_height = ctx->display_height;
228
229        ctx->src_surface = obj_surface->psb_surface;
230        dec_ctx->obj_context->msvdx_rotate = vpp_params->rotation_state;
231        SET_SURFACE_INFO_rotate(rotate_surface, dec_ctx->obj_context->msvdx_rotate);
232
233        ctx->proc_param = vpp_params;
234        obj_buffer->buffer_data = NULL;
235        obj_buffer->size = 0;
236
237#ifdef PSBVIDEO_MSVDX_DEC_TILING
238        object_context_p obj_context = dec_ctx->obj_context;
239	psb_driver_data_p driver_data = obj_context->driver_data;
240        drv_debug_msg(VIDEO_DEBUG_GENERAL, "attempt to update tile context\n");
241        if (GET_SURFACE_INFO_tiling(ctx->src_surface)) {
242            drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context\n");
243
244            unsigned long msvdx_tile = psb__tile_stride_log2_256(rotate_surface->stride);
245            obj_context->msvdx_tile &= 0xf; /* clear rotate tile */
246            obj_context->msvdx_tile |= (msvdx_tile << 4);
247            obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */
248            obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16);
249            psb_update_context(driver_data, obj_context->ctp_type);
250            drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context, msvdx_tiled is 0x%08x \n", obj_context->msvdx_tile);
251        }
252#endif
253    }
254
255#ifdef ADNROID
256        LOGV("%s, %d %d %d %d***************************************************\n",
257                  __func__, ctx->display_width, ctx->display_height, ctx->coded_width, ctx->coded_height);
258#endif
259
260    vaStatus = VA_STATUS_SUCCESS;
261
262    if (psb_context_get_next_cmdbuf(dec_ctx->obj_context)) {
263        vaStatus = VA_STATUS_ERROR_UNKNOWN;
264        DEBUG_FAILURE;
265        return vaStatus;
266    }
267    /* ctx->begin_slice(ctx, slice_param); */
268    vld_dec_FE_state(dec_ctx->obj_context, NULL);
269
270    tng__yuv_processor_process(dec_ctx);
271    /* ctx->process_slice(ctx, slice_param); */
272    vld_dec_write_kick(dec_ctx->obj_context);
273
274    dec_ctx->obj_context->video_op = psb_video_vld;
275    dec_ctx->obj_context->flags = 0;
276
277    /* ctx->end_slice(ctx); */
278    dec_ctx->obj_context->flags = FW_VA_RENDER_IS_FIRST_SLICE | FW_VA_RENDER_IS_LAST_SLICE | FW_INTERNAL_CONTEXT_SWITCH;
279
280    if (psb_context_submit_cmdbuf(dec_ctx->obj_context)) {
281        vaStatus = VA_STATUS_ERROR_UNKNOWN;
282    }
283    return vaStatus;
284}
285
286static VAStatus tng_yuv_processor_process_buffer(
287    context_DEC_p dec_ctx,
288    object_buffer_p buffer)
289{
290    VAStatus vaStatus = VA_STATUS_SUCCESS;
291    object_buffer_p obj_buffer = buffer;
292
293    {
294        switch (obj_buffer->type) {
295        case YUVProcessorSurfaceType:
296        case VAProcPipelineParameterBufferType:
297            vaStatus = tng__yuv_processor_execute(dec_ctx, obj_buffer);
298            DEBUG_FAILURE;
299            break;
300
301        default:
302            vaStatus = VA_STATUS_ERROR_UNKNOWN;
303            DEBUG_FAILURE;
304        }
305    }
306
307    return vaStatus;
308}
309
310static VAStatus tng_yuv_processor_EndPicture(
311    object_context_p obj_context)
312{
313    context_DEC_p dec_ctx = (context_DEC_p) obj_context->format_data;
314    context_yuv_processor_p ctx = dec_ctx->yuv_ctx;
315
316    if (psb_context_flush_cmdbuf(obj_context)) {
317        return VA_STATUS_ERROR_UNKNOWN;
318    }
319
320    if (ctx->proc_param) {
321        free(ctx->proc_param);
322        ctx->proc_param = NULL;
323    }
324
325    return VA_STATUS_SUCCESS;
326}
327
328struct format_vtable_s tng_yuv_processor_vtable = {
329queryConfigAttributes:
330    tng_yuv_processor_QueryConfigAttributes,
331validateConfig:
332    tng_yuv_processor_ValidateConfig,
333createContext:
334    tng_yuv_processor_CreateContext,
335destroyContext:
336    tng_yuv_processor_DestroyContext,
337beginPicture:
338    tng_yuv_processor_BeginPicture,
339renderPicture:
340    vld_dec_RenderPicture,
341endPicture:
342    tng_yuv_processor_EndPicture
343};
344
345#define VED_SUPPORTED_FILTERS_NUM 1
346#define INIT_DRIVER_DATA    psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData;
347#define CONFIG(id)  ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
348#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
349#define BUFFER(id)  ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id ))
350
351VAStatus ved_QueryVideoProcFilters(
352    VADriverContextP    ctx,
353    VAContextID         context,
354    VAProcFilterType   *filters,
355    unsigned int       *num_filters)
356{
357    INIT_DRIVER_DATA;
358    VAStatus vaStatus = VA_STATUS_SUCCESS;
359    object_context_p obj_context;
360    object_config_p obj_config;
361    VAEntrypoint tmp;
362    int count;
363
364    /* check if ctx is right */
365    obj_context = CONTEXT(context);
366    if (NULL == obj_context) {
367        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
368        vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
369        goto err;
370    }
371
372    obj_config = CONFIG(obj_context->config_id);
373    if (NULL == obj_config) {
374        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
375        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
376        goto err;
377    }
378
379    tmp = obj_config->entrypoint;
380    if (tmp != VAEntrypointVideoProc) {
381        drv_debug_msg(VIDEO_DEBUG_ERROR, "current entrypoint is %d, not VAEntrypointVideoProc\n", tmp);
382        vaStatus = VA_STATUS_ERROR_UNKNOWN;
383        goto err;
384    }
385
386    /* check if filters and num_filters is valid */
387    if (NULL == num_filters || NULL == filters) {
388        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filters, filters);
389        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
390        goto err;
391    }
392
393    /* check if the filter array size is valid */
394    if (*num_filters < VED_SUPPORTED_FILTERS_NUM) {
395        drv_debug_msg(VIDEO_DEBUG_ERROR, "The filters array size(%d) is NOT valid! Supported filters num is %d\n",
396                *num_filters, VED_SUPPORTED_FILTERS_NUM);
397        vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
398        *num_filters = VED_SUPPORTED_FILTERS_NUM;
399        goto err;
400    }
401
402    count = 0;
403    filters[count++] = VAProcFilterNone;
404    *num_filters = count;
405
406err:
407    return vaStatus;
408}
409
410VAStatus ved_QueryVideoProcFilterCaps(
411        VADriverContextP    ctx,
412        VAContextID         context,
413        VAProcFilterType    type,
414        void               *filter_caps,
415        unsigned int       *num_filter_caps)
416{
417    INIT_DRIVER_DATA;
418    VAStatus vaStatus = VA_STATUS_SUCCESS;
419    object_context_p obj_context;
420    object_config_p obj_config;
421    VAProcFilterCap *no_cap;
422
423    /* check if context is right */
424    obj_context = CONTEXT(context);
425    if (NULL == obj_context) {
426        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
427        vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
428        goto err;
429    }
430
431    obj_config = CONFIG(obj_context->config_id);
432    if (NULL == obj_config) {
433        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
434        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
435        goto err;
436    }
437
438    /* check if filter_caps and num_filter_caps is right */
439    if (NULL == num_filter_caps || NULL == filter_caps){
440        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filter_caps, filter_caps);
441        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
442        goto err;
443    }
444
445    if (*num_filter_caps < 1) {
446        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters == %d (> 1)\n", *num_filter_caps);
447        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
448        goto err;
449    }
450
451    /* check if curent HW support and return corresponding caps */
452        /* FIXME: we should use a constant table to return caps */
453    switch (type) {
454    case VAProcFilterNone:
455        no_cap = filter_caps;
456        no_cap->range.min_value = 0;
457        no_cap->range.max_value = 0;
458        no_cap->range.default_value = 0;
459        no_cap->range.step = 0;
460        *num_filter_caps = 1;
461        break;
462    default:
463        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide filter type %d\n", type);
464        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER;
465        *num_filter_caps = 0;
466        goto err;
467    }
468
469err:
470    return vaStatus;
471}
472
473VAStatus ved_QueryVideoProcPipelineCaps(
474        VADriverContextP    ctx,
475        VAContextID         context,
476        VABufferID         *filters,
477        unsigned int        num_filters,
478        VAProcPipelineCaps *pipeline_caps)
479{
480    INIT_DRIVER_DATA;
481    VAStatus vaStatus = VA_STATUS_SUCCESS;
482    object_context_p obj_context;
483    object_config_p obj_config;
484    VAProcFilterParameterBufferBase *base;
485    object_buffer_p buf;
486
487    /* check if ctx is right */
488    obj_context = CONTEXT(context);
489    if (NULL == obj_context) {
490        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n");
491        vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
492        goto err;
493    }
494
495    obj_config = CONFIG(obj_context->config_id);
496    if (NULL == obj_config) {
497        drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n");
498        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
499        goto err;
500    }
501
502    /* check if filters and num_filters and pipeline-caps are right */
503    if (num_filters != 1) {
504        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_filters %d\n", num_filters);
505        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
506        goto err;
507    }
508
509    if (NULL == filters || pipeline_caps == NULL) {
510        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filters %p or pipeline_caps %p\n", filters, pipeline_caps);
511        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
512        goto err;
513    }
514
515    memset(pipeline_caps, 0, sizeof(*pipeline_caps));
516
517    buf = BUFFER(*(filters));
518
519    if (buf == NULL){
520        drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter buffer: NULL \n");
521        vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER;
522        goto err;
523    }
524
525    base = (VAProcFilterParameterBufferBase *)buf->buffer_data;
526    /* check filter buffer setting */
527    switch (base->type) {
528    case VAProcFilterNone:
529        pipeline_caps->rotation_flags = (1 << VA_ROTATION_NONE);
530        pipeline_caps->rotation_flags |= (1 << VA_ROTATION_90);
531        pipeline_caps->rotation_flags |= (1 << VA_ROTATION_180);
532        pipeline_caps->rotation_flags |= (1 << VA_ROTATION_270);
533        break;
534
535    default:
536        drv_debug_msg(VIDEO_DEBUG_ERROR, "Do NOT support the filter type %d\n", base->type);
537        vaStatus = VA_STATUS_ERROR_UNKNOWN;
538        goto err;
539    }
540err:
541    return vaStatus;
542}
543