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 
tng_yuv_processor_QueryConfigAttributes(VAProfile __maybe_unused rofile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib __maybe_unused * attrib_list,int __maybe_unused num_attribs)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 
tng_yuv_processor_ValidateConfig(object_config_p __maybe_unused obj_config)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 
tng_yuv_processor_CreateContext(object_context_p obj_context,object_config_p __maybe_unused obj_config)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 
tng_yuv_processor_DestroyContext(object_context_p obj_context)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 
tng_yuv_processor_BeginPicture(object_context_p __maybe_unused obj_context)111 static VAStatus tng_yuv_processor_BeginPicture(
112     object_context_p __maybe_unused obj_context)
113 {
114     return VA_STATUS_SUCCESS;
115 }
116 
tng__yuv_processor_process(context_DEC_p dec_ctx)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 
tng__yuv_processor_execute(context_DEC_p dec_ctx,object_buffer_p obj_buffer)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 
tng_yuv_processor_process_buffer(context_DEC_p dec_ctx,object_buffer_p buffer)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 
tng_yuv_processor_EndPicture(object_context_p obj_context)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 
ved_QueryVideoProcFilters(VADriverContextP ctx,VAContextID context,VAProcFilterType * filters,unsigned int * num_filters)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 
ved_QueryVideoProcFilterCaps(VADriverContextP ctx,VAContextID context,VAProcFilterType type,void * filter_caps,unsigned int * num_filter_caps)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 
ved_QueryVideoProcPipelineCaps(VADriverContextP ctx,VAContextID context,VABufferID * filters,unsigned int num_filters,VAProcPipelineCaps * pipeline_caps)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