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