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 __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 49static VAStatus tng_yuv_processor_ValidateConfig( 50 object_config_p __maybe_unused 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 __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 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 __maybe_unused 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 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 308static 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 332static 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 350struct format_vtable_s tng_yuv_processor_vtable = { 351queryConfigAttributes: 352 tng_yuv_processor_QueryConfigAttributes, 353validateConfig: 354 tng_yuv_processor_ValidateConfig, 355createContext: 356 tng_yuv_processor_CreateContext, 357destroyContext: 358 tng_yuv_processor_DestroyContext, 359beginPicture: 360 tng_yuv_processor_BeginPicture, 361renderPicture: 362 vld_dec_RenderPicture, 363endPicture: 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 373VAStatus 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 428err: 429 return vaStatus; 430} 431 432VAStatus 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 491err: 492 return vaStatus; 493} 494 495VAStatus 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 } 562err: 563 return vaStatus; 564} 565