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 #include <malloc.h>
39
40 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &dec_ctx->obj_context->driver_data->surface_heap, id ))
41
tng_yuv_processor_QueryConfigAttributes(VAProfile __maybe_unused rofile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib __maybe_unused * attrib_list,int __maybe_unused num_attribs)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
tng_yuv_processor_ValidateConfig(object_config_p __maybe_unused obj_config)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
tng_yuv_processor_CreateContext(object_context_p obj_context,object_config_p __maybe_unused obj_config)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
tng_yuv_processor_DestroyContext(object_context_p obj_context)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
tng_yuv_processor_BeginPicture(object_context_p __maybe_unused obj_context)118 static VAStatus tng_yuv_processor_BeginPicture(
119 object_context_p __maybe_unused obj_context)
120 {
121 return VA_STATUS_SUCCESS;
122 }
123
tng__yuv_processor_process(context_DEC_p dec_ctx)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
tng__yuv_processor_execute(context_DEC_p dec_ctx,object_buffer_p obj_buffer)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
tng_yuv_processor_process_buffer(context_DEC_p dec_ctx,object_buffer_p buffer)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
tng_yuv_processor_EndPicture(object_context_p obj_context)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
ved_QueryVideoProcFilters(VADriverContextP ctx,VAContextID context,VAProcFilterType * filters,unsigned int * num_filters)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
ved_QueryVideoProcFilterCaps(VADriverContextP ctx,VAContextID context,VAProcFilterType type,void * filter_caps,unsigned int * num_filter_caps)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
ved_QueryVideoProcPipelineCaps(VADriverContextP ctx,VAContextID context,VABufferID * filters,unsigned int num_filters,VAProcPipelineCaps * pipeline_caps)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