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