1 /* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sub license, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the 13 * next paragraph) shall be included in all copies or substantial portions 14 * of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Binglin Chen <binglin.chen (at) intel.com> 26 * 27 */ 28 29 #include "vsp_VPP.h" 30 #include "psb_buffer.h" 31 #include "psb_surface.h" 32 #include "vsp_cmdbuf.h" 33 #include "psb_drv_debug.h" 34 #include "vsp_compose.h" 35 36 #define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; 37 #define INIT_CONTEXT_VPP context_VPP_p ctx = (context_VPP_p) obj_context->format_data; 38 #define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id )) 39 #define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) 40 #define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) 41 42 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id )) 43 44 #define KB 1024 45 #define MB (KB * KB) 46 #define VSP_CONTEXT_BUF_SIZE (60*KB) 47 #define VSP_INTERMEDIATE_BUF_SIZE (29*MB) 48 49 #define MAX_VPP_PARAM (100) 50 #define MIN_VPP_PARAM (0) 51 #define STEP_VPP_PARAM (33) 52 #define MAX_VPP_AUTO_PARAM (1) 53 #define MIN_VPP_AUTO_PARAM (0) 54 #define STEP_VPP_AUTO_PARAM (1) 55 56 #define VSP_FORWARD_REF_NUM 3 57 58 #define VSP_COLOR_ENHANCE_FEATURES 2 59 60 #define ALIGN_TO_128(value) ((value + 128 - 1) & ~(128 - 1)) 61 #define ALIGN_TO_16(value) ((value + 16 - 1) & ~(16 - 1)) 62 63 #define QVGA_AREA (320 * 240) 64 #define VGA_AREA (640 * 480) 65 #define SD_AREA (720 * 576) 66 #define HD720P_AREA (1280 * 720) 67 #define HD1080P_AREA (1920 * 1088) 68 69 #define MIN_SUPPORTED_HEIGHT 96 70 #define MAX_SUPPORTED_HEIGHT 1088 71 72 /** 73 * The number of supported filter is 5: 74 * VAProcFilterDeblocking 75 * VAProcFilterNoiseReduction 76 * VAProcFilterSharpening 77 * VAProcFilterColorBalance 78 * VAProcFilterFrameRateConversion 79 */ 80 #define VSP_SUPPORTED_FILTERS_NUM 5 81 82 /* The size of supported color standard */ 83 #define COLOR_STANDARDS_NUM 1 84 85 enum resolution_set { 86 NOT_SUPPORTED_RESOLUTION = -1, 87 QCIF_TO_QVGA = 0, 88 QVGA_TO_VGA, 89 VGA_TO_SD, 90 SD_TO_720P, 91 HD720P_TO_1080P, 92 RESOLUTION_SET_NUM 93 }; 94 95 struct vpp_chain_capability { 96 int frc_enabled; 97 int sharpen_enabled; 98 int color_balance_enabled; 99 int denoise_enabled; 100 int deblock_enabled; 101 }; 102 103 enum filter_status { 104 FILTER_DISABLED = 0, 105 FILTER_ENABLED 106 }; 107 108 struct vpp_chain_capability vpp_chain_caps[RESOLUTION_SET_NUM] = { 109 [HD720P_TO_1080P] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_DISABLED, FILTER_DISABLED}, 110 [SD_TO_720P] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_DISABLED, FILTER_DISABLED}, 111 [VGA_TO_SD] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_DISABLED, FILTER_DISABLED}, 112 [QVGA_TO_VGA] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED}, 113 [QCIF_TO_QVGA] = {FILTER_ENABLED, FILTER_ENABLED, FILTER_ENABLED, FILTER_DISABLED, FILTER_ENABLED} 114 }; 115 116 struct filter_strength { 117 struct VssProcDenoiseParameterBuffer denoise_deblock[RESOLUTION_SET_NUM]; 118 struct VssProcColorEnhancementParameterBuffer enhancer[RESOLUTION_SET_NUM]; 119 struct VssProcSharpenParameterBuffer sharpen[RESOLUTION_SET_NUM]; 120 }; 121 122 enum filter_strength_type { 123 INVALID_STRENGTH = -1, 124 LOW_STRENGTH = 0, 125 MEDIUM_STRENGTH, 126 HIGH_STRENGTH, 127 STRENGTH_NUM 128 }; 129 130 #define SHARPEN_ON (1) 131 132 struct filter_strength vpp_strength[STRENGTH_NUM] = { 133 [LOW_STRENGTH] = { 134 /* structure: 135 * type(0-Denoise,1-Deblock), value_thr, cnt_thr, coef, temp_thr1, temp_thr2, _pad[2] 136 */ 137 .denoise_deblock = { 138 [QCIF_TO_QVGA] = {1, 15, 47, 35, 0, 0, {0, 0}}, 139 [QVGA_TO_VGA] = {0, 7, 48, 47, 0, 0, {0, 0}}, 140 [VGA_TO_SD] = {0, 10, 8, 9, 1, 3, {0, 0}}, 141 [SD_TO_720P] = {0, 10, 48, 47, 0, 0, {0, 0}}, 142 [HD720P_TO_1080P] = {0, 10, 48, 47, 0, 0, {0, 0}} 143 }, 144 /* structure: 145 * temp_detect, temp_correct, clip_thr, mid_thr, luma_amm, chroma_amm, _pad[2] 146 */ 147 .enhancer = { 148 [QCIF_TO_QVGA] = {200, 100, 1, 42, 40, 60, {0, 0}}, 149 [QVGA_TO_VGA] = {220, 180, 1, 42, 40, 60, {0, 0}}, 150 [VGA_TO_SD] = {220, 200, 1, 42, 40, 60, {0, 0}}, 151 [SD_TO_720P] = {100, 100, 5, 33, 0, 0, {0, 0}}, 152 [HD720P_TO_1080P] = {100, 100, 5, 33, 0, 0, {0, 0}} 153 }, 154 .sharpen = { 155 [QCIF_TO_QVGA] = { .quality = SHARPEN_ON }, 156 [QVGA_TO_VGA] = { .quality = SHARPEN_ON }, 157 [VGA_TO_SD] = { .quality = SHARPEN_ON }, 158 [SD_TO_720P] = { .quality = SHARPEN_ON }, 159 [HD720P_TO_1080P] = { .quality = SHARPEN_ON } 160 } 161 }, 162 [MEDIUM_STRENGTH] = { 163 .denoise_deblock = { 164 [QCIF_TO_QVGA] = {1, 25, 47, 12, 0, 0, {0, 0}}, 165 [QVGA_TO_VGA] = {0, 10, 48, 47, 0, 0, {0, 0}}, 166 [VGA_TO_SD] = {0, 20, 8, 9, 2, 4, {0, 0}}, 167 [SD_TO_720P] = {0, 10, 48, 47, 0, 0, {0, 0}}, 168 [HD720P_TO_1080P] = {0, 10, 48, 47, 0, 0, {0, 0}} 169 }, 170 .enhancer = { 171 [QCIF_TO_QVGA] = {100, 100, 1, 33, 100, 100, {0, 0}}, 172 [QVGA_TO_VGA] = {100, 180, 1, 33, 100, 100, {0, 0}}, 173 [VGA_TO_SD] = {100, 200, 1, 33, 100, 100, {0, 0}}, 174 [SD_TO_720P] = {100, 100, 5, 33, 0, 0, {0, 0}}, 175 [HD720P_TO_1080P] = {100, 100, 5, 33, 0, 0, {0, 0}} 176 }, 177 .sharpen = { 178 [QCIF_TO_QVGA] = { .quality = SHARPEN_ON }, 179 [QVGA_TO_VGA] = { .quality = SHARPEN_ON }, 180 [VGA_TO_SD] = { .quality = SHARPEN_ON }, 181 [SD_TO_720P] = { .quality = SHARPEN_ON }, 182 [HD720P_TO_1080P] = { .quality = SHARPEN_ON } 183 } 184 }, 185 [HIGH_STRENGTH] = { 186 .denoise_deblock = { 187 [QCIF_TO_QVGA] = {1, 30, 40, 10, 0, 0, {0, 0}}, 188 [QVGA_TO_VGA] = {0, 15, 45, 25, 0, 0, {0, 0}}, 189 [VGA_TO_SD] = {0, 20, 7, 5, 3, 6, {0, 0}}, 190 [SD_TO_720P] = {0, 10, 48, 47, 0, 0, {0, 0}}, 191 [HD720P_TO_1080P] = {0, 10, 48, 47, 0, 0, {0, 0}} 192 }, 193 .enhancer = { 194 [QCIF_TO_QVGA] = {100, 100, 5, 33, 150, 200, {0, 0}}, 195 [QVGA_TO_VGA] = {100, 180, 5, 33, 150, 200, {0, 0}}, 196 [VGA_TO_SD] = {100, 200, 5, 33, 100, 150, {0, 0}}, 197 [SD_TO_720P] = {100, 100, 5, 33, 0, 0, {0, 0}}, 198 [HD720P_TO_1080P] = {100, 100, 5, 33, 0, 0, {0, 0}} 199 }, 200 .sharpen = { 201 [QCIF_TO_QVGA] = { .quality = SHARPEN_ON }, 202 [QVGA_TO_VGA] = { .quality = SHARPEN_ON }, 203 [VGA_TO_SD] = { .quality = SHARPEN_ON }, 204 [SD_TO_720P] = { .quality = SHARPEN_ON }, 205 [HD720P_TO_1080P] = { .quality = SHARPEN_ON } 206 } 207 } 208 }; 209 210 static void vsp_VPP_DestroyContext(object_context_p obj_context); 211 static VAStatus vsp_set_pipeline(context_VPP_p ctx); 212 static VAStatus vsp_set_filter_param(context_VPP_p ctx); 213 static VAStatus vsp__VPP_check_legal_picture(object_context_p obj_context, object_config_p obj_config); 214 static int check_resolution(int width, int height); 215 static int check_vpp_strength(int value); 216 217 static void vsp_VPP_QueryConfigAttributes( 218 VAProfile __maybe_unused profile, 219 VAEntrypoint __maybe_unused entrypoint, 220 VAConfigAttrib __maybe_unused *attrib_list, 221 int __maybe_unused num_attribs) 222 { 223 /* No VPP specific attributes */ 224 return; 225 } 226 227 static VAStatus vsp_VPP_ValidateConfig( 228 object_config_p obj_config) 229 { 230 int i; 231 /* Check all attributes */ 232 for (i = 0; i < obj_config->attrib_count; i++) { 233 switch (obj_config->attrib_list[i].type) { 234 case VAConfigAttribRTFormat: 235 /* Ignore */ 236 break; 237 238 default: 239 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 240 } 241 } 242 243 return VA_STATUS_SUCCESS; 244 } 245 246 static VAStatus vsp__VPP_check_legal_picture(object_context_p obj_context, object_config_p obj_config) 247 { 248 VAStatus vaStatus = VA_STATUS_SUCCESS; 249 250 if (NULL == obj_context) { 251 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 252 DEBUG_FAILURE; 253 return vaStatus; 254 } 255 256 if (NULL == obj_config) { 257 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 258 DEBUG_FAILURE; 259 return vaStatus; 260 } 261 262 return vaStatus; 263 } 264 265 static VAStatus vsp_VPP_CreateContext( 266 object_context_p obj_context, 267 object_config_p obj_config) 268 { 269 VAStatus vaStatus = VA_STATUS_SUCCESS; 270 context_VPP_p ctx; 271 int i; 272 273 /* Validate flag */ 274 /* Validate picture dimensions */ 275 vaStatus = vsp__VPP_check_legal_picture(obj_context, obj_config); 276 if (VA_STATUS_SUCCESS != vaStatus) { 277 DEBUG_FAILURE; 278 return vaStatus; 279 } 280 281 ctx = (context_VPP_p) calloc(1, sizeof(struct context_VPP_s)); 282 if (NULL == ctx) { 283 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 284 DEBUG_FAILURE; 285 return vaStatus; 286 } 287 288 ctx->filters = NULL; 289 ctx->num_filters = 0; 290 291 ctx->frc_buf = NULL; 292 293 /* set size */ 294 ctx->param_sz = 0; 295 ctx->pic_param_sz = ALIGN_TO_128(sizeof(struct VssProcPictureParameterBuffer)); 296 ctx->param_sz += ctx->pic_param_sz; 297 ctx->end_param_sz = ALIGN_TO_128(sizeof(struct VssProcPictureParameterBuffer)); 298 ctx->param_sz += ctx->end_param_sz; 299 300 ctx->pipeline_param_sz = ALIGN_TO_128(sizeof(struct VssProcPipelineParameterBuffer)); 301 ctx->param_sz += ctx->pipeline_param_sz; 302 ctx->denoise_param_sz = ALIGN_TO_128(sizeof(struct VssProcDenoiseParameterBuffer)); 303 ctx->param_sz += ctx->denoise_param_sz; 304 ctx->enhancer_param_sz = ALIGN_TO_128(sizeof(struct VssProcColorEnhancementParameterBuffer)); 305 ctx->param_sz += ctx->enhancer_param_sz; 306 ctx->sharpen_param_sz = ALIGN_TO_128(sizeof(struct VssProcSharpenParameterBuffer)); 307 ctx->param_sz += ctx->sharpen_param_sz; 308 ctx->frc_param_sz = ALIGN_TO_128(sizeof(struct VssProcFrcParameterBuffer)); 309 ctx->param_sz += ctx->frc_param_sz; 310 ctx->compose_param_sz = ALIGN_TO_128(sizeof(struct VssWiDi_ComposeSequenceParameterBuffer)); 311 ctx->param_sz += ctx->compose_param_sz; 312 313 /* set offset */ 314 ctx->pic_param_offset = 0; 315 ctx->end_param_offset = ctx->pic_param_offset + ctx->pic_param_sz; 316 ctx->pipeline_param_offset = ctx->end_param_offset + ctx->end_param_sz; 317 ctx->denoise_param_offset = ctx->pipeline_param_offset + ctx->pipeline_param_sz; 318 ctx->enhancer_param_offset = ctx->denoise_param_offset + ctx->denoise_param_sz; 319 ctx->sharpen_param_offset = ctx->enhancer_param_offset + ctx->enhancer_param_sz; 320 ctx->frc_param_offset = ctx->sharpen_param_offset + ctx->sharpen_param_sz; 321 /* For composer, it'll start on 0 */ 322 ctx->compose_param_offset = 0; 323 324 /* create intermediate buffer */ 325 ctx->intermediate_buf = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s)); 326 if (NULL == ctx->intermediate_buf) { 327 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 328 DEBUG_FAILURE; 329 goto out; 330 } 331 vaStatus = psb_buffer_create(obj_context->driver_data, VSP_INTERMEDIATE_BUF_SIZE, psb_bt_vpu_only, ctx->intermediate_buf); 332 if (VA_STATUS_SUCCESS != vaStatus) { 333 goto out; 334 } 335 336 obj_context->format_data = (void*) ctx; 337 ctx->obj_context = obj_context; 338 339 for (i = 0; i < obj_config->attrib_count; ++i) { 340 if (VAConfigAttribRTFormat == obj_config->attrib_list[i].type) { 341 switch (obj_config->attrib_list[i].value) { 342 case VA_RT_FORMAT_YUV420: 343 ctx->format = VSP_NV12; 344 break; 345 case VA_RT_FORMAT_YUV422: 346 ctx->format = VSP_NV16; 347 default: 348 ctx->format = VSP_NV12; 349 break; 350 } 351 break; 352 } 353 } 354 355 bzero(&ctx->denoise_deblock_param, sizeof(ctx->denoise_deblock_param)); 356 bzero(&ctx->enhancer_param, sizeof(ctx->enhancer_param)); 357 bzero(&ctx->sharpen_param, sizeof(ctx->sharpen_param)); 358 359 return vaStatus; 360 out: 361 vsp_VPP_DestroyContext(obj_context); 362 363 if (ctx) 364 free(ctx); 365 366 return vaStatus; 367 } 368 369 static void vsp_VPP_DestroyContext( 370 object_context_p obj_context) 371 { 372 INIT_CONTEXT_VPP; 373 374 if (ctx->intermediate_buf) { 375 psb_buffer_destroy(ctx->intermediate_buf); 376 377 free(ctx->intermediate_buf); 378 ctx->intermediate_buf = NULL; 379 } 380 381 if (ctx->filters) { 382 free(ctx->filters); 383 ctx->num_filters = 0; 384 } 385 386 free(obj_context->format_data); 387 obj_context->format_data = NULL; 388 } 389 390 static VAStatus vsp__VPP_process_pipeline_param(context_VPP_p ctx, object_context_p obj_context, object_buffer_p obj_buffer) 391 { 392 VAStatus vaStatus = VA_STATUS_SUCCESS; 393 vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf; 394 unsigned int i = 0; 395 VAProcPipelineParameterBuffer *pipeline_param = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data; 396 struct VssProcPictureParameterBuffer *cell_proc_picture_param = (struct VssProcPictureParameterBuffer *)cmdbuf->pic_param_p; 397 struct VssProcPictureParameterBuffer *cell_end_param = (struct VssProcPictureParameterBuffer *)cmdbuf->end_param_p; 398 VAProcFilterParameterBufferFrameRateConversion *frc_param; 399 object_surface_p input_surface = NULL; 400 object_surface_p cur_output_surf = NULL; 401 unsigned int rotation_angle = 0, vsp_rotation_angle = 0; 402 int tiled = 0, width = 0, height = 0, stride = 0; 403 unsigned char *src_addr, *dest_addr; 404 struct psb_surface_s *output_surface; 405 psb_driver_data_p driver_data = obj_context->driver_data; 406 407 if (pipeline_param->surface_region != NULL) { 408 drv_debug_msg(VIDEO_DEBUG_ERROR, "Cann't scale\n"); 409 vaStatus = VA_STATUS_ERROR_UNKNOWN; 410 goto out; 411 } 412 413 if (pipeline_param->output_region != NULL) { 414 drv_debug_msg(VIDEO_DEBUG_ERROR, "Cann't scale\n"); 415 vaStatus = VA_STATUS_ERROR_UNKNOWN; 416 goto out; 417 } 418 419 if (pipeline_param->output_background_color != 0) { 420 drv_debug_msg(VIDEO_DEBUG_ERROR, "Cann't support background color here\n"); 421 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 422 goto out; 423 } 424 425 if (pipeline_param->filters == NULL) { 426 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter setting filters = %p\n", pipeline_param->filters); 427 vaStatus = VA_STATUS_ERROR_UNKNOWN; 428 goto out; 429 } 430 431 #if 0 432 /* for pass filter */ 433 if (pipeline_param->num_filters == 0 || pipeline_param->num_filters > VssProcPipelineMaxNumFilters) { 434 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filter number = %d\n", pipeline_param->num_filters); 435 vaStatus = VA_STATUS_ERROR_UNKNOWN; 436 goto out; 437 } 438 #endif 439 440 if (pipeline_param->forward_references == NULL) { 441 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid forward_refereces %p setting\n", pipeline_param->forward_references); 442 vaStatus = VA_STATUS_ERROR_UNKNOWN; 443 goto out; 444 } 445 446 /* should we check it? since the begining it's not VSP_FORWARD_REF_NUM */ 447 if (pipeline_param->num_forward_references != VSP_FORWARD_REF_NUM) { 448 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_forward_refereces %d setting, should be %d\n", pipeline_param->num_forward_references, VSP_FORWARD_REF_NUM); 449 vaStatus = VA_STATUS_ERROR_UNKNOWN; 450 goto out; 451 } 452 453 /* first picture, need to setup the VSP context */ 454 if (ctx->obj_context->frame_count == 0) 455 vsp_cmdbuf_vpp_context(cmdbuf, VssGenInitializeContext, CONTEXT_VPP_ID, VSP_APP_ID_FRC_VPP); 456 457 /* get the input surface */ 458 if (!(pipeline_param->pipeline_flags & VA_PIPELINE_FLAG_END)) { 459 input_surface = SURFACE(pipeline_param->surface); 460 if (input_surface == NULL) { 461 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid input surface %x\n", pipeline_param->surface); 462 vaStatus = VA_STATUS_ERROR_UNKNOWN; 463 goto out; 464 } 465 } else { 466 input_surface = NULL; 467 } 468 469 /* if it is the first pipeline command */ 470 if (pipeline_param->num_filters != ctx->num_filters || pipeline_param->num_filters == 0) { 471 if (ctx->num_filters != 0) { 472 drv_debug_msg(VIDEO_DEBUG_ERROR, "can not reset pipeline in the mid of post-processing or without create a new context\n"); 473 vaStatus = VA_STATUS_ERROR_UNKNOWN; 474 goto out; 475 } else { 476 /* save filters */ 477 ctx->num_filters = pipeline_param->num_filters; 478 if (ctx->num_filters == 0) { 479 ctx->filters = NULL; 480 } else { 481 ctx->filters = (VABufferID *) calloc(ctx->num_filters, sizeof(*ctx->filters)); 482 if (ctx->filters == NULL) { 483 drv_debug_msg(VIDEO_DEBUG_ERROR, "can not reset pipeline in the mid of post-processing or without create a new context\n"); 484 vaStatus = VA_STATUS_ERROR_UNKNOWN; 485 goto out; 486 } 487 memcpy(ctx->filters, pipeline_param->filters, ctx->num_filters * sizeof(*ctx->filters)); 488 } 489 490 /* set pipeline command to FW */ 491 vaStatus = vsp_set_pipeline(ctx); 492 if (vaStatus) { 493 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to set pipeline\n"); 494 goto out; 495 } 496 497 /* set filter parameter to FW, record frc parameter buffer */ 498 vaStatus = vsp_set_filter_param(ctx); 499 if (vaStatus) { 500 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to set filter parameter\n"); 501 goto out; 502 } 503 } 504 } else { 505 /* else ignore pipeline/filter setting */ 506 #if 0 507 /* FIXME: we can save these check for PnP */ 508 for (i = 0; i < pipeline_param->num_filters; i++) { 509 if (pipeline_param->filters[i] != ctx->filters[i]) { 510 drv_debug_msg(VIDEO_DEBUG_ERROR, "can not reset pipeline in the mid of post-processing or without create a new context\n"); 511 vaStatus = VA_STATUS_ERROR_UNKNOWN; 512 goto out; 513 } 514 } 515 #endif 516 } 517 518 /* fill picture command to FW */ 519 if (ctx->frc_buf != NULL) 520 frc_param = (VAProcFilterParameterBufferFrameRateConversion *)ctx->frc_buf->buffer_data; 521 else 522 frc_param = NULL; 523 524 /* end picture command */ 525 if (pipeline_param->pipeline_flags & VA_PIPELINE_FLAG_END) { 526 cell_end_param->num_input_pictures = 0; 527 cell_end_param->num_output_pictures = 0; 528 vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VPP_ID, &cmdbuf->param_mem, VssProcPictureCommand, 529 ctx->end_param_offset, sizeof(struct VssProcPictureParameterBuffer)); 530 /* Destory the VSP context */ 531 vsp_cmdbuf_vpp_context(cmdbuf, VssGenDestroyContext, CONTEXT_VPP_ID, 0); 532 goto out; 533 } 534 535 #ifdef PSBVIDEO_VPP_TILING 536 /* get the tiling flag*/ 537 tiled = GET_SURFACE_INFO_tiling(input_surface->psb_surface); 538 #endif 539 /* According to VIED's design, the width must be multiple of 16 */ 540 width = ALIGN_TO_16(input_surface->width); 541 if (width > (int)input_surface->psb_surface->stride) 542 width = (int)input_surface->psb_surface->stride; 543 544 /* Setup input surface */ 545 cell_proc_picture_param->num_input_pictures = 1; 546 cell_proc_picture_param->input_picture[0].surface_id = pipeline_param->surface; 547 vsp_cmdbuf_reloc_pic_param(&(cell_proc_picture_param->input_picture[0].base), ctx->pic_param_offset, &(input_surface->psb_surface->buf), 548 cmdbuf->param_mem_loc, cell_proc_picture_param); 549 cell_proc_picture_param->input_picture[0].height = input_surface->height_origin; 550 cell_proc_picture_param->input_picture[0].width = width; 551 cell_proc_picture_param->input_picture[0].irq = 0; 552 cell_proc_picture_param->input_picture[0].stride = input_surface->psb_surface->stride; 553 cell_proc_picture_param->input_picture[0].format = ctx->format; 554 cell_proc_picture_param->input_picture[0].tiled = tiled; 555 cell_proc_picture_param->input_picture[0].rot_angle = 0; 556 557 /* Setup output surfaces */ 558 if (frc_param == NULL) 559 cell_proc_picture_param->num_output_pictures = 1; 560 else 561 cell_proc_picture_param->num_output_pictures = frc_param->num_output_frames + 1; 562 563 for (i = 0; i < cell_proc_picture_param->num_output_pictures; ++i) { 564 if (i == 0) { 565 cur_output_surf = ctx->obj_context->current_render_target; 566 567 #ifdef PSBVIDEO_MRFL_VPP_ROTATE 568 /* The rotation info is saved in the first frame */ 569 rotation_angle = GET_SURFACE_INFO_rotate(cur_output_surf->psb_surface); 570 switch (rotation_angle) { 571 case VA_ROTATION_90: 572 vsp_rotation_angle = VSP_ROTATION_90; 573 break; 574 case VA_ROTATION_180: 575 vsp_rotation_angle = VSP_ROTATION_180; 576 break; 577 case VA_ROTATION_270: 578 vsp_rotation_angle = VSP_ROTATION_270; 579 break; 580 default: 581 vsp_rotation_angle = VSP_ROTATION_NONE; 582 } 583 #endif 584 } else { 585 if (frc_param == NULL) { 586 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid output surface numbers %x\n", 587 cell_proc_picture_param->num_output_pictures); 588 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 589 goto out; 590 } 591 592 cur_output_surf = SURFACE(frc_param->output_frames[i-1]); 593 if (cur_output_surf == NULL) { 594 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid input surface %x\n", frc_param->output_frames[i-1]); 595 vaStatus = VA_STATUS_ERROR_UNKNOWN; 596 goto out; 597 } 598 599 #ifdef PSBVIDEO_MRFL_VPP_ROTATE 600 /* VPP rotation is just for 1080P */ 601 if (tiled && rotation_angle != VA_ROTATION_NONE) { 602 if (VA_STATUS_SUCCESS != psb_CreateRotateSurface(obj_context, cur_output_surf, rotation_angle)) { 603 drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to alloc rotation surface!\n"); 604 vaStatus = VA_STATUS_ERROR_UNKNOWN; 605 goto out; 606 } 607 } 608 #endif 609 } 610 611 if (tiled && rotation_angle != VA_ROTATION_NONE) { 612 #ifdef PSBVIDEO_MRFL_VPP_ROTATE 613 /* For 90d and 270d, we need to alloc rotation buff and 614 * copy the 0d data from input to output 615 */ 616 psb_buffer_map(&(input_surface->psb_surface->buf), &src_addr); 617 psb_buffer_map(&(cur_output_surf->psb_surface->buf), &dest_addr); 618 memcpy(dest_addr, src_addr, cur_output_surf->psb_surface->size); 619 psb_buffer_unmap(&(cur_output_surf->psb_surface->buf)); 620 psb_buffer_unmap(&(input_surface->psb_surface->buf)); 621 622 output_surface = cur_output_surf->out_loop_surface; 623 624 /* According to VIED's design, the width must be multiple of 16 */ 625 width = ALIGN_TO_16(cur_output_surf->height_origin); 626 if (width > cur_output_surf->out_loop_surface->stride) 627 width = cur_output_surf->out_loop_surface->stride; 628 height = cur_output_surf->width; 629 stride = cur_output_surf->out_loop_surface->stride; 630 #endif 631 } else { 632 output_surface = cur_output_surf->psb_surface; 633 634 /* According to VIED's design, the width must be multiple of 16 */ 635 width = ALIGN_TO_16(cur_output_surf->width); 636 if (width > (int)cur_output_surf->psb_surface->stride) 637 width = cur_output_surf->psb_surface->stride; 638 height = cur_output_surf->height_origin; 639 stride = cur_output_surf->psb_surface->stride; 640 641 /* Check the rotate bit */ 642 if (pipeline_param->rotation_state == VA_ROTATION_90) 643 vsp_rotation_angle = VSP_ROTATION_90; 644 else if (pipeline_param->rotation_state == VA_ROTATION_180) 645 vsp_rotation_angle = VSP_ROTATION_180; 646 else if (pipeline_param->rotation_state == VA_ROTATION_270) 647 vsp_rotation_angle = VSP_ROTATION_270; 648 else 649 vsp_rotation_angle = VSP_ROTATION_NONE; 650 } 651 652 cell_proc_picture_param->output_picture[i].surface_id = wsbmKBufHandle(wsbmKBuf(output_surface->buf.drm_buf)); 653 654 vsp_cmdbuf_reloc_pic_param(&(cell_proc_picture_param->output_picture[i].base), 655 ctx->pic_param_offset, &(output_surface->buf), 656 cmdbuf->param_mem_loc, cell_proc_picture_param); 657 cell_proc_picture_param->output_picture[i].height = height; 658 cell_proc_picture_param->output_picture[i].width = width; 659 cell_proc_picture_param->output_picture[i].stride = stride; 660 cell_proc_picture_param->output_picture[i].irq = 1; 661 cell_proc_picture_param->output_picture[i].format = ctx->format; 662 cell_proc_picture_param->output_picture[i].rot_angle = vsp_rotation_angle; 663 cell_proc_picture_param->output_picture[i].tiled = tiled; 664 } 665 666 vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VPP_ID, &cmdbuf->param_mem, VssProcPictureCommand, 667 ctx->pic_param_offset, sizeof(struct VssProcPictureParameterBuffer)); 668 669 vsp_cmdbuf_fence_pic_param(cmdbuf, wsbmKBufHandle(wsbmKBuf(cmdbuf->param_mem.drm_buf))); 670 671 #if 0 672 /* handle reference frames, ignore backward reference */ 673 for (i = 0; i < pipeline_param->num_forward_references; ++i) { 674 cur_output_surf = SURFACE(pipeline_param->forward_references[i]); 675 if (cur_output_surf == NULL) 676 continue; 677 if (vsp_cmdbuf_buffer_ref(cmdbuf, &cur_output_surf->psb_surface->buf) < 0) { 678 drv_debug_msg(VIDEO_DEBUG_ERROR, "vsp_cmdbuf_buffer_ref() failed\n"); 679 vaStatus = VA_STATUS_ERROR_UNKNOWN; 680 goto out; 681 } 682 } 683 #endif 684 out: 685 free(pipeline_param); 686 obj_buffer->buffer_data = NULL; 687 obj_buffer->size = 0; 688 689 return vaStatus; 690 } 691 692 static VAStatus vsp_VPP_RenderPicture( 693 object_context_p obj_context, 694 object_buffer_p *buffers, 695 int num_buffers) 696 { 697 int i; 698 INIT_CONTEXT_VPP; 699 VAProcPipelineParameterBuffer *pipeline_param = NULL; 700 VAStatus vaStatus = VA_STATUS_SUCCESS; 701 702 for (i = 0; i < num_buffers; i++) { 703 object_buffer_p obj_buffer = buffers[i]; 704 pipeline_param = (VAProcPipelineParameterBuffer *) obj_buffer->buffer_data; 705 706 switch (obj_buffer->type) { 707 case VAProcPipelineParameterBufferType: 708 if (!pipeline_param->num_filters && pipeline_param->blend_state) 709 /* For Security Composer */ 710 vaStatus = vsp_compose_process_pipeline_param(ctx, obj_context, obj_buffer); 711 else 712 /* For VPP/FRC */ 713 vaStatus = vsp__VPP_process_pipeline_param(ctx, obj_context, obj_buffer); 714 DEBUG_FAILURE; 715 break; 716 default: 717 vaStatus = VA_STATUS_ERROR_UNKNOWN; 718 DEBUG_FAILURE; 719 } 720 if (vaStatus != VA_STATUS_SUCCESS) { 721 break; 722 } 723 } 724 725 return vaStatus; 726 } 727 728 static VAStatus vsp_VPP_BeginPicture( 729 object_context_p obj_context) 730 { 731 int ret; 732 VAStatus vaStatus = VA_STATUS_SUCCESS; 733 INIT_CONTEXT_VPP; 734 vsp_cmdbuf_p cmdbuf; 735 736 /* Initialise the command buffer */ 737 ret = vsp_context_get_next_cmdbuf(ctx->obj_context); 738 if (ret) { 739 drv_debug_msg(VIDEO_DEBUG_GENERAL, "get next cmdbuf fail\n"); 740 vaStatus = VA_STATUS_ERROR_UNKNOWN; 741 return vaStatus; 742 } 743 744 cmdbuf = obj_context->vsp_cmdbuf; 745 746 /* map param mem */ 747 vaStatus = psb_buffer_map(&cmdbuf->param_mem, &cmdbuf->param_mem_p); 748 if (vaStatus) { 749 return vaStatus; 750 } 751 752 cmdbuf->pic_param_p = cmdbuf->param_mem_p + ctx->pic_param_offset; 753 cmdbuf->end_param_p = cmdbuf->param_mem_p + ctx->end_param_offset; 754 cmdbuf->pipeline_param_p = cmdbuf->param_mem_p + ctx->pipeline_param_offset; 755 cmdbuf->denoise_param_p = cmdbuf->param_mem_p + ctx->denoise_param_offset; 756 cmdbuf->enhancer_param_p = cmdbuf->param_mem_p + ctx->enhancer_param_offset; 757 cmdbuf->sharpen_param_p = cmdbuf->param_mem_p + ctx->sharpen_param_offset; 758 cmdbuf->frc_param_p = cmdbuf->param_mem_p + ctx->frc_param_offset; 759 cmdbuf->compose_param_p = cmdbuf->param_mem_p + ctx->compose_param_offset; 760 761 return VA_STATUS_SUCCESS; 762 } 763 764 static VAStatus vsp_VPP_EndPicture( 765 object_context_p obj_context) 766 { 767 INIT_CONTEXT_VPP; 768 psb_driver_data_p driver_data = obj_context->driver_data; 769 vsp_cmdbuf_p cmdbuf = obj_context->vsp_cmdbuf; 770 771 if(cmdbuf->param_mem_p != NULL) { 772 psb_buffer_unmap(&cmdbuf->param_mem); 773 cmdbuf->param_mem_p = NULL; 774 cmdbuf->pic_param_p = NULL; 775 cmdbuf->end_param_p = NULL; 776 cmdbuf->pipeline_param_p = NULL; 777 cmdbuf->denoise_param_p = NULL; 778 cmdbuf->enhancer_param_p = NULL; 779 cmdbuf->sharpen_param_p = NULL; 780 cmdbuf->frc_param_p = NULL; 781 cmdbuf->compose_param_p = NULL; 782 } 783 784 if (vsp_context_flush_cmdbuf(ctx->obj_context)) { 785 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VPP: flush deblock cmdbuf error\n"); 786 return VA_STATUS_ERROR_UNKNOWN; 787 } 788 789 return VA_STATUS_SUCCESS; 790 } 791 792 struct format_vtable_s vsp_VPP_vtable = { 793 queryConfigAttributes: 794 vsp_VPP_QueryConfigAttributes, 795 validateConfig: 796 vsp_VPP_ValidateConfig, 797 createContext: 798 vsp_VPP_CreateContext, 799 destroyContext: 800 vsp_VPP_DestroyContext, 801 beginPicture: 802 vsp_VPP_BeginPicture, 803 renderPicture: 804 vsp_VPP_RenderPicture, 805 endPicture: 806 vsp_VPP_EndPicture 807 }; 808 809 VAStatus vsp_QueryVideoProcFilters( 810 VADriverContextP ctx, 811 VAContextID context, 812 VAProcFilterType *filters, 813 unsigned int *num_filters 814 ) 815 { 816 INIT_DRIVER_DATA; 817 VAStatus vaStatus = VA_STATUS_SUCCESS; 818 object_context_p obj_context; 819 object_config_p obj_config; 820 VAEntrypoint tmp; 821 int count; 822 823 /* check if ctx is right */ 824 obj_context = CONTEXT(context); 825 if (NULL == obj_context) { 826 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n"); 827 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 828 goto err; 829 } 830 831 obj_config = CONFIG(obj_context->config_id); 832 if (NULL == obj_config) { 833 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n"); 834 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 835 goto err; 836 } 837 838 tmp = obj_config->entrypoint; 839 if (tmp != VAEntrypointVideoProc) { 840 drv_debug_msg(VIDEO_DEBUG_ERROR, "current entrypoint is %d, not VAEntrypointVideoProc\n", tmp); 841 vaStatus = VA_STATUS_ERROR_UNKNOWN; 842 goto err; 843 } 844 845 /* check if filters and num_filters is valid */ 846 if (NULL == num_filters || NULL == filters) { 847 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filters, filters); 848 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 849 goto err; 850 } 851 852 /* check if the filter array size is valid */ 853 if (*num_filters < VSP_SUPPORTED_FILTERS_NUM) { 854 drv_debug_msg(VIDEO_DEBUG_ERROR, "The filters array size(%d) is NOT valid! Supported filters num is %d\n", 855 *num_filters, VSP_SUPPORTED_FILTERS_NUM); 856 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED; 857 *num_filters = VSP_SUPPORTED_FILTERS_NUM; 858 goto err; 859 } 860 861 /* check if current HW support Video proc */ 862 if (IS_MRFL(driver_data)) { 863 count = 0; 864 filters[count++] = VAProcFilterDeblocking; 865 filters[count++] = VAProcFilterNoiseReduction; 866 filters[count++] = VAProcFilterSharpening; 867 filters[count++] = VAProcFilterColorBalance; 868 filters[count++] = VAProcFilterFrameRateConversion; 869 *num_filters = count; 870 } else { 871 *num_filters = 0; 872 } 873 err: 874 return vaStatus; 875 } 876 877 VAStatus vsp_QueryVideoProcFilterCaps( 878 VADriverContextP ctx, 879 VAContextID context, 880 VAProcFilterType type, 881 void *filter_caps, 882 unsigned int *num_filter_caps 883 ) 884 { 885 INIT_DRIVER_DATA; 886 VAStatus vaStatus = VA_STATUS_SUCCESS; 887 object_context_p obj_context; 888 object_config_p obj_config; 889 VAEntrypoint tmp; 890 VAProcFilterCap *denoise_cap, *deblock_cap; 891 VAProcFilterCap *sharpen_cap; 892 VAProcFilterCapColorBalance *color_balance_cap; 893 VAProcFilterCap *frc_cap; 894 895 /* check if context is right */ 896 obj_context = CONTEXT(context); 897 if (NULL == obj_context) { 898 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n"); 899 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 900 goto err; 901 } 902 903 obj_config = CONFIG(obj_context->config_id); 904 if (NULL == obj_config) { 905 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n"); 906 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 907 goto err; 908 } 909 910 /* check if filter_caps and num_filter_caps is right */ 911 if (NULL == num_filter_caps || NULL == filter_caps){ 912 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters %p, filters %p\n", num_filter_caps, filter_caps); 913 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 914 goto err; 915 } 916 917 if (*num_filter_caps < 1) { 918 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide input parameter num_filters == %d (> 1)\n", *num_filter_caps); 919 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 920 goto err; 921 } 922 923 /* check if curent HW support and return corresponding caps */ 924 if (IS_MRFL(driver_data)) { 925 /* FIXME: we should use a constant table to return caps */ 926 switch (type) { 927 case VAProcFilterNoiseReduction: 928 denoise_cap = filter_caps; 929 denoise_cap->range.min_value = MIN_VPP_PARAM; 930 denoise_cap->range.max_value = MAX_VPP_PARAM; 931 denoise_cap->range.default_value = MIN_VPP_PARAM; 932 denoise_cap->range.step = STEP_VPP_PARAM; 933 *num_filter_caps = 1; 934 break; 935 case VAProcFilterDeblocking: 936 deblock_cap = filter_caps; 937 deblock_cap->range.min_value = MIN_VPP_PARAM; 938 deblock_cap->range.max_value = MAX_VPP_PARAM; 939 deblock_cap->range.default_value = MIN_VPP_PARAM; 940 deblock_cap->range.step = STEP_VPP_PARAM; 941 *num_filter_caps = 1; 942 break; 943 944 case VAProcFilterSharpening: 945 sharpen_cap = filter_caps; 946 sharpen_cap->range.min_value = MIN_VPP_PARAM; 947 sharpen_cap->range.max_value = MAX_VPP_PARAM; 948 sharpen_cap->range.default_value = MIN_VPP_PARAM; 949 sharpen_cap->range.step = STEP_VPP_PARAM; 950 *num_filter_caps = 1; 951 break; 952 953 case VAProcFilterColorBalance: 954 if (*num_filter_caps < VSP_COLOR_ENHANCE_FEATURES) { 955 drv_debug_msg(VIDEO_DEBUG_ERROR, "filter cap num is should big than %d(%d)\n", 956 VSP_COLOR_ENHANCE_FEATURES, *num_filter_caps); 957 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED; 958 *num_filter_caps = VSP_COLOR_ENHANCE_FEATURES; 959 goto err; 960 } 961 color_balance_cap = filter_caps; 962 color_balance_cap->type = VAProcColorBalanceAutoSaturation; 963 color_balance_cap->range.min_value = MIN_VPP_AUTO_PARAM; 964 color_balance_cap->range.max_value = MAX_VPP_AUTO_PARAM; 965 color_balance_cap->range.default_value = MIN_VPP_AUTO_PARAM; 966 color_balance_cap->range.step = STEP_VPP_AUTO_PARAM; 967 968 color_balance_cap++; 969 color_balance_cap->type = VAProcColorBalanceAutoBrightness; 970 color_balance_cap->range.min_value = MIN_VPP_AUTO_PARAM; 971 color_balance_cap->range.max_value = MAX_VPP_AUTO_PARAM; 972 color_balance_cap->range.default_value = MIN_VPP_AUTO_PARAM; 973 color_balance_cap->range.step = STEP_VPP_AUTO_PARAM; 974 975 *num_filter_caps = 2; 976 break; 977 978 case VAProcFilterFrameRateConversion: 979 frc_cap = filter_caps; 980 frc_cap->range.min_value = 2; 981 frc_cap->range.max_value = 4; 982 frc_cap->range.default_value = 2; 983 /* FIXME: it's a set, step is helpless */ 984 frc_cap->range.step = 0.5; 985 *num_filter_caps = 1; 986 break; 987 988 default: 989 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalide filter type %d\n", type); 990 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER; 991 *num_filter_caps = 0; 992 goto err; 993 } 994 } else { 995 *num_filter_caps = 0; 996 } 997 998 err: 999 return vaStatus; 1000 } 1001 1002 VAStatus vsp_QueryVideoProcPipelineCaps( 1003 VADriverContextP ctx, 1004 VAContextID context, 1005 VABufferID *filters, 1006 unsigned int num_filters, 1007 VAProcPipelineCaps *pipeline_caps 1008 ) 1009 { 1010 INIT_DRIVER_DATA; 1011 VAStatus vaStatus = VA_STATUS_SUCCESS; 1012 object_context_p obj_context; 1013 object_config_p obj_config; 1014 VAEntrypoint tmp; 1015 unsigned int i, j; 1016 VAProcFilterParameterBuffer *deblock, *denoise, *sharpen; 1017 VAProcFilterParameterBufferFrameRateConversion *frc; 1018 VAProcFilterParameterBufferColorBalance *balance; 1019 VAProcFilterParameterBufferBase *base; 1020 object_buffer_p buf; 1021 uint32_t enabled_brightness, enabled_saturation; 1022 float ratio; 1023 int res_set; 1024 int strength; 1025 context_VPP_p vpp_ctx; 1026 int combination_check; 1027 1028 /* check if ctx is right */ 1029 obj_context = CONTEXT(context); 1030 if (NULL == obj_context) { 1031 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find context\n"); 1032 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 1033 goto err; 1034 } 1035 1036 vpp_ctx = (context_VPP_p) obj_context->format_data; 1037 1038 obj_config = CONFIG(obj_context->config_id); 1039 if (NULL == obj_config) { 1040 drv_debug_msg(VIDEO_DEBUG_ERROR, "Failed to find config\n"); 1041 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 1042 goto err; 1043 } 1044 1045 /* Don't check the filter number. 1046 * According to VIED's design, without any filter, HW will just copy input data 1047 */ 1048 #if 0 1049 if (num_filters == 0) { 1050 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_filters %d\n", num_filters); 1051 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1052 goto err; 1053 } 1054 #endif 1055 if (NULL == filters || pipeline_caps == NULL) { 1056 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid filters %p or pipeline_caps %p\n", filters, pipeline_caps); 1057 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1058 goto err; 1059 } 1060 1061 /* base on HW capability check the filters and return pipeline caps */ 1062 if (IS_MRFL(driver_data)) { 1063 pipeline_caps->pipeline_flags = 0; 1064 pipeline_caps->filter_flags = 0; 1065 pipeline_caps->num_forward_references = VSP_FORWARD_REF_NUM; 1066 pipeline_caps->num_backward_references = 0; 1067 1068 /* check the input color standard */ 1069 if (pipeline_caps->input_color_standards == NULL){ 1070 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid input color standard array!\n"); 1071 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1072 goto err; 1073 } 1074 if (pipeline_caps->num_input_color_standards < COLOR_STANDARDS_NUM) { 1075 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_input_color_standards %d\n", pipeline_caps->num_input_color_standards); 1076 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED; 1077 pipeline_caps->num_input_color_standards = COLOR_STANDARDS_NUM; 1078 goto err; 1079 } 1080 pipeline_caps->input_color_standards[0] = VAProcColorStandardNone; 1081 pipeline_caps->num_input_color_standards = COLOR_STANDARDS_NUM; 1082 1083 /* check the output color standard */ 1084 if (pipeline_caps->output_color_standards == NULL){ 1085 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid output color standard array!\n"); 1086 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1087 goto err; 1088 } 1089 if (pipeline_caps->num_output_color_standards < COLOR_STANDARDS_NUM) { 1090 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid num_output_color_standards %d\n", pipeline_caps->num_output_color_standards); 1091 vaStatus = VA_STATUS_ERROR_MAX_NUM_EXCEEDED; 1092 pipeline_caps->num_output_color_standards = COLOR_STANDARDS_NUM; 1093 goto err; 1094 } 1095 pipeline_caps->output_color_standards[0] = VAProcColorStandardNone; 1096 pipeline_caps->num_output_color_standards = COLOR_STANDARDS_NUM; 1097 1098 /* check the resolution */ 1099 res_set = check_resolution(obj_context->picture_width, 1100 obj_context->picture_height); 1101 if (res_set == NOT_SUPPORTED_RESOLUTION) { 1102 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 1103 goto err; 1104 } 1105 1106 /* Blend type */ 1107 pipeline_caps->blend_flags = VA_BLEND_PREMULTIPLIED_ALPHA; 1108 1109 if (getenv("VSP_PIPELINE_CHECK") != NULL) 1110 combination_check = 1; 1111 else 1112 combination_check = 0; 1113 1114 /* FIXME: should check filter value settings here */ 1115 for (i = 0; i < num_filters; ++i) { 1116 /* find buffer */ 1117 buf = BUFFER(*(filters + i)); 1118 if (!buf) { 1119 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1120 goto err; 1121 } 1122 1123 base = (VAProcFilterParameterBufferBase *)buf->buffer_data; 1124 /* check filter buffer setting */ 1125 switch (base->type) { 1126 case VAProcFilterDeblocking: 1127 deblock = (VAProcFilterParameterBuffer *)base; 1128 1129 if (combination_check && 1130 vpp_chain_caps[res_set].deblock_enabled != FILTER_ENABLED) { 1131 drv_debug_msg(VIDEO_DEBUG_ERROR, "The deblock is DISABLE for %d format\n", res_set); 1132 vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN; 1133 goto err; 1134 } else { 1135 /* check if the value is right */ 1136 strength = check_vpp_strength(deblock->value); 1137 if (strength == INVALID_STRENGTH) { 1138 vaStatus = VA_STATUS_ERROR_INVALID_VALUE; 1139 goto err; 1140 } 1141 memcpy(&vpp_ctx->denoise_deblock_param, 1142 &vpp_strength[strength].denoise_deblock[res_set], 1143 sizeof(vpp_ctx->denoise_deblock_param)); 1144 } 1145 break; 1146 1147 case VAProcFilterNoiseReduction: 1148 denoise = (VAProcFilterParameterBuffer *)base; 1149 1150 if (combination_check && 1151 vpp_chain_caps[res_set].denoise_enabled != FILTER_ENABLED) { 1152 drv_debug_msg(VIDEO_DEBUG_ERROR, "The denoise is DISABLE for %d format\n", res_set); 1153 vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN; 1154 goto err; 1155 } else { 1156 strength = check_vpp_strength(denoise->value); 1157 if (strength == INVALID_STRENGTH) { 1158 vaStatus = VA_STATUS_ERROR_INVALID_VALUE; 1159 goto err; 1160 } 1161 memcpy(&vpp_ctx->denoise_deblock_param, 1162 &vpp_strength[strength].denoise_deblock[res_set], 1163 sizeof(vpp_ctx->denoise_deblock_param)); 1164 } 1165 break; 1166 1167 case VAProcFilterSharpening: 1168 sharpen = (VAProcFilterParameterBuffer *)base; 1169 1170 if (combination_check && 1171 vpp_chain_caps[res_set].sharpen_enabled != FILTER_ENABLED) { 1172 drv_debug_msg(VIDEO_DEBUG_ERROR, "The sharpen is DISABLE for %d format\n", res_set); 1173 vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN; 1174 goto err; 1175 } else { 1176 strength = check_vpp_strength(sharpen->value); 1177 if (strength == INVALID_STRENGTH) { 1178 vaStatus = VA_STATUS_ERROR_INVALID_VALUE; 1179 goto err; 1180 } 1181 memcpy(&vpp_ctx->sharpen_param, 1182 &vpp_strength[strength].sharpen[res_set], 1183 sizeof(vpp_ctx->sharpen_param)); 1184 } 1185 break; 1186 1187 case VAProcFilterColorBalance: 1188 balance = (VAProcFilterParameterBufferColorBalance *)base; 1189 1190 enabled_brightness = 0; 1191 enabled_saturation = 0; 1192 1193 for (j = 0; j < buf->num_elements; ++j, ++balance) { 1194 if (balance->attrib == VAProcColorBalanceAutoSaturation && 1195 balance->value == MAX_VPP_AUTO_PARAM) { 1196 enabled_saturation = 1; 1197 } else if (balance->attrib == VAProcColorBalanceAutoBrightness && 1198 balance->value == MAX_VPP_AUTO_PARAM) { 1199 enabled_brightness = 1; 1200 } else { 1201 drv_debug_msg(VIDEO_DEBUG_ERROR, "The color_banlance do NOT support this attrib %d\n", 1202 balance->attrib); 1203 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER; 1204 goto err; 1205 } 1206 } 1207 1208 /* check filter chain */ 1209 if (combination_check && 1210 vpp_chain_caps[res_set].color_balance_enabled != FILTER_ENABLED) { 1211 drv_debug_msg(VIDEO_DEBUG_ERROR, "The color_balance is DISABLE for %d format\n", res_set); 1212 vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN; 1213 goto err; 1214 } else { 1215 strength = MEDIUM_STRENGTH; 1216 memcpy(&vpp_ctx->enhancer_param, 1217 &vpp_strength[strength].enhancer[res_set], 1218 sizeof(vpp_ctx->enhancer_param)); 1219 if (!enabled_saturation) 1220 vpp_ctx->enhancer_param.chroma_amm = 0; 1221 if (!enabled_brightness) 1222 vpp_ctx->enhancer_param.luma_amm = 0; 1223 } 1224 1225 break; 1226 1227 case VAProcFilterFrameRateConversion: 1228 frc = (VAProcFilterParameterBufferFrameRateConversion *)base; 1229 1230 /* check frame rate */ 1231 ratio = frc->output_fps / (float)frc->input_fps; 1232 1233 if (!((ratio == 2 || ratio == 2.5 || ratio == 4) && frc->output_fps <= 60)) { 1234 drv_debug_msg(VIDEO_DEBUG_ERROR, "The FRC do NOT support the ration(%f) and fps(%d)\n", 1235 ratio, frc->output_fps); 1236 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_FILTER; 1237 goto err; 1238 } 1239 1240 /* check the chain */ 1241 if (combination_check && 1242 vpp_chain_caps[res_set].frc_enabled != FILTER_ENABLED) { 1243 drv_debug_msg(VIDEO_DEBUG_ERROR, "The FRC is DISABLE for %d format\n", res_set); 1244 vaStatus = VA_STATUS_ERROR_INVALID_FILTER_CHAIN; 1245 goto err; 1246 } 1247 1248 break; 1249 default: 1250 drv_debug_msg(VIDEO_DEBUG_ERROR, "Do NOT support the filter type %d\n", base->type); 1251 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1252 goto err; 1253 } 1254 } 1255 } else { 1256 drv_debug_msg(VIDEO_DEBUG_ERROR, "no HW support\n"); 1257 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1258 goto err; 1259 } 1260 err: 1261 return vaStatus; 1262 } 1263 1264 static VAStatus vsp_set_pipeline(context_VPP_p ctx) 1265 { 1266 VAStatus vaStatus = VA_STATUS_SUCCESS; 1267 vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf; 1268 struct VssProcPipelineParameterBuffer *cell_pipeline_param = (struct VssProcPipelineParameterBuffer *)cmdbuf->pipeline_param_p; 1269 unsigned int i, j, filter_count, check_filter = 0; 1270 VAProcFilterParameterBufferBase *cur_param; 1271 enum VssProcFilterType tmp; 1272 psb_driver_data_p driver_data = ctx->obj_context->driver_data; 1273 1274 /* set intermediate buffer */ 1275 cell_pipeline_param->intermediate_buffer_size = VSP_INTERMEDIATE_BUF_SIZE; 1276 cell_pipeline_param->intermediate_buffer_base = wsbmBOOffsetHint(ctx->intermediate_buf->drm_buf); 1277 1278 /* init pipeline cmd */ 1279 for (i = 0; i < VssProcPipelineMaxNumFilters; ++i) 1280 cell_pipeline_param->filter_pipeline[i] = -1; 1281 cell_pipeline_param->num_filters = 0; 1282 1283 filter_count = 0; 1284 1285 /* store filter buffer object */ 1286 if (ctx->num_filters != 0) { 1287 for (i = 0; i < ctx->num_filters; ++i) 1288 ctx->filter_buf[i] = BUFFER(ctx->filters[i]); 1289 } else { 1290 goto finished; 1291 } 1292 1293 /* loop the filter, set correct pipeline param for FW */ 1294 for (i = 0; i < ctx->num_filters; ++i) { 1295 cur_param = (VAProcFilterParameterBufferBase *)ctx->filter_buf[i]->buffer_data; 1296 switch (cur_param->type) { 1297 case VAProcFilterNone: 1298 goto finished; 1299 break; 1300 case VAProcFilterNoiseReduction: 1301 case VAProcFilterDeblocking: 1302 cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterDenoise; 1303 check_filter++; 1304 break; 1305 case VAProcFilterSharpening: 1306 cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterSharpening; 1307 break; 1308 case VAProcFilterColorBalance: 1309 cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterColorEnhancement; 1310 break; 1311 case VAProcFilterFrameRateConversion: 1312 cell_pipeline_param->filter_pipeline[filter_count++] = VssProcFilterFrameRateConversion; 1313 break; 1314 default: 1315 cell_pipeline_param->filter_pipeline[filter_count++] = -1; 1316 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1317 goto out; 1318 } 1319 } 1320 1321 /* Denoise and Deblock is alternative */ 1322 if (check_filter >= 2) { 1323 drv_debug_msg(VIDEO_DEBUG_ERROR, "Denoise and Deblock is alternative!\n"); 1324 cell_pipeline_param->filter_pipeline[filter_count++] = -1; 1325 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1326 goto out; 1327 } 1328 1329 finished: 1330 cell_pipeline_param->num_filters = filter_count; 1331 1332 /* reorder */ 1333 for (i = 1; i < filter_count; ++i) 1334 for (j = i; j > 0; --j) 1335 if (cell_pipeline_param->filter_pipeline[j] < cell_pipeline_param->filter_pipeline[j - 1]) { 1336 /* swap */ 1337 tmp = cell_pipeline_param->filter_pipeline[j]; 1338 cell_pipeline_param->filter_pipeline[j] = cell_pipeline_param->filter_pipeline[j - 1]; 1339 cell_pipeline_param->filter_pipeline[j - 1] = tmp; 1340 } 1341 1342 vsp_cmdbuf_insert_command(cmdbuf, CONTEXT_VPP_ID, &cmdbuf->param_mem, VssProcPipelineParameterCommand, 1343 ctx->pipeline_param_offset, sizeof(struct VssProcPipelineParameterBuffer)); 1344 out: 1345 return vaStatus; 1346 } 1347 1348 static VAStatus vsp_set_filter_param(context_VPP_p ctx) 1349 { 1350 VAStatus vaStatus = VA_STATUS_SUCCESS; 1351 vsp_cmdbuf_p cmdbuf = ctx->obj_context->vsp_cmdbuf; 1352 struct VssProcDenoiseParameterBuffer *cell_denoiser_param = (struct VssProcDenoiseParameterBuffer *)cmdbuf->denoise_param_p; 1353 struct VssProcColorEnhancementParameterBuffer *cell_enhancer_param = (struct VssProcColorEnhancementParameterBuffer *)cmdbuf->enhancer_param_p; 1354 struct VssProcSharpenParameterBuffer *cell_sharpen_param = (struct VssProcSharpenParameterBuffer *)cmdbuf->sharpen_param_p; 1355 struct VssProcFrcParameterBuffer *cell_proc_frc_param = (struct VssProcFrcParameterBuffer *)cmdbuf->frc_param_p; 1356 VAProcFilterParameterBufferBase *cur_param = NULL; 1357 VAProcFilterParameterBufferFrameRateConversion *frc_param = NULL; 1358 unsigned int i; 1359 float ratio; 1360 1361 for (i = 0; i < ctx->num_filters; ++i) { 1362 cur_param = (VAProcFilterParameterBufferBase *)ctx->filter_buf[i]->buffer_data; 1363 switch (cur_param->type) { 1364 case VAProcFilterDeblocking: 1365 memcpy(cell_denoiser_param, 1366 &ctx->denoise_deblock_param, 1367 sizeof(ctx->denoise_deblock_param)); 1368 cell_denoiser_param->type = VssProcDeblock; 1369 1370 vsp_cmdbuf_insert_command(cmdbuf, 1371 CONTEXT_VPP_ID, 1372 &cmdbuf->param_mem, 1373 VssProcDenoiseParameterCommand, 1374 ctx->denoise_param_offset, 1375 sizeof(struct VssProcDenoiseParameterBuffer)); 1376 break; 1377 1378 case VAProcFilterNoiseReduction: 1379 memcpy(cell_denoiser_param, 1380 &ctx->denoise_deblock_param, 1381 sizeof(ctx->denoise_deblock_param)); 1382 cell_denoiser_param->type = VssProcDegrain; 1383 1384 vsp_cmdbuf_insert_command(cmdbuf, 1385 CONTEXT_VPP_ID, 1386 &cmdbuf->param_mem, 1387 VssProcDenoiseParameterCommand, 1388 ctx->denoise_param_offset, 1389 sizeof(struct VssProcDenoiseParameterBuffer)); 1390 break; 1391 1392 case VAProcFilterSharpening: 1393 memcpy(cell_sharpen_param, 1394 &ctx->sharpen_param, 1395 sizeof(ctx->sharpen_param)); 1396 1397 vsp_cmdbuf_insert_command(cmdbuf, 1398 CONTEXT_VPP_ID, 1399 &cmdbuf->param_mem, 1400 VssProcSharpenParameterCommand, 1401 ctx->sharpen_param_offset, 1402 sizeof(struct VssProcSharpenParameterBuffer)); 1403 break; 1404 1405 case VAProcFilterColorBalance: 1406 memcpy(cell_enhancer_param, 1407 &ctx->enhancer_param, 1408 sizeof(ctx->enhancer_param)); 1409 1410 vsp_cmdbuf_insert_command(cmdbuf, 1411 CONTEXT_VPP_ID, 1412 &cmdbuf->param_mem, 1413 VssProcColorEnhancementParameterCommand, 1414 ctx->enhancer_param_offset, 1415 sizeof(struct VssProcColorEnhancementParameterBuffer)); 1416 1417 break; 1418 1419 case VAProcFilterFrameRateConversion: 1420 ctx->frc_buf = ctx->filter_buf[i]; 1421 1422 frc_param = (VAProcFilterParameterBufferFrameRateConversion *)ctx->filter_buf[i]->buffer_data; 1423 ratio = frc_param->output_fps / (float)frc_param->input_fps; 1424 1425 /* set the FRC quality */ 1426 /* cell_proc_frc_param->quality = VssFrcMediumQuality; */ 1427 cell_proc_frc_param->quality = VssFrcHighQuality; 1428 1429 /* check if the input fps is in the range of HW capability */ 1430 if (ratio == 2) 1431 cell_proc_frc_param->conversion_rate = VssFrc2xConversionRate; 1432 else if (ratio == 2.5) 1433 cell_proc_frc_param->conversion_rate = VssFrc2_5xConversionRate; 1434 else if (ratio == 4) 1435 cell_proc_frc_param->conversion_rate = VssFrc4xConversionRate; 1436 else if (ratio == 1.25) 1437 cell_proc_frc_param->conversion_rate = VssFrc1_25xConversionRate; 1438 else { 1439 drv_debug_msg(VIDEO_DEBUG_ERROR, "invalid frame rate conversion ratio %f \n", ratio); 1440 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1441 goto out; 1442 } 1443 1444 vsp_cmdbuf_insert_command(cmdbuf, 1445 CONTEXT_VPP_ID, 1446 &cmdbuf->param_mem, 1447 VssProcFrcParameterCommand, 1448 ctx->frc_param_offset, 1449 sizeof(struct VssProcFrcParameterBuffer)); 1450 break; 1451 default: 1452 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1453 goto out; 1454 } 1455 } 1456 out: 1457 return vaStatus; 1458 } 1459 1460 static int check_resolution(int width, int height) 1461 { 1462 int ret; 1463 int image_area; 1464 1465 if (height < MIN_SUPPORTED_HEIGHT || height > MAX_SUPPORTED_HEIGHT) 1466 return NOT_SUPPORTED_RESOLUTION; 1467 1468 image_area = height * width; 1469 1470 if (image_area <= QVGA_AREA) 1471 ret = QCIF_TO_QVGA; 1472 else if (image_area <= VGA_AREA) 1473 ret = QVGA_TO_VGA; 1474 else if (image_area <= SD_AREA) 1475 ret = VGA_TO_SD; 1476 else if (image_area <= HD720P_AREA) 1477 ret = SD_TO_720P; 1478 else if (image_area <= HD1080P_AREA) 1479 ret = HD720P_TO_1080P; 1480 else 1481 ret = NOT_SUPPORTED_RESOLUTION; 1482 1483 return ret; 1484 } 1485 1486 /* 1487 * The strength area is: 1488 * 1489 * 0______33______66______100 1490 * LOW MED HIGH 1491 * 1492 * MIN=0; MAX=100; STEP=33 1493 */ 1494 static int check_vpp_strength(int value) 1495 { 1496 if (value < MIN_VPP_PARAM || value > MAX_VPP_PARAM) 1497 return INVALID_STRENGTH; 1498 1499 if (value >= MIN_VPP_PARAM && 1500 value < MIN_VPP_PARAM + STEP_VPP_PARAM) 1501 return LOW_STRENGTH; 1502 else if (value >= MIN_VPP_PARAM + STEP_VPP_PARAM && 1503 value < MIN_VPP_PARAM + 2 * STEP_VPP_PARAM) 1504 return MEDIUM_STRENGTH; 1505 else 1506 return HIGH_STRENGTH; 1507 } 1508