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 (at) 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 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 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 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 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 113 static VAStatus tng_yuv_processor_BeginPicture( 114 object_context_p __maybe_unused obj_context) 115 { 116 return VA_STATUS_SUCCESS; 117 } 118 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 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 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 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 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 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 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