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