tng_yuv_processor.c revision dbf2ee864763f6da009b5455943917c72e31e9ec
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 profile, 42 VAEntrypoint entrypoint, 43 VAConfigAttrib *attrib_list, 44 int num_attribs) 45{ 46 /* No specific attributes */ 47} 48 49static VAStatus tng_yuv_processor_ValidateConfig( 50 object_config_p 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 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 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 ctx->display_width = surface_params->display_width; 207 ctx->display_height = surface_params->display_height; 208 ctx->coded_width = surface_params->coded_width; 209 ctx->coded_height = surface_params->coded_height; 210 ctx->src_surface = dec_ctx->obj_context->current_render_target->psb_surface; 211 ctx->proc_param = NULL; 212 } else if (obj_buffer->type == VAProcPipelineParameterBufferType) { 213 VAProcPipelineParameterBuffer *vpp_params = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data; 214 object_surface_p obj_surface = SURFACE(vpp_params->surface); 215 psb_surface_p rotate_surface = dec_ctx->obj_context->current_render_target->psb_surface; 216 217 if (obj_surface == NULL){ 218 vaStatus = VA_STATUS_ERROR_UNKNOWN; 219 return vaStatus; 220 } 221 222 //ctx->display_width = ((vpp_params->surface_region->width + 0xf) & ~0xf); 223 //ctx->display_height = ((vpp_params->surface_region->height + 0x1f) & ~0x1f); 224 ctx->display_width = ((obj_surface->width + 0xf) & ~0xf); 225 ctx->display_height = ((obj_surface->height + 0xf) & ~0xf); 226 ctx->coded_width = ctx->display_width; 227 ctx->coded_height = ctx->display_height; 228 229 ctx->src_surface = obj_surface->psb_surface; 230 dec_ctx->obj_context->msvdx_rotate = vpp_params->rotation_state; 231 SET_SURFACE_INFO_rotate(rotate_surface, dec_ctx->obj_context->msvdx_rotate); 232 233 ctx->proc_param = vpp_params; 234 obj_buffer->buffer_data = NULL; 235 obj_buffer->size = 0; 236 237#ifdef PSBVIDEO_MSVDX_DEC_TILING 238 object_context_p obj_context = dec_ctx->obj_context; 239 psb_driver_data_p driver_data = obj_context->driver_data; 240 drv_debug_msg(VIDEO_DEBUG_GENERAL, "attempt to update tile context\n"); 241 if (GET_SURFACE_INFO_tiling(ctx->src_surface)) { 242 drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context\n"); 243 244 unsigned long msvdx_tile = psb__tile_stride_log2_256(rotate_surface->stride); 245 obj_context->msvdx_tile &= 0xf; /* clear rotate tile */ 246 obj_context->msvdx_tile |= (msvdx_tile << 4); 247 obj_context->ctp_type &= (~PSB_CTX_TILING_MASK); /* clear tile context */ 248 obj_context->ctp_type |= ((obj_context->msvdx_tile & 0xff) << 16); 249 psb_update_context(driver_data, obj_context->ctp_type); 250 drv_debug_msg(VIDEO_DEBUG_GENERAL, "update tile context, msvdx_tiled is 0x%08x \n", obj_context->msvdx_tile); 251 } 252#endif 253 } 254 255#ifdef ADNROID 256 LOGV("%s, %d %d %d %d***************************************************\n", 257 __func__, ctx->display_width, ctx->display_height, ctx->coded_width, ctx->coded_height); 258#endif 259 260 vaStatus = VA_STATUS_SUCCESS; 261 262 if (psb_context_get_next_cmdbuf(dec_ctx->obj_context)) { 263 vaStatus = VA_STATUS_ERROR_UNKNOWN; 264 DEBUG_FAILURE; 265 return vaStatus; 266 } 267 /* ctx->begin_slice(ctx, slice_param); */ 268 vld_dec_FE_state(dec_ctx->obj_context, NULL); 269 270 tng__yuv_processor_process(dec_ctx); 271 /* ctx->process_slice(ctx, slice_param); */ 272 vld_dec_write_kick(dec_ctx->obj_context); 273 274 dec_ctx->obj_context->video_op = psb_video_vld; 275 dec_ctx->obj_context->flags = 0; 276 277 /* ctx->end_slice(ctx); */ 278 dec_ctx->obj_context->flags = FW_VA_RENDER_IS_FIRST_SLICE | FW_VA_RENDER_IS_LAST_SLICE | FW_INTERNAL_CONTEXT_SWITCH; 279 280 if (psb_context_submit_cmdbuf(dec_ctx->obj_context)) { 281 vaStatus = VA_STATUS_ERROR_UNKNOWN; 282 } 283 return vaStatus; 284} 285 286static VAStatus tng_yuv_processor_process_buffer( 287 context_DEC_p dec_ctx, 288 object_buffer_p buffer) 289{ 290 VAStatus vaStatus = VA_STATUS_SUCCESS; 291 object_buffer_p obj_buffer = buffer; 292 293 { 294 switch (obj_buffer->type) { 295 case YUVProcessorSurfaceType: 296 case VAProcPipelineParameterBufferType: 297 vaStatus = tng__yuv_processor_execute(dec_ctx, obj_buffer); 298 DEBUG_FAILURE; 299 break; 300 301 default: 302 vaStatus = VA_STATUS_ERROR_UNKNOWN; 303 DEBUG_FAILURE; 304 } 305 } 306 307 return vaStatus; 308} 309 310static VAStatus tng_yuv_processor_EndPicture( 311 object_context_p obj_context) 312{ 313 context_DEC_p dec_ctx = (context_DEC_p) obj_context->format_data; 314 context_yuv_processor_p ctx = dec_ctx->yuv_ctx; 315 316 if (psb_context_flush_cmdbuf(obj_context)) { 317 return VA_STATUS_ERROR_UNKNOWN; 318 } 319 320 if (ctx->proc_param) { 321 free(ctx->proc_param); 322 ctx->proc_param = NULL; 323 } 324 325 return VA_STATUS_SUCCESS; 326} 327 328struct format_vtable_s tng_yuv_processor_vtable = { 329queryConfigAttributes: 330 tng_yuv_processor_QueryConfigAttributes, 331validateConfig: 332 tng_yuv_processor_ValidateConfig, 333createContext: 334 tng_yuv_processor_CreateContext, 335destroyContext: 336 tng_yuv_processor_DestroyContext, 337beginPicture: 338 tng_yuv_processor_BeginPicture, 339renderPicture: 340 vld_dec_RenderPicture, 341endPicture: 342 tng_yuv_processor_EndPicture 343}; 344 345#define VED_SUPPORTED_FILTERS_NUM 1 346#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; 347#define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id )) 348#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) 349#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) 350 351VAStatus ved_QueryVideoProcFilters( 352 VADriverContextP ctx, 353 VAContextID context, 354 VAProcFilterType *filters, 355 unsigned int *num_filters) 356{ 357 INIT_DRIVER_DATA; 358 VAStatus vaStatus = VA_STATUS_SUCCESS; 359 object_context_p obj_context; 360 object_config_p obj_config; 361 VAEntrypoint tmp; 362 int count; 363 364 /* check if ctx is right */ 365 obj_context = CONTEXT(context); 366 if (NULL == obj_context) { 367 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n"); 368 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 369 goto err; 370 } 371 372 obj_config = CONFIG(obj_context->config_id); 373 if (NULL == obj_config) { 374 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n"); 375 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 376 goto err; 377 } 378 379 tmp = obj_config->entrypoint; 380 if (tmp != VAEntrypointVideoProc) { 381 drv_debug_msg(VIDEO_DEBUG_ERROR, "current entrypoint is %d, not VAEntrypointVideoProc\n", tmp); 382 vaStatus = VA_STATUS_ERROR_UNKNOWN; 383 goto err; 384 } 385 386 /* check if filters and num_filters is valid */ 387 if (NULL == num_filters || NULL == filters) { 388 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filters, filters); 389 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 390 goto err; 391 } 392 393 /* check if the filter array size is valid */ 394 if (*num_filters < VED_SUPPORTED_FILTERS_NUM) { 395 drv_debug_msg(VIDEO_DEBUG_ERROR, "The filters array size(%d) is NOT valid! Supported filters num is %d\n", 396 *num_filters, VED_SUPPORTED_FILTERS_NUM); 397 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED; 398 *num_filters = VED_SUPPORTED_FILTERS_NUM; 399 goto err; 400 } 401 402 count = 0; 403 filters[count++] = VAProcFilterNone; 404 *num_filters = count; 405 406err: 407 return vaStatus; 408} 409 410VAStatus ved_QueryVideoProcFilterCaps( 411 VADriverContextP ctx, 412 VAContextID context, 413 VAProcFilterType type, 414 void *filter_caps, 415 unsigned int *num_filter_caps) 416{ 417 INIT_DRIVER_DATA; 418 VAStatus vaStatus = VA_STATUS_SUCCESS; 419 object_context_p obj_context; 420 object_config_p obj_config; 421 VAProcFilterCap *no_cap; 422 423 /* check if context is right */ 424 obj_context = CONTEXT(context); 425 if (NULL == obj_context) { 426 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n"); 427 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 428 goto err; 429 } 430 431 obj_config = CONFIG(obj_context->config_id); 432 if (NULL == obj_config) { 433 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n"); 434 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 435 goto err; 436 } 437 438 /* check if filter_caps and num_filter_caps is right */ 439 if (NULL == num_filter_caps || NULL == filter_caps){ 440 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filter_caps, filter_caps); 441 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 442 goto err; 443 } 444 445 if (*num_filter_caps < 1) { 446 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters == %d (> 1)\n", *num_filter_caps); 447 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 448 goto err; 449 } 450 451 /* check if curent HW support and return corresponding caps */ 452 /* FIXME: we should use a constant table to return caps */ 453 switch (type) { 454 case VAProcFilterNone: 455 no_cap = filter_caps; 456 no_cap->range.min_value = 0; 457 no_cap->range.max_value = 0; 458 no_cap->range.default_value = 0; 459 no_cap->range.step = 0; 460 *num_filter_caps = 1; 461 break; 462 default: 463 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide filter type %d\n", type); 464 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER; 465 *num_filter_caps = 0; 466 goto err; 467 } 468 469err: 470 return vaStatus; 471} 472 473VAStatus ved_QueryVideoProcPipelineCaps( 474 VADriverContextP ctx, 475 VAContextID context, 476 VABufferID *filters, 477 unsigned int num_filters, 478 VAProcPipelineCaps *pipeline_caps) 479{ 480 INIT_DRIVER_DATA; 481 VAStatus vaStatus = VA_STATUS_SUCCESS; 482 object_context_p obj_context; 483 object_config_p obj_config; 484 VAProcFilterParameterBufferBase *base; 485 object_buffer_p buf; 486 487 /* check if ctx is right */ 488 obj_context = CONTEXT(context); 489 if (NULL == obj_context) { 490 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n"); 491 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 492 goto err; 493 } 494 495 obj_config = CONFIG(obj_context->config_id); 496 if (NULL == obj_config) { 497 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n"); 498 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 499 goto err; 500 } 501 502 /* check if filters and num_filters and pipeline-caps are right */ 503 if (num_filters != 1) { 504 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_filters %d\n", num_filters); 505 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 506 goto err; 507 } 508 509 if (NULL == filters || pipeline_caps == NULL) { 510 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filters %p or pipeline_caps %p\n", filters, pipeline_caps); 511 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 512 goto err; 513 } 514 515 memset(pipeline_caps, 0, sizeof(*pipeline_caps)); 516 517 buf = BUFFER(*(filters)); 518 519 if (buf == NULL){ 520 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter buffer: NULL \n"); 521 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 522 goto err; 523 } 524 525 base = (VAProcFilterParameterBufferBase *)buf->buffer_data; 526 /* check filter buffer setting */ 527 switch (base->type) { 528 case VAProcFilterNone: 529 pipeline_caps->rotation_flags = (1 << VA_ROTATION_NONE); 530 pipeline_caps->rotation_flags |= (1 << VA_ROTATION_90); 531 pipeline_caps->rotation_flags |= (1 << VA_ROTATION_180); 532 pipeline_caps->rotation_flags |= (1 << VA_ROTATION_270); 533 break; 534 535 default: 536 drv_debug_msg(VIDEO_DEBUG_ERROR, "Do NOT support the filter type %d\n", base->type); 537 vaStatus = VA_STATUS_ERROR_UNKNOWN; 538 goto err; 539 } 540err: 541 return vaStatus; 542} 543