psb_output.c revision 67612a448651896b2557796ff98d46c5e0dbbdc6
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 * Shengquan Yuan <shengquan.yuan@intel.com> 26 * Zhaohan Ren <zhaohan.ren@intel.com> 27 * Jason Hu <jason.hu@intel.com> 28 * 29 */ 30 31#ifndef ANDROID 32#include <X11/Xutil.h> 33#include <X11/extensions/Xrandr.h> 34#include <va/va_dricommon.h> 35#include "x11/psb_x11.h" 36#include "x11/psb_xrandr.h" 37#endif 38#include <va/va_backend.h> 39#include <dlfcn.h> 40#include <stdlib.h> 41#include "psb_output.h" 42#include "psb_surface.h" 43#include "psb_buffer.h" 44#include "psb_surface_ext.h" 45#include "pnw_rotate.h" 46#include <stdio.h> 47#include <string.h> 48#include <stdarg.h> 49#include <wsbm/wsbm_manager.h> 50 51#include <string.h> 52#include <unistd.h> 53#include <sys/ioctl.h> 54 55#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; 56 57#define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) 58#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) 59#define IMAGE(id) ((object_image_p) object_heap_lookup( &driver_data->image_heap, id )) 60#define SUBPIC(id) ((object_subpic_p) object_heap_lookup( &driver_data->subpic_heap, id )) 61#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) 62 63 64/* surfaces link list associated with a subpicture */ 65typedef struct _subpic_surface { 66 VASurfaceID surface_id; 67 struct _subpic_surface *next; 68} subpic_surface_s, *subpic_surface_p; 69 70 71static VAImageFormat psb__SubpicFormat[] = { 72 psb__ImageRGBA, 73 //psb__ImageAYUV, 74 //psb__ImageAI44 75}; 76 77static VAImageFormat psb__CreateImageFormat[] = { 78 psb__ImageNV12, 79 psb__ImageRGBA, 80 //psb__ImageAYUV, 81 //psb__ImageAI44, 82 psb__ImageYV16 83}; 84 85unsigned char *psb_x11_output_init(VADriverContextP ctx); 86VAStatus psb_x11_output_deinit(VADriverContextP ctx); 87unsigned char *psb_android_output_init(VADriverContextP ctx); 88VAStatus psb_android_output_deinit(VADriverContextP ctx); 89 90int psb_coverlay_init(VADriverContextP ctx); 91int psb_coverlay_deinit(VADriverContextP ctx); 92 93VAStatus psb_initOutput(VADriverContextP ctx) 94{ 95 INIT_DRIVER_DATA; 96 unsigned char *ws_priv = NULL; 97 char *fps = NULL; 98 char env_value[1024]; 99 100 pthread_mutex_init(&driver_data->output_mutex, NULL); 101 102 if (psb_parse_config("PSB_VIDEO_PUTSURFACE_DUMMY", &env_value[0]) == 0) { 103 psb__information_message("vaPutSurface: dummy mode, return directly\n"); 104 driver_data->dummy_putsurface = 0; 105 106 return VA_STATUS_SUCCESS; 107 } 108 109 if (psb_parse_config("PSB_VIDEO_FPS", &env_value[0]) == 0) { 110 driver_data->fixed_fps = atoi(env_value); 111 psb__information_message("Throttling at FPS=%d\n", driver_data->fixed_fps); 112 } else 113 driver_data->fixed_fps = 0; 114 115 driver_data->outputmethod_checkinterval = 1; 116 if (psb_parse_config("PSB_VIDEO_INTERVAL", &env_value[0]) == 0) { 117 driver_data->outputmethod_checkinterval = atoi(env_value); 118 psb__information_message("Check output method at %d frames interval\n", 119 driver_data->outputmethod_checkinterval); 120 } 121 122 driver_data->cur_displaying_surface = VA_INVALID_SURFACE; 123 driver_data->last_displaying_surface = VA_INVALID_SURFACE; 124 125 psb_InitRotate(ctx); 126 127#ifdef ANDROID 128 ws_priv = psb_android_output_init(ctx); 129 driver_data->is_android = 1; 130#else 131 ws_priv = psb_x11_output_init(ctx); 132 driver_data->is_android = 0; 133#endif 134 driver_data->ws_priv = ws_priv; 135 136 137 //use client textureblit 138 if (driver_data->ctexture == 1) { 139 int ret = psb_ctexture_init(ctx); 140 if (ret != 0) 141 driver_data->ctexture = 0; 142 } 143 144 /* 145 //use texture streaming 146 if (driver_data->ctexstreaming == 1) 147 psb_ctexstreaing_init(ctx); 148 */ 149 150 return VA_STATUS_SUCCESS; 151} 152 153VAStatus psb_deinitOutput( 154 VADriverContextP ctx 155) 156{ 157 INIT_DRIVER_DATA; 158 159 //use client textureblit 160 if (driver_data->ctexture == 1) 161 psb_ctexture_deinit(ctx); 162 163 if (driver_data->coverlay_init) { 164 psb_coverlay_deinit(ctx); 165 driver_data->coverlay_init = 0; 166 } 167 168#ifndef ANDROID 169 psb_x11_output_deinit(ctx); 170#else 171 psb_android_output_deinit(ctx); 172#endif 173 174 /* free here, but allocate in window system specific */ 175 free(driver_data->ws_priv); 176 /* 177 //use texture streaming 178 if (driver_data->ctexstreaming == 1) 179 psb_ctexstreaing_deinit(ctx); 180 */ 181 /* clean the displaying surface information in kernel */ 182 psb_surface_set_displaying(driver_data, 0, 0, NULL); 183 184 pthread_mutex_destroy(&driver_data->output_mutex); 185 186 return VA_STATUS_SUCCESS; 187} 188 189#ifndef VA_STATUS_ERROR_INVALID_IMAGE_FORMAT 190#define VA_STATUS_ERROR_INVALID_IMAGE_FORMAT VA_STATUS_ERROR_UNKNOWN 191#endif 192 193static VAImageFormat *psb__VAImageCheckFourCC( 194 VAImageFormat *src_format, 195 VAImageFormat *dst_format, 196 int dst_num 197) 198{ 199 int i; 200 if (NULL == src_format || dst_format == NULL) { 201 return NULL; 202 } 203 204 /* check VAImage at first */ 205 for (i = 0; i < dst_num; i++) { 206 if (dst_format[i].fourcc == src_format->fourcc) 207 return &dst_format[i]; 208 } 209 210 psb__error_message("Unsupport fourcc 0x%x\n", src_format->fourcc); 211 return NULL; 212} 213 214static void psb__VAImageCheckRegion( 215 object_surface_p surface, 216 VAImage *image, 217 int *src_x, 218 int *src_y, 219 int *dest_x, 220 int *dest_y, 221 int *width, 222 int *height 223) 224{ 225 /* check for image */ 226 if (*src_x < 0) *src_x = 0; 227 if (*src_x > image->width) *src_x = image->width - 1; 228 if (*src_y < 0) *src_y = 0; 229 if (*src_y > image->height) *src_y = image->height - 1; 230 231 if (((*width) + (*src_x)) > image->width) *width = image->width - *src_x; 232 if (((*height) + (*src_y)) > image->height) *height = image->height - *src_x; 233 234 /* check for surface */ 235 if (*dest_x < 0) *dest_x = 0; 236 if (*dest_x > surface->width) *dest_x = surface->width - 1; 237 if (*dest_y < 0) *dest_y = 0; 238 if (*dest_y > surface->height) *dest_y = surface->height - 1; 239 240 if (((*width) + (*dest_x)) > surface->width) *width = surface->width - *dest_x; 241 if (((*height) + (*dest_y)) > surface->height) *height = surface->height - *dest_x; 242} 243 244 245VAStatus psb_QueryImageFormats( 246 VADriverContextP ctx, 247 VAImageFormat *format_list, /* out */ 248 int *num_formats /* out */ 249) 250{ 251 VAStatus vaStatus = VA_STATUS_SUCCESS; 252 253 if (NULL == format_list) { 254 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 255 DEBUG_FAILURE; 256 return vaStatus; 257 } 258 if (NULL == num_formats) { 259 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 260 DEBUG_FAILURE; 261 return vaStatus; 262 } 263 memcpy(format_list, psb__CreateImageFormat, sizeof(psb__CreateImageFormat)); 264 *num_formats = PSB_MAX_IMAGE_FORMATS; 265 266 return VA_STATUS_SUCCESS; 267} 268 269inline int min_POT(int n) 270{ 271 if ((n & (n - 1)) == 0) /* already POT */ 272 return n; 273 274 return n |= n >> 16, n |= n >> 8, n |= n >> 4, n |= n >> 2, n |= n >> 1, n + 1; 275 /* return ((((n |= n>>16) |= n>>8) |= n>>4) |= n>>2) |= n>>1, n + 1; */ 276} 277 278VAStatus psb_CreateImage( 279 VADriverContextP ctx, 280 VAImageFormat *format, 281 int width, 282 int height, 283 VAImage *image /* out */ 284) 285{ 286 INIT_DRIVER_DATA; 287 VAImageID imageID; 288 object_image_p obj_image; 289 VAStatus vaStatus = VA_STATUS_SUCCESS; 290 VAImageFormat *img_fmt; 291 int pitch_pot; 292 293 (void)driver_data; 294 295 img_fmt = psb__VAImageCheckFourCC(format, psb__CreateImageFormat, 296 sizeof(psb__CreateImageFormat) / sizeof(VAImageFormat)); 297 if (img_fmt == NULL) 298 return VA_STATUS_ERROR_UNKNOWN; 299 300 if (NULL == image) { 301 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 302 return vaStatus; 303 } 304 305 imageID = object_heap_allocate(&driver_data->image_heap); 306 obj_image = IMAGE(imageID); 307 if (NULL == obj_image) { 308 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 309 return vaStatus; 310 } 311 312 MEMSET_OBJECT(obj_image, struct object_image_s); 313 314 obj_image->image.image_id = imageID; 315 obj_image->image.format = *img_fmt; 316 obj_image->subpic_ref = 0; 317 318 pitch_pot = min_POT(width); 319 320 switch (format->fourcc) { 321 case VA_FOURCC_NV12: { 322 obj_image->image.width = width; 323 obj_image->image.height = height; 324 obj_image->image.data_size = pitch_pot * height /*Y*/ + 2 * (pitch_pot / 2) * (height / 2);/*UV*/ 325 obj_image->image.num_planes = 2; 326 obj_image->image.pitches[0] = pitch_pot; 327 obj_image->image.pitches[1] = pitch_pot; 328 obj_image->image.offsets[0] = 0; 329 obj_image->image.offsets[1] = pitch_pot * height; 330 obj_image->image.num_palette_entries = 0; 331 obj_image->image.entry_bytes = 0; 332 obj_image->image.component_order[0] = 'Y'; 333 obj_image->image.component_order[1] = 'U';/* fixed me: packed UV packed here! */ 334 obj_image->image.component_order[2] = 'V'; 335 obj_image->image.component_order[3] = '\0'; 336 break; 337 } 338 case VA_FOURCC_AYUV: { 339 obj_image->image.width = width; 340 obj_image->image.height = height; 341 obj_image->image.data_size = 4 * pitch_pot * height; 342 obj_image->image.num_planes = 1; 343 obj_image->image.pitches[0] = 4 * pitch_pot; 344 obj_image->image.num_palette_entries = 0; 345 obj_image->image.entry_bytes = 0; 346 obj_image->image.component_order[0] = 'V'; 347 obj_image->image.component_order[1] = 'U'; 348 obj_image->image.component_order[2] = 'Y'; 349 obj_image->image.component_order[3] = 'A'; 350 break; 351 } 352 case VA_FOURCC_RGBA: { 353 obj_image->image.width = width; 354 obj_image->image.height = height; 355 obj_image->image.data_size = 4 * pitch_pot * height; 356 obj_image->image.num_planes = 1; 357 obj_image->image.pitches[0] = 4 * pitch_pot; 358 obj_image->image.num_palette_entries = 0; 359 obj_image->image.entry_bytes = 0; 360 obj_image->image.component_order[0] = 'R'; 361 obj_image->image.component_order[1] = 'G'; 362 obj_image->image.component_order[2] = 'B'; 363 obj_image->image.component_order[3] = 'A'; 364 break; 365 } 366 case VA_FOURCC_AI44: { 367 obj_image->image.width = width; 368 obj_image->image.height = height; 369 obj_image->image.data_size = pitch_pot * height;/* one byte one element */ 370 obj_image->image.num_planes = 1; 371 obj_image->image.pitches[0] = pitch_pot; 372 obj_image->image.num_palette_entries = 16; 373 obj_image->image.entry_bytes = 4; /* AYUV */ 374 obj_image->image.component_order[0] = 'I'; 375 obj_image->image.component_order[1] = 'A'; 376 obj_image->image.component_order[2] = '\0'; 377 obj_image->image.component_order[3] = '\0'; 378 break; 379 } 380 case VA_FOURCC_IYUV: { 381 obj_image->image.width = width; 382 obj_image->image.height = height; 383 obj_image->image.data_size = pitch_pot * height /*Y*/ + 2 * (pitch_pot / 2) * (height / 2);/*UV*/ 384 obj_image->image.num_planes = 3; 385 obj_image->image.pitches[0] = pitch_pot; 386 obj_image->image.pitches[1] = pitch_pot / 2; 387 obj_image->image.pitches[2] = pitch_pot / 2; 388 obj_image->image.offsets[0] = 0; 389 obj_image->image.offsets[1] = pitch_pot * height; 390 obj_image->image.offsets[2] = pitch_pot * height + (pitch_pot / 2) * (height / 2); 391 obj_image->image.num_palette_entries = 0; 392 obj_image->image.entry_bytes = 0; 393 obj_image->image.component_order[0] = 'Y'; 394 obj_image->image.component_order[1] = 'U'; 395 obj_image->image.component_order[2] = 'V'; 396 obj_image->image.component_order[3] = '\0'; 397 break; 398 } 399 default: { 400 vaStatus = VA_STATUS_ERROR_INVALID_IMAGE_FORMAT; 401 break; 402 } 403 } 404 405 if (VA_STATUS_SUCCESS == vaStatus) { 406 /* create the buffer */ 407 vaStatus = psb__CreateBuffer(driver_data, NULL, VAImageBufferType, 408 obj_image->image.data_size, 1, NULL, &obj_image->image.buf); 409 } 410 411 obj_image->derived_surface = 0; 412 413 if (VA_STATUS_SUCCESS != vaStatus) { 414 object_heap_free(&driver_data->image_heap, (object_base_p) obj_image); 415 } else { 416 memcpy(image, &obj_image->image, sizeof(VAImage)); 417 } 418 419 return vaStatus; 420} 421 422VAStatus psb_DeriveImage( 423 VADriverContextP ctx, 424 VASurfaceID surface, 425 VAImage *image /* out */ 426) 427{ 428 INIT_DRIVER_DATA; 429 VAStatus vaStatus = VA_STATUS_SUCCESS; 430 VABufferID bufferID; 431 object_buffer_p obj_buffer; 432 VAImageID imageID; 433 object_image_p obj_image; 434 object_surface_p obj_surface = SURFACE(surface); 435 unsigned int fourcc, fourcc_index = ~0, i; 436 uint32_t srf_buf_ofs = 0; 437 438 if (NULL == obj_surface) { 439 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 440 DEBUG_FAILURE; 441 return vaStatus; 442 } 443 444 if (NULL == image) { 445 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 446 return vaStatus; 447 } 448 449 fourcc = obj_surface->psb_surface->extra_info[4]; 450 for (i = 0; i < PSB_MAX_IMAGE_FORMATS; i++) { 451 if (psb__CreateImageFormat[i].fourcc == fourcc) { 452 fourcc_index = i; 453 break; 454 } 455 } 456 if (i == PSB_MAX_IMAGE_FORMATS) { 457 psb__error_message("Can't support the Fourcc\n"); 458 vaStatus = VA_STATUS_ERROR_OPERATION_FAILED; 459 return vaStatus; 460 } 461 462 /* create the image */ 463 imageID = object_heap_allocate(&driver_data->image_heap); 464 obj_image = IMAGE(imageID); 465 if (NULL == obj_image) { 466 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 467 return vaStatus; 468 } 469 470 MEMSET_OBJECT(obj_image, struct object_image_s); 471 472 /* create a buffer to represent surface buffer */ 473 bufferID = object_heap_allocate(&driver_data->buffer_heap); 474 obj_buffer = BUFFER(bufferID); 475 if (NULL == obj_buffer) { 476 object_heap_free(&driver_data->image_heap, (object_base_p) obj_image); 477 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 478 DEBUG_FAILURE; 479 return vaStatus; 480 } 481 MEMSET_OBJECT(obj_buffer, struct object_buffer_s); 482 483 obj_buffer->type = VAImageBufferType; 484 obj_buffer->buffer_data = NULL; 485 obj_buffer->psb_buffer = &obj_surface->psb_surface->buf; 486 obj_buffer->size = obj_surface->psb_surface->size; 487 obj_buffer->max_num_elements = 0; 488 obj_buffer->alloc_size = obj_buffer->size; 489 490 /* fill obj_image data structure */ 491 obj_image->image.image_id = imageID; 492 obj_image->image.format = psb__CreateImageFormat[fourcc_index]; 493 obj_image->subpic_ref = 0; 494 495 obj_image->image.buf = bufferID; 496 obj_image->image.width = obj_surface->width; 497 obj_image->image.height = obj_surface->height; 498 obj_image->image.data_size = obj_surface->psb_surface->size; 499 500 srf_buf_ofs = obj_surface->psb_surface->buf.buffer_ofs; 501 502 switch (fourcc) { 503 case VA_FOURCC_NV12: { 504 obj_image->image.num_planes = 2; 505 obj_image->image.pitches[0] = obj_surface->psb_surface->stride; 506 obj_image->image.pitches[1] = obj_surface->psb_surface->stride; 507 508 obj_image->image.offsets[0] = srf_buf_ofs; 509 obj_image->image.offsets[1] = srf_buf_ofs + obj_surface->height * obj_surface->psb_surface->stride; 510 obj_image->image.num_palette_entries = 0; 511 obj_image->image.entry_bytes = 0; 512 obj_image->image.component_order[0] = 'Y'; 513 obj_image->image.component_order[1] = 'U';/* fixed me: packed UV packed here! */ 514 obj_image->image.component_order[2] = 'V'; 515 obj_image->image.component_order[3] = '\0'; 516 break; 517 } 518 case VA_FOURCC_YV16: { 519 obj_image->image.num_planes = 3; 520 obj_image->image.pitches[0] = obj_surface->psb_surface->stride; 521 obj_image->image.pitches[1] = obj_surface->psb_surface->stride / 2; 522 obj_image->image.pitches[2] = obj_surface->psb_surface->stride / 2; 523 524 obj_image->image.offsets[0] = srf_buf_ofs; 525 obj_image->image.offsets[1] = srf_buf_ofs + obj_surface->height * obj_surface->psb_surface->stride; 526 obj_image->image.offsets[2] = srf_buf_ofs + obj_surface->height * obj_surface->psb_surface->stride * 3 / 2; 527 obj_image->image.num_palette_entries = 0; 528 obj_image->image.entry_bytes = 0; 529 obj_image->image.component_order[0] = 'Y'; 530 obj_image->image.component_order[1] = 'V';/* fixed me: packed UV packed here! */ 531 obj_image->image.component_order[2] = 'U'; 532 obj_image->image.component_order[3] = '\0'; 533 break; 534 } 535 default: 536 break; 537 } 538 539 obj_image->derived_surface = surface; /* this image is derived from a surface */ 540 obj_surface->derived_imgcnt++; 541 542 memcpy(image, &obj_image->image, sizeof(VAImage)); 543 544 return vaStatus; 545} 546 547VAStatus psb__destroy_image(psb_driver_data_p driver_data, object_image_p obj_image) 548{ 549 VAStatus vaStatus = VA_STATUS_SUCCESS; 550 551 if (obj_image->subpic_ref > 0) { 552 vaStatus = VA_STATUS_ERROR_OPERATION_FAILED; 553 return vaStatus; 554 } 555 556 object_surface_p obj_surface = SURFACE(obj_image->derived_surface); 557 558 if (obj_surface == NULL) { /* destroy the buffer */ 559 object_buffer_p obj_buffer = BUFFER(obj_image->image.buf); 560 if (NULL == obj_buffer) { 561 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 562 DEBUG_FAILURE; 563 return vaStatus; 564 } 565 psb__suspend_buffer(driver_data, obj_buffer); 566 } else { 567 object_buffer_p obj_buffer = BUFFER(obj_image->image.buf); 568 object_heap_free(&driver_data->buffer_heap, &obj_buffer->base); 569 obj_surface->derived_imgcnt--; 570 } 571 object_heap_free(&driver_data->image_heap, (object_base_p) obj_image); 572 573 return VA_STATUS_SUCCESS; 574} 575 576VAStatus psb_DestroyImage( 577 VADriverContextP ctx, 578 VAImageID image 579) 580{ 581 INIT_DRIVER_DATA 582 VAStatus vaStatus = VA_STATUS_SUCCESS; 583 object_image_p obj_image; 584 585 obj_image = IMAGE(image); 586 if (NULL == obj_image) { 587 vaStatus = VA_STATUS_ERROR_INVALID_IMAGE; 588 DEBUG_FAILURE; 589 return vaStatus; 590 } 591 return psb__destroy_image(driver_data, obj_image); 592} 593 594VAStatus psb_SetImagePalette( 595 VADriverContextP ctx, 596 VAImageID image, 597 /* 598 * pointer to an array holding the palette data. The size of the array is 599 * num_palette_entries * entry_bytes in size. The order of the components 600 * in the palette is described by the component_order in VAImage struct 601 */ 602 unsigned char *palette 603) 604{ 605 INIT_DRIVER_DATA; 606 VAStatus vaStatus = VA_STATUS_SUCCESS; 607 608 object_image_p obj_image = IMAGE(image); 609 if (NULL == obj_image) { 610 vaStatus = VA_STATUS_ERROR_INVALID_IMAGE; 611 DEBUG_FAILURE; 612 return vaStatus; 613 } 614 615 if (obj_image->image.format.fourcc != VA_FOURCC_AI44) { 616 /* only support AI44 palette */ 617 vaStatus = VA_STATUS_ERROR_OPERATION_FAILED; 618 return vaStatus; 619 } 620 621 if (obj_image->image.num_palette_entries > 16) { 622 psb__error_message("image.num_palette_entries(%d) is too big\n", obj_image->image.num_palette_entries); 623 memcpy(obj_image->palette, palette, 16); 624 } else 625 memcpy(obj_image->palette, palette, obj_image->image.num_palette_entries * sizeof(unsigned int)); 626 627 return vaStatus; 628} 629 630static VAStatus lnc_unpack_topaz_rec(int src_width, int src_height, 631 unsigned char *p_srcY, unsigned char *p_srcUV, 632 unsigned char *p_dstY, unsigned char *p_dstU, unsigned char *p_dstV, 633 int dstY_stride, int dstU_stride, int dstV_stride, 634 int surface_height) 635{ 636 unsigned char *tmp_dstY = NULL; 637 unsigned char *tmp_dstUV = NULL; 638 639 int n, i, index; 640 641 psb__information_message("Unpack reconstructed frame to image\n"); 642 643 /* do this one column at a time. */ 644 tmp_dstY = (unsigned char *)calloc(1, 16 * src_height); 645 if (tmp_dstY == NULL) 646 return VA_STATUS_ERROR_ALLOCATION_FAILED; 647 648 tmp_dstUV = (unsigned char*)calloc(1, 16 * src_height / 2); 649 if (tmp_dstUV == NULL) { 650 free(tmp_dstY); 651 return VA_STATUS_ERROR_ALLOCATION_FAILED; 652 } 653 654 /* Copy Y data */ 655 for (n = 0; n < src_width / 16; n++) { 656 memcpy((void*)tmp_dstY, p_srcY, 16 * src_height); 657 p_srcY += (16 * surface_height); 658 for (i = 0; i < src_height; i++) { 659 memcpy(p_dstY + dstY_stride * i + n * 16, tmp_dstY + 16 * i, 16); 660 } 661 } 662 663 /* Copy U/V data */ 664 for (n = 0; n < src_width / 16; n++) { 665 memcpy((void*)tmp_dstUV, p_srcUV, 16 * src_height / 2); 666 p_srcUV += (16 * surface_height / 2); 667 for (i = 0; i < src_height / 2; i++) { 668 for (index = 0; index < 8; index++) { 669 p_dstU[i*dstU_stride + n*8 + index] = tmp_dstUV[index*2 + i*16]; 670 p_dstV[i*dstV_stride + n*8 + index] = tmp_dstUV[index*2 + i*16+1]; 671 } 672 } 673 } 674 if (tmp_dstY) 675 free(tmp_dstY); 676 if (tmp_dstUV) 677 free(tmp_dstUV); 678 679 return VA_STATUS_SUCCESS; 680} 681 682 683VAStatus psb_GetImage( 684 VADriverContextP ctx, 685 VASurfaceID surface, 686 int x, /* coordinates of the upper left source pixel */ 687 int y, 688 unsigned int width, /* width and height of the region */ 689 unsigned int height, 690 VAImageID image_id 691) 692{ 693 INIT_DRIVER_DATA; 694 VAStatus vaStatus = VA_STATUS_SUCCESS; 695 int ret, src_x = 0, src_y = 0, dest_x = 0, dest_y = 0; 696 697 (void)driver_data; 698 (void)lnc_unpack_topaz_rec; 699 700 object_image_p obj_image = IMAGE(image_id); 701 if (NULL == obj_image) { 702 psb__error_message("Invalidate Image\n"); 703 704 vaStatus = VA_STATUS_ERROR_INVALID_IMAGE; 705 DEBUG_FAILURE; 706 return vaStatus; 707 } 708 709 if (obj_image->image.format.fourcc != VA_FOURCC_NV12) { 710 psb__error_message("target VAImage fourcc should be NV12 or IYUV\n"); 711 vaStatus = VA_STATUS_ERROR_OPERATION_FAILED; 712 return vaStatus; 713 } 714 715 object_surface_p obj_surface = SURFACE(surface); 716 if (NULL == obj_surface) { 717 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 718 DEBUG_FAILURE; 719 return vaStatus; 720 } 721 722 psb__VAImageCheckRegion(obj_surface, &obj_image->image, &src_x, &src_y, &dest_x, &dest_y, 723 (int *)&width, (int *)&height); 724 725 psb_surface_p psb_surface = obj_surface->psb_surface; 726 unsigned char *surface_data; 727 ret = psb_buffer_map(&psb_surface->buf, &surface_data); 728 if (ret) { 729 return VA_STATUS_ERROR_UNKNOWN; 730 } 731 732 object_buffer_p obj_buffer = BUFFER(obj_image->image.buf); 733 if (NULL == obj_buffer) { 734 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 735 DEBUG_FAILURE; 736 return vaStatus; 737 } 738 739 unsigned char *image_data; 740 ret = psb_buffer_map(obj_buffer->psb_buffer, &image_data); 741 if (ret) { 742 psb__error_message("Map buffer failed\n"); 743 744 psb_buffer_unmap(&psb_surface->buf); 745 return VA_STATUS_ERROR_UNKNOWN; 746 } 747 748 image_data += obj_surface->psb_surface->buf.buffer_ofs; 749 750 switch (obj_image->image.format.fourcc) { 751 case VA_FOURCC_NV12: { 752 unsigned char *source_y, *src_uv, *dst_y, *dst_uv; 753 unsigned int i; 754 /* copy Y plane */ 755 dst_y = image_data; 756 source_y = surface_data + y * psb_surface->stride + x; 757 for (i = 0; i < height; i++) { 758 memcpy(dst_y, source_y, width); 759 dst_y += obj_image->image.pitches[0]; 760 source_y += psb_surface->stride; 761 } 762 763 /* copy UV plane */ 764 dst_uv = image_data + obj_image->image.offsets[1]; 765 src_uv = surface_data + psb_surface->stride * obj_surface->height + (y / 2) * psb_surface->stride + x;; 766 for (i = 0; i < obj_image->image.height / 2; i++) { 767 memcpy(dst_uv, src_uv, width); 768 dst_uv += obj_image->image.pitches[1]; 769 src_uv += psb_surface->stride; 770 } 771 break; 772 } 773#if 0 774 case VA_FOURCC_IYUV: { 775 unsigned char *source_y, *dst_y; 776 unsigned char *source_uv, *source_u, *source_v, *dst_u, *dst_v; 777 unsigned int i; 778 779 if (psb_surface->extra_info[4] == VA_FOURCC_IREC) { 780 /* copy Y plane */ 781 dst_y = image_data + obj_image->image.offsets[0] + src_y * obj_image->image.pitches[0] + src_x; 782 dst_u = image_data + obj_image->image.offsets[1] + src_y * obj_image->image.pitches[1] + src_x; 783 dst_v = image_data + obj_image->image.offsets[2] + src_y * obj_image->image.pitches[2] + src_x; 784 785 source_y = surface_data + dest_y * psb_surface->stride + dest_x; 786 source_uv = surface_data + obj_surface->height * psb_surface->stride 787 + dest_y * (psb_surface->stride / 2) + dest_x; 788 789 vaStatus = lnc_unpack_topaz_rec(width, height, source_y, source_uv, 790 dst_y, dst_u, dst_v, 791 obj_image->image.pitches[0], 792 obj_image->image.pitches[1], 793 obj_image->image.pitches[2], 794 obj_surface->height); 795 } 796 797 break; 798 } 799#endif 800 default: 801 break; 802 } 803 psb_buffer_unmap(obj_buffer->psb_buffer); 804 psb_buffer_unmap(&psb_surface->buf); 805 806 return vaStatus; 807} 808 809static VAStatus psb_PutImage2( 810 VADriverContextP ctx, 811 VASurfaceID surface, 812 VAImageID image_id, 813 int src_x, 814 int src_y, 815 unsigned int width, 816 unsigned int height, 817 int dest_x, 818 int dest_y 819) 820{ 821 INIT_DRIVER_DATA; 822 VAStatus vaStatus = VA_STATUS_SUCCESS; 823 int ret; 824 825 object_image_p obj_image = IMAGE(image_id); 826 if (NULL == obj_image) { 827 vaStatus = VA_STATUS_ERROR_INVALID_IMAGE; 828 DEBUG_FAILURE; 829 return vaStatus; 830 } 831 832 object_surface_p obj_surface = SURFACE(surface); 833 if (NULL == obj_surface) { 834 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 835 DEBUG_FAILURE; 836 return vaStatus; 837 } 838 839 if (obj_image->image.format.fourcc != VA_FOURCC_NV12) { 840 psb__error_message("target VAImage fourcc should be NV12 or IYUV\n"); 841 vaStatus = VA_STATUS_ERROR_OPERATION_FAILED; 842 return vaStatus; 843 } 844 845 psb__VAImageCheckRegion(obj_surface, &obj_image->image, &src_x, &src_y, &dest_x, &dest_y, 846 (int *)&width, (int *)&height); 847 848 psb_surface_p psb_surface = obj_surface->psb_surface; 849 unsigned char *surface_data; 850 ret = psb_buffer_map(&psb_surface->buf, &surface_data); 851 if (ret) { 852 return VA_STATUS_ERROR_UNKNOWN; 853 } 854 855 object_buffer_p obj_buffer = BUFFER(obj_image->image.buf); 856 if (NULL == obj_buffer) { 857 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 858 DEBUG_FAILURE; 859 return vaStatus; 860 } 861 862 unsigned char *image_data; 863 ret = psb_buffer_map(obj_buffer->psb_buffer, &image_data); 864 if (ret) { 865 psb_buffer_unmap(&psb_surface->buf); 866 return VA_STATUS_ERROR_UNKNOWN; 867 } 868 869 image_data += obj_surface->psb_surface->buf.buffer_ofs; 870 871 switch (obj_image->image.format.fourcc) { 872 case VA_FOURCC_NV12: { 873 unsigned char *source_y, *src_uv, *dst_y, *dst_uv; 874 unsigned int i; 875 876 /* copy Y plane */ 877 source_y = image_data + obj_image->image.offsets[0] + src_y * obj_image->image.pitches[0] + src_x; 878 dst_y = surface_data + dest_y * psb_surface->stride + dest_x; 879 for (i = 0; i < height; i++) { 880 memcpy(dst_y, source_y, width); 881 source_y += obj_image->image.pitches[0]; 882 dst_y += psb_surface->stride; 883 } 884 885 /* copy UV plane */ 886 src_uv = image_data + obj_image->image.offsets[1] + (src_y / 2) * obj_image->image.pitches[1] + src_x; 887 dst_uv = surface_data + psb_surface->stride * obj_surface->height + (dest_y / 2) * psb_surface->stride + dest_x; 888 for (i = 0; i < obj_image->image.height / 2; i++) { 889 memcpy(dst_uv, src_uv, width); 890 src_uv += obj_image->image.pitches[1]; 891 dst_uv += psb_surface->stride; 892 } 893 break; 894 } 895#if 0 896 case VA_FOURCC_IYUV: { 897 char *source_y, *dst_y; 898 char *source_u, *source_v, *dst_u, *dst_v; 899 unsigned int i; 900 901 /* copy Y plane */ 902 source_y = image_data + obj_image->image.offsets[0] + src_y * obj_image->image.pitches[0] + src_x; 903 source_u = image_data + obj_image->image.offsets[1] + src_y * obj_image->image.pitches[1] + src_x; 904 source_v = image_data + obj_image->image.offsets[2] + src_y * obj_image->image.pitches[2] + src_x; 905 906 dst_y = surface_data + dest_y * psb_surface->stride + dest_x; 907 dst_u = surface_data + obj_surface->height * psb_surface->stride 908 + dest_y * (psb_surface->stride / 2) + dest_x; 909 dst_v = surface_data + obj_surface->height * psb_surface->stride 910 + (obj_surface->height / 2) * (psb_surface->stride / 2) 911 + dest_y * (psb_surface->stride / 2) + dest_x; 912 913 for (i = 0; i < height; i++) { 914 memcpy(dst_y, source_y, width); 915 source_y += obj_image->image.pitches[0]; 916 dst_y += psb_surface->stride; 917 } 918 919 /* copy UV plane */ 920 for (i = 0; i < obj_image->image.height / 2; i++) { 921 memcpy(dst_u, source_u, width); 922 memcpy(dst_v, source_v, width); 923 924 source_u += obj_image->image.pitches[1]; 925 source_v += obj_image->image.pitches[2]; 926 927 dst_u += psb_surface->stride / 2; 928 dst_v += psb_surface->stride / 2; 929 } 930 break; 931 } 932#endif 933 default: 934 break; 935 } 936 937 psb_buffer_unmap(obj_buffer->psb_buffer); 938 psb_buffer_unmap(&psb_surface->buf); 939 940 return VA_STATUS_SUCCESS; 941} 942 943 944static void psb__VAImageCheckRegion2( 945 object_surface_p surface, 946 VAImage *image, 947 int *src_x, 948 int *src_y, 949 unsigned int *src_width, 950 unsigned int *src_height, 951 int *dest_x, 952 int *dest_y, 953 int *dest_width, 954 int *dest_height 955) 956{ 957 /* check for image */ 958 if (*src_x < 0) *src_x = 0; 959 if (*src_x > image->width) *src_x = image->width - 1; 960 if (*src_y < 0) *src_y = 0; 961 if (*src_y > image->height) *src_y = image->height - 1; 962 963 if (((*src_width) + (*src_x)) > image->width) *src_width = image->width - *src_x; 964 if (((*src_height) + (*src_y)) > image->height) *src_height = image->height - *src_x; 965 966 /* check for surface */ 967 if (*dest_x < 0) *dest_x = 0; 968 if (*dest_x > surface->width) *dest_x = surface->width - 1; 969 if (*dest_y < 0) *dest_y = 0; 970 if (*dest_y > surface->height) *dest_y = surface->height - 1; 971 972 if (((*dest_width) + (*dest_x)) > (int)surface->width) *dest_width = surface->width - *dest_x; 973 if (((*dest_height) + (*dest_y)) > (int)surface->height) *dest_height = surface->height - *dest_x; 974} 975 976VAStatus psb_PutImage( 977 VADriverContextP ctx, 978 VASurfaceID surface, 979 VAImageID image_id, 980 int src_x, 981 int src_y, 982 unsigned int src_width, 983 unsigned int src_height, 984 int dest_x, 985 int dest_y, 986 unsigned int dest_width, 987 unsigned int dest_height 988) 989{ 990 INIT_DRIVER_DATA; 991 VAStatus vaStatus = VA_STATUS_SUCCESS; 992 int ret; 993 994 if ((src_width == dest_width) && (src_height == dest_height)) { 995 /* Shortcut if scaling is not required */ 996 return psb_PutImage2(ctx, surface, image_id, src_x, src_y, src_width, src_height, dest_x, dest_y); 997 } 998 999 object_image_p obj_image = IMAGE(image_id); 1000 if (NULL == obj_image) { 1001 vaStatus = VA_STATUS_ERROR_INVALID_IMAGE; 1002 DEBUG_FAILURE; 1003 return vaStatus; 1004 } 1005 1006 if (obj_image->image.format.fourcc != VA_FOURCC_NV12) { 1007 /* only support NV12 getImage/putImage */ 1008 vaStatus = VA_STATUS_ERROR_OPERATION_FAILED; 1009 return vaStatus; 1010 } 1011 1012 object_surface_p obj_surface = SURFACE(surface); 1013 if (NULL == obj_surface) { 1014 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1015 DEBUG_FAILURE; 1016 return vaStatus; 1017 } 1018 1019 psb__VAImageCheckRegion2(obj_surface, &obj_image->image, 1020 &src_x, &src_y, &src_width, &src_height, 1021 &dest_x, &dest_y, (int *)&dest_width, (int *)&dest_height); 1022 1023 psb_surface_p psb_surface = obj_surface->psb_surface; 1024 unsigned char *surface_data; 1025 ret = psb_buffer_map(&psb_surface->buf, &surface_data); 1026 if (ret) { 1027 return VA_STATUS_ERROR_UNKNOWN; 1028 } 1029 1030 object_buffer_p obj_buffer = BUFFER(obj_image->image.buf); 1031 if (NULL == obj_buffer) { 1032 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 1033 DEBUG_FAILURE; 1034 return vaStatus; 1035 } 1036 1037 unsigned char *image_data; 1038 ret = psb_buffer_map(obj_buffer->psb_buffer, &image_data); 1039 if (ret) { 1040 psb_buffer_unmap(&psb_surface->buf); 1041 return VA_STATUS_ERROR_UNKNOWN; 1042 } 1043 1044 /* just a prototype, the algorithm is ugly and not optimized */ 1045 switch (obj_image->image.format.fourcc) { 1046 case VA_FOURCC_NV12: { 1047 unsigned char *source_y, *dst_y; 1048 unsigned short *source_uv, *dst_uv; 1049 unsigned int i, j; 1050 float xratio = (float) src_width / dest_width; 1051 float yratio = (float) src_height / dest_height; 1052 1053 /* dst_y/dst_uv: Y/UV plane of destination */ 1054 dst_y = (unsigned char *)(surface_data + dest_y * psb_surface->stride + dest_x); 1055 dst_uv = (unsigned short *)(surface_data + psb_surface->stride * obj_surface->height 1056 + (dest_y / 2) * psb_surface->stride + dest_x); 1057 1058 for (j = 0; j < dest_height; j++) { 1059 unsigned char *dst_y_tmp = dst_y; 1060 unsigned short *dst_uv_tmp = dst_uv; 1061 1062 for (i = 0; i < dest_width; i++) { 1063 int x = (int)(i * xratio); 1064 int y = (int)(j * yratio); 1065 1066 source_y = image_data + obj_image->image.offsets[0] 1067 + (src_y + y) * obj_image->image.pitches[0] 1068 + (src_x + x); 1069 *dst_y_tmp = *source_y; 1070 dst_y_tmp++; 1071 1072 if (((i & 1) == 0)) { 1073 source_uv = (unsigned short *)(image_data + obj_image->image.offsets[1] 1074 + ((src_y + y) / 2) * obj_image->image.pitches[1]) 1075 + ((src_x + x) / 2); 1076 *dst_uv_tmp = *source_uv; 1077 dst_uv_tmp++; 1078 } 1079 } 1080 dst_y += psb_surface->stride; 1081 1082 if (j & 1) 1083 dst_uv = (unsigned short *)((unsigned char *)dst_uv + psb_surface->stride); 1084 } 1085 break; 1086 } 1087 default:/* will not reach here */ 1088 break; 1089 } 1090 1091 psb_buffer_unmap(obj_buffer->psb_buffer); 1092 psb_buffer_unmap(&psb_surface->buf); 1093 1094 return VA_STATUS_SUCCESS; 1095} 1096 1097/* 1098 * Link supbicture into one surface, when update is zero, not need to 1099 * update the location information 1100 * The image informatio and its BO of subpicture will copied to surface 1101 * so need to update it when a vaSetSubpictureImage is called 1102 */ 1103static VAStatus psb__LinkSubpictIntoSurface( 1104 psb_driver_data_p driver_data, 1105 object_surface_p obj_surface, 1106 object_subpic_p obj_subpic, 1107 short src_x, 1108 short src_y, 1109 unsigned short src_w, 1110 unsigned short src_h, 1111 short dest_x, 1112 short dest_y, 1113 unsigned short dest_w, 1114 unsigned short dest_h, 1115 int update /* update subpicture location */ 1116) 1117{ 1118 PsbVASurfaceRec *surface_subpic; 1119 object_image_p obj_image = IMAGE(obj_subpic->image_id); 1120 if (NULL == obj_image) { 1121 return VA_STATUS_ERROR_INVALID_IMAGE; 1122 } 1123 1124 VAImage *image = &obj_image->image; 1125 object_buffer_p obj_buffer = BUFFER(image->buf); 1126 if (NULL == obj_buffer) { 1127 return VA_STATUS_ERROR_INVALID_BUFFER; 1128 } 1129 1130 int found = 0; 1131 1132 if (obj_surface->subpictures != NULL) { 1133 surface_subpic = (PsbVASurfaceRec *)obj_surface->subpictures; 1134 do { 1135 if (surface_subpic->subpic_id == obj_subpic->subpic_id) { 1136 found = 1; 1137 break; 1138 } else 1139 surface_subpic = surface_subpic->next; 1140 } while (surface_subpic); 1141 } 1142 1143 if (found == 0) { /* new node */ 1144 if (obj_surface->subpic_count >= PSB_SUBPIC_MAX_NUM) { 1145 psb__error_message("can't support so many sub-pictures for the surface\n"); 1146 return VA_STATUS_ERROR_UNKNOWN; 1147 } 1148 1149 surface_subpic = (PsbVASurfaceRec *)calloc(1, sizeof(*surface_subpic)); 1150 if (NULL == surface_subpic) 1151 return VA_STATUS_ERROR_ALLOCATION_FAILED; 1152 } 1153 1154 surface_subpic->subpic_id = obj_subpic->subpic_id; 1155 surface_subpic->fourcc = image->format.fourcc; 1156 surface_subpic->size = image->data_size; 1157 surface_subpic->bo = obj_buffer->psb_buffer->drm_buf; 1158 surface_subpic->bufid = wsbmKBufHandle(wsbmKBuf(obj_buffer->psb_buffer->drm_buf)); 1159 surface_subpic->pl_flags = obj_buffer->psb_buffer->pl_flags; 1160 surface_subpic->subpic_flags = obj_subpic->flags; 1161 1162 surface_subpic->width = image->width; 1163 surface_subpic->height = image->height; 1164 switch (surface_subpic->fourcc) { 1165 case VA_FOURCC_AYUV: 1166 surface_subpic->stride = image->pitches[0] / 4; 1167 break; 1168 case VA_FOURCC_RGBA: 1169 surface_subpic->stride = image->pitches[0] / 4; 1170 break; 1171 case VA_FOURCC_AI44: 1172 surface_subpic->stride = image->pitches[0]; 1173 /* point to Image palette */ 1174 surface_subpic->palette_ptr = (PsbAYUVSample8 *) & obj_image->palette[0]; 1175 break; 1176 } 1177 1178 if (update) { 1179 surface_subpic->subpic_srcx = src_x; 1180 surface_subpic->subpic_srcy = src_y; 1181 surface_subpic->subpic_dstx = dest_x; 1182 surface_subpic->subpic_dsty = dest_y; 1183 surface_subpic->subpic_srcw = src_w; 1184 surface_subpic->subpic_srch = src_h; 1185 surface_subpic->subpic_dstw = dest_w; 1186 surface_subpic->subpic_dsth = dest_h; 1187 } 1188 1189 if (found == 0) { /* new node, link into the list */ 1190 if (NULL == obj_surface->subpictures) { 1191 obj_surface->subpictures = (void *)surface_subpic; 1192 } else { /* insert as the head */ 1193 surface_subpic->next = (PsbVASurfacePtr)obj_surface->subpictures; 1194 obj_surface->subpictures = (void *)surface_subpic; 1195 } 1196 obj_surface->subpic_count++; 1197 } 1198 1199 return VA_STATUS_SUCCESS; 1200} 1201 1202 1203static VAStatus psb__LinkSurfaceIntoSubpict( 1204 object_subpic_p obj_subpic, 1205 VASurfaceID surface_id 1206) 1207{ 1208 subpic_surface_s *subpic_surface; 1209 int found = 0; 1210 1211 if (obj_subpic->surfaces != NULL) { 1212 subpic_surface = (subpic_surface_s *)obj_subpic->surfaces; 1213 do { 1214 if (subpic_surface->surface_id == surface_id) { 1215 found = 1; 1216 return VA_STATUS_SUCCESS; /* reture directly */ 1217 } else 1218 subpic_surface = subpic_surface->next; 1219 } while (subpic_surface); 1220 } 1221 1222 /* not found */ 1223 subpic_surface = (subpic_surface_s *)calloc(1, sizeof(*subpic_surface)); 1224 if (NULL == subpic_surface) 1225 return VA_STATUS_ERROR_ALLOCATION_FAILED; 1226 1227 subpic_surface->surface_id = surface_id; 1228 subpic_surface->next = NULL; 1229 1230 if (NULL == obj_subpic->surfaces) { 1231 obj_subpic->surfaces = (void *)subpic_surface; 1232 } else { /* insert as the head */ 1233 subpic_surface->next = (subpic_surface_p)obj_subpic->surfaces; 1234 obj_subpic->surfaces = (void *)subpic_surface; 1235 } 1236 1237 return VA_STATUS_SUCCESS; 1238} 1239 1240static VAStatus psb__DelinkSubpictFromSurface( 1241 object_surface_p obj_surface, 1242 VASubpictureID subpic_id 1243) 1244{ 1245 PsbVASurfaceRec *surface_subpic, *pre_surface_subpic = NULL; 1246 int found = 0; 1247 1248 if (obj_surface->subpictures != NULL) { 1249 surface_subpic = (PsbVASurfaceRec *)obj_surface->subpictures; 1250 do { 1251 if (surface_subpic->subpic_id == subpic_id) { 1252 found = 1; 1253 break; 1254 } else { 1255 pre_surface_subpic = surface_subpic; 1256 surface_subpic = surface_subpic->next; 1257 } 1258 } while (surface_subpic); 1259 } 1260 1261 if (found == 1) { 1262 if (pre_surface_subpic == NULL) { /* remove the first node */ 1263 obj_surface->subpictures = (void *)surface_subpic->next; 1264 } else { 1265 pre_surface_subpic->next = surface_subpic->next; 1266 } 1267 free(surface_subpic); 1268 obj_surface->subpic_count--; 1269 } 1270 1271 return VA_STATUS_SUCCESS; 1272} 1273 1274 1275static VAStatus psb__DelinkSurfaceFromSubpict( 1276 object_subpic_p obj_subpic, 1277 VASurfaceID surface_id 1278) 1279{ 1280 subpic_surface_s *subpic_surface, *pre_subpic_surface = NULL; 1281 int found = 0; 1282 1283 if (obj_subpic->surfaces != NULL) { 1284 subpic_surface = (subpic_surface_s *)obj_subpic->surfaces; 1285 do { 1286 if (subpic_surface->surface_id == surface_id) { 1287 found = 1; 1288 break; 1289 } else { 1290 pre_subpic_surface = subpic_surface; 1291 subpic_surface = subpic_surface->next; 1292 } 1293 } while (subpic_surface); 1294 } 1295 1296 if (found == 1) { 1297 if (pre_subpic_surface == NULL) { /* remove the first node */ 1298 obj_subpic->surfaces = (void *)subpic_surface->next; 1299 } else { 1300 pre_subpic_surface->next = subpic_surface->next; 1301 } 1302 free(subpic_surface); 1303 } 1304 1305 return VA_STATUS_SUCCESS; 1306} 1307 1308 1309VAStatus psb_QuerySubpictureFormats( 1310 VADriverContextP ctx, 1311 VAImageFormat *format_list, /* out */ 1312 unsigned int *flags, /* out */ 1313 unsigned int *num_formats /* out */ 1314) 1315{ 1316 VAStatus vaStatus = VA_STATUS_SUCCESS; 1317 1318 if (NULL == format_list) { 1319 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1320 DEBUG_FAILURE; 1321 return vaStatus; 1322 } 1323 if (NULL == flags) { 1324 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1325 DEBUG_FAILURE; 1326 return vaStatus; 1327 } 1328 if (NULL == num_formats) { 1329 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1330 DEBUG_FAILURE; 1331 return vaStatus; 1332 } 1333 memcpy(format_list, psb__SubpicFormat, sizeof(psb__SubpicFormat)); 1334 *num_formats = PSB_MAX_SUBPIC_FORMATS; 1335 *flags = PSB_SUPPORTED_SUBPIC_FLAGS; 1336 1337 return VA_STATUS_SUCCESS; 1338} 1339 1340 1341VAStatus psb_CreateSubpicture( 1342 VADriverContextP ctx, 1343 VAImageID image, 1344 VASubpictureID *subpicture /* out */ 1345) 1346{ 1347 INIT_DRIVER_DATA; 1348 VASubpictureID subpicID; 1349 object_subpic_p obj_subpic; 1350 object_image_p obj_image; 1351 VAStatus vaStatus = VA_STATUS_SUCCESS; 1352 VAImageFormat *img_fmt; 1353 1354 obj_image = IMAGE(image); 1355 1356 if (NULL == subpicture) { 1357 vaStatus = VA_STATUS_ERROR_INVALID_SUBPICTURE; 1358 DEBUG_FAILURE; 1359 return vaStatus; 1360 } 1361 1362 if (NULL == obj_image) { 1363 vaStatus = VA_STATUS_ERROR_INVALID_IMAGE; 1364 return vaStatus; 1365 } 1366 1367 img_fmt = psb__VAImageCheckFourCC(&obj_image->image.format, psb__SubpicFormat, 1368 sizeof(psb__SubpicFormat) / sizeof(VAImageFormat)); 1369 if (img_fmt == NULL) 1370 return VA_STATUS_ERROR_UNKNOWN; 1371 1372 subpicID = object_heap_allocate(&driver_data->subpic_heap); 1373 obj_subpic = SUBPIC(subpicID); 1374 if (NULL == obj_subpic) { 1375 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1376 return vaStatus; 1377 } 1378 MEMSET_OBJECT(obj_subpic, struct object_subpic_s); 1379 1380 obj_subpic->subpic_id = subpicID; 1381 obj_subpic->image_id = obj_image->image.image_id; 1382 obj_subpic->surfaces = NULL; 1383 obj_subpic->global_alpha = 255; 1384 1385 obj_image->subpic_ref ++; 1386 1387 *subpicture = subpicID; 1388 1389 return VA_STATUS_SUCCESS; 1390} 1391 1392 1393 1394VAStatus psb__destroy_subpicture(psb_driver_data_p driver_data, object_subpic_p obj_subpic) 1395{ 1396 subpic_surface_s *subpic_surface = (subpic_surface_s *)obj_subpic->surfaces; 1397 VASubpictureID subpicture = obj_subpic->subpic_id; 1398 1399 if (subpic_surface) { 1400 do { 1401 subpic_surface_s *tmp = subpic_surface; 1402 object_surface_p obj_surface = SURFACE(subpic_surface->surface_id); 1403 1404 if (obj_surface) { /* remove subpict from surface */ 1405 psb__DelinkSubpictFromSurface(obj_surface, subpicture); 1406 } 1407 subpic_surface = subpic_surface->next; 1408 free(tmp); 1409 } while (subpic_surface); 1410 } 1411 1412 object_heap_free(&driver_data->subpic_heap, (object_base_p) obj_subpic); 1413 return VA_STATUS_SUCCESS; 1414} 1415 1416 1417VAStatus psb_DestroySubpicture( 1418 VADriverContextP ctx, 1419 VASubpictureID subpicture 1420) 1421{ 1422 INIT_DRIVER_DATA; 1423 object_subpic_p obj_subpic; 1424 VAStatus vaStatus = VA_STATUS_SUCCESS; 1425 1426 obj_subpic = SUBPIC(subpicture); 1427 if (NULL == obj_subpic) { 1428 vaStatus = VA_STATUS_ERROR_INVALID_SUBPICTURE; 1429 return vaStatus; 1430 } 1431 1432 1433 return psb__destroy_subpicture(driver_data, obj_subpic); 1434} 1435 1436VAStatus psb_SetSubpictureImage( 1437 VADriverContextP ctx, 1438 VASubpictureID subpicture, 1439 VAImageID image 1440) 1441{ 1442 INIT_DRIVER_DATA; 1443 object_subpic_p obj_subpic; 1444 object_image_p obj_image; 1445 VAStatus vaStatus = VA_STATUS_SUCCESS; 1446 subpic_surface_s *subpic_surface; 1447 VAImageFormat *img_fmt; 1448 1449 obj_image = IMAGE(image); 1450 if (NULL == obj_image) { 1451 vaStatus = VA_STATUS_ERROR_INVALID_IMAGE; 1452 return vaStatus; 1453 } 1454 1455 img_fmt = psb__VAImageCheckFourCC(&obj_image->image.format, 1456 psb__SubpicFormat, 1457 sizeof(psb__SubpicFormat) / sizeof(VAImageFormat)); 1458 if (img_fmt == NULL) 1459 return VA_STATUS_ERROR_INVALID_IMAGE; 1460 1461 obj_subpic = SUBPIC(subpicture); 1462 if (NULL == obj_subpic) { 1463 vaStatus = VA_STATUS_ERROR_INVALID_SUBPICTURE; 1464 return vaStatus; 1465 } 1466 1467 object_image_p old_obj_image = IMAGE(obj_subpic->image_id); 1468 if (old_obj_image) { 1469 old_obj_image->subpic_ref--;/* decrease reference count */ 1470 } 1471 1472 /* reset the image */ 1473 obj_subpic->image_id = obj_image->image.image_id; 1474 obj_image->subpic_ref ++; 1475 1476 /* relink again */ 1477 if (obj_subpic->surfaces != NULL) { 1478 /* the subpicture already linked into surfaces 1479 * so not check the return value of psb__LinkSubpictIntoSurface 1480 */ 1481 subpic_surface = (subpic_surface_s *)obj_subpic->surfaces; 1482 do { 1483 object_surface_p obj_surface = SURFACE(subpic_surface->surface_id); 1484 if (NULL == obj_surface) { 1485 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1486 return vaStatus; 1487 } 1488 1489 psb__LinkSubpictIntoSurface(driver_data, obj_surface, obj_subpic, 1490 0, 0, 0, 0, 0, 0, 0, 0, 1491 0 /* not update location */ 1492 ); 1493 subpic_surface = subpic_surface->next; 1494 } while (subpic_surface); 1495 } 1496 1497 1498 return VA_STATUS_SUCCESS; 1499} 1500 1501 1502VAStatus psb_SetSubpictureChromakey( 1503 VADriverContextP ctx, 1504 VASubpictureID subpicture, 1505 unsigned int chromakey_min, 1506 unsigned int chromakey_max, 1507 unsigned int chromakey_mask 1508) 1509{ 1510 INIT_DRIVER_DATA; 1511 (void)driver_data; 1512 /* TODO */ 1513 if ((chromakey_mask < chromakey_min) || (chromakey_mask > chromakey_max)) { 1514 psb__error_message("Invalid chromakey value %d, chromakey value should between min and max\n", chromakey_mask); 1515 return VA_STATUS_ERROR_INVALID_PARAMETER; 1516 } 1517 object_subpic_p obj_subpic = SUBPIC(subpicture); 1518 if (NULL == obj_subpic) { 1519 psb__error_message("Invalid subpicture value %d\n", subpicture); 1520 return VA_STATUS_ERROR_INVALID_SUBPICTURE; 1521 } 1522 1523 return VA_STATUS_SUCCESS; 1524} 1525 1526VAStatus psb_SetSubpictureGlobalAlpha( 1527 VADriverContextP ctx, 1528 VASubpictureID subpicture, 1529 float global_alpha 1530) 1531{ 1532 INIT_DRIVER_DATA; 1533 1534 if (global_alpha < 0 || global_alpha > 1) { 1535 psb__error_message("Invalid global alpha value %07f, global alpha value should between 0 and 1\n", global_alpha); 1536 return VA_STATUS_ERROR_INVALID_PARAMETER; 1537 } 1538 1539 object_subpic_p obj_subpic = SUBPIC(subpicture); 1540 if (NULL == obj_subpic) { 1541 psb__error_message("Invalid subpicture value %d\n", subpicture); 1542 return VA_STATUS_ERROR_INVALID_SUBPICTURE; 1543 } 1544 1545 obj_subpic->global_alpha = global_alpha * 255; 1546 1547 return VA_STATUS_SUCCESS; 1548} 1549 1550 1551VAStatus psb__AssociateSubpicture( 1552 VADriverContextP ctx, 1553 VASubpictureID subpicture, 1554 VASurfaceID *target_surfaces, 1555 int num_surfaces, 1556 short src_x, /* upper left offset in subpicture */ 1557 short src_y, 1558 unsigned short src_w, 1559 unsigned short src_h, 1560 short dest_x, /* upper left offset in surface */ 1561 short dest_y, 1562 unsigned short dest_w, 1563 unsigned short dest_h, 1564 /* 1565 * whether to enable chroma-keying or global-alpha 1566 * see VA_SUBPICTURE_XXX values 1567 */ 1568 unsigned int flags 1569) 1570{ 1571 INIT_DRIVER_DATA; 1572 1573 object_subpic_p obj_subpic; 1574 VAStatus vaStatus = VA_STATUS_SUCCESS; 1575 int i; 1576 1577 if (num_surfaces <= 0) { 1578 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1579 DEBUG_FAILURE; 1580 return vaStatus; 1581 } 1582 1583 obj_subpic = SUBPIC(subpicture); 1584 if (NULL == obj_subpic) { 1585 vaStatus = VA_STATUS_ERROR_INVALID_SUBPICTURE; 1586 DEBUG_FAILURE; 1587 return vaStatus; 1588 } 1589 1590 if (NULL == target_surfaces) { 1591 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1592 DEBUG_FAILURE; 1593 return vaStatus; 1594 } 1595 1596 if (flags & ~PSB_SUPPORTED_SUBPIC_FLAGS) { 1597#ifdef VA_STATUS_ERROR_FLAG_NOT_SUPPORTED 1598 vaStatus = VA_STATUS_ERROR_FLAG_NOT_SUPPORTED; 1599#else 1600 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1601#endif 1602 DEBUG_FAILURE; 1603 return vaStatus; 1604 } else { 1605 1606 /* If flags are ok, copy them to the subpicture object */ 1607 obj_subpic->flags = flags; 1608 1609 } 1610 1611 /* Validate input params */ 1612 for (i = 0; i < num_surfaces; i++) { 1613 object_surface_p obj_surface = SURFACE(target_surfaces[i]); 1614 if (NULL == obj_surface) { 1615 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1616 DEBUG_FAILURE; 1617 return vaStatus; 1618 } 1619 } 1620 1621 VASurfaceID *surfaces = target_surfaces; 1622 for (i = 0; i < num_surfaces; i++) { 1623 object_surface_p obj_surface = SURFACE(*surfaces); 1624 if (obj_surface) { 1625 vaStatus = psb__LinkSubpictIntoSurface(driver_data, obj_surface, obj_subpic, 1626 src_x, src_y, src_w, src_h, 1627 dest_x, dest_y, dest_w, dest_h, 1); 1628 if (VA_STATUS_SUCCESS == vaStatus) { 1629 vaStatus = psb__LinkSurfaceIntoSubpict(obj_subpic, *surfaces); 1630 } 1631 if (VA_STATUS_SUCCESS != vaStatus) { /* failed with malloc */ 1632 DEBUG_FAILURE; 1633 return vaStatus; 1634 } 1635 } else { 1636 /* Should never get here */ 1637 psb__error_message("Invalid surfaces,SurfaceID=0x%x\n", *surfaces); 1638 } 1639 1640 surfaces++; 1641 } 1642 1643 return VA_STATUS_SUCCESS; 1644} 1645 1646 1647VAStatus psb_AssociateSubpicture( 1648 VADriverContextP ctx, 1649 VASubpictureID subpicture, 1650 VASurfaceID *target_surfaces, 1651 int num_surfaces, 1652 short src_x, /* upper left offset in subpicture */ 1653 short src_y, 1654 unsigned short src_width, 1655 unsigned short src_height, 1656 short dest_x, /* upper left offset in surface */ 1657 short dest_y, 1658 unsigned short dest_width, 1659 unsigned short dest_height, 1660 /* 1661 * whether to enable chroma-keying or global-alpha 1662 * see VA_SUBPICTURE_XXX values 1663 */ 1664 unsigned int flags 1665) 1666{ 1667 return psb__AssociateSubpicture(ctx, subpicture, target_surfaces, num_surfaces, 1668 src_x, src_y, src_width, src_height, 1669 dest_x, dest_y, dest_width, dest_height, 1670 flags 1671 ); 1672} 1673 1674 1675VAStatus psb_DeassociateSubpicture( 1676 VADriverContextP ctx, 1677 VASubpictureID subpicture, 1678 VASurfaceID *target_surfaces, 1679 int num_surfaces 1680) 1681{ 1682 INIT_DRIVER_DATA; 1683 1684 object_subpic_p obj_subpic; 1685 VAStatus vaStatus = VA_STATUS_SUCCESS; 1686 object_image_p obj_image; 1687 int i; 1688 1689 if (num_surfaces <= 0) { 1690 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1691 DEBUG_FAILURE; 1692 return vaStatus; 1693 } 1694 1695 obj_subpic = SUBPIC(subpicture); 1696 if (NULL == obj_subpic) { 1697 vaStatus = VA_STATUS_ERROR_INVALID_SUBPICTURE; 1698 DEBUG_FAILURE; 1699 return vaStatus; 1700 } 1701 1702 if (NULL == target_surfaces) { 1703 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1704 DEBUG_FAILURE; 1705 return vaStatus; 1706 } 1707 1708 VASurfaceID *surfaces = target_surfaces; 1709 for (i = 0; i < num_surfaces; i++) { 1710 object_surface_p obj_surface = SURFACE(*surfaces); 1711 1712 if (obj_surface) { 1713 psb__DelinkSubpictFromSurface(obj_surface, subpicture); 1714 psb__DelinkSurfaceFromSubpict(obj_subpic, obj_surface->surface_id); 1715 } else { 1716 psb__error_message("vaDeassociateSubpicture: Invalid surface, VASurfaceID=0x%08x\n", *surfaces); 1717 } 1718 1719 surfaces++; 1720 } 1721 1722 obj_image = IMAGE(obj_subpic->image_id); 1723 if (obj_image) 1724 obj_image->subpic_ref--;/* decrease reference count */ 1725 1726 return VA_STATUS_SUCCESS; 1727} 1728 1729 1730void psb_SurfaceDeassociateSubpict( 1731 psb_driver_data_p driver_data, 1732 object_surface_p obj_surface 1733) 1734{ 1735 PsbVASurfaceRec *surface_subpic = (PsbVASurfaceRec *)obj_surface->subpictures; 1736 1737 if (surface_subpic != NULL) { 1738 do { 1739 PsbVASurfaceRec *tmp = surface_subpic; 1740 object_subpic_p obj_subpic = SUBPIC(surface_subpic->subpic_id); 1741 if (obj_subpic) 1742 psb__DelinkSurfaceFromSubpict(obj_subpic, obj_surface->surface_id); 1743 surface_subpic = surface_subpic->next; 1744 free(tmp); 1745 } while (surface_subpic); 1746 } 1747} 1748 1749 1750static VADisplayAttribute psb__DisplayAttribute[] = { 1751 { 1752 VADisplayAttribBrightness, 1753 BRIGHTNESS_MIN, 1754 BRIGHTNESS_MAX, 1755 BRIGHTNESS_DEFAULT_VALUE, 1756 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1757 }, 1758 1759 { 1760 VADisplayAttribContrast, 1761 CONTRAST_MIN, 1762 CONTRAST_MAX, 1763 CONTRAST_DEFAULT_VALUE, 1764 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1765 }, 1766 1767 { 1768 VADisplayAttribHue, 1769 HUE_MIN, 1770 HUE_MAX, 1771 HUE_DEFAULT_VALUE, 1772 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1773 }, 1774 1775 { 1776 VADisplayAttribSaturation, 1777 SATURATION_MIN, 1778 SATURATION_MAX, 1779 SATURATION_DEFAULT_VALUE, 1780 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1781 }, 1782 { 1783 VADisplayAttribBackgroundColor, 1784 0x00000000, 1785 0xffffffff, 1786 0x00000000, 1787 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1788 }, 1789 { 1790 VADisplayAttribRotation, 1791 VA_ROTATION_NONE, 1792 VA_ROTATION_270, 1793 VA_ROTATION_NONE, 1794 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1795 }, 1796 { 1797 VADisplayAttribOutofLoopDeblock, 1798 VA_OOL_DEBLOCKING_FALSE, 1799 VA_OOL_DEBLOCKING_TRUE, 1800 VA_OOL_DEBLOCKING_FALSE, 1801 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1802 }, 1803 { 1804 VADisplayAttribBLEBlackMode, 1805 0x00000000, 1806 0xffffffff, 1807 0x00000000, 1808 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1809 }, 1810 { 1811 VADisplayAttribBLEWhiteMode, 1812 0x00000000, 1813 0xffffffff, 1814 0x00000000, 1815 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1816 }, 1817 1818 { 1819 VADisplayAttribBlueStretch, 1820 0x00000000, 1821 0xffffffff, 1822 0x00000000, 1823 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1824 }, 1825 { 1826 VADisplayAttribSkinColorCorrection, 1827 0x00000000, 1828 0xffffffff, 1829 0x00000000, 1830 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1831 }, 1832 { 1833 VADisplayAttribBlendColor, 1834 0x00000000, 1835 0xffffffff, 1836 0x00000000, 1837 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1838 }, 1839 { 1840 VADisplayAttribOverlayColorKey, 1841 0x00000000, 1842 0xffffffff, 1843 0x00000000, 1844 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1845 }, 1846 { 1847 VADisplayAttribOverlayAutoPaintColorKey, 1848 0x00000000, 1849 0xffffffff, 1850 0x00000000, 1851 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1852 }, 1853 { 1854 VADisplayAttribCSCMatrix, 1855 0x00000000, 1856 0xffffffff, 1857 0x00000000, 1858 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1859 }, 1860 { 1861 VADisplayAttribRenderDevice, 1862 0x00000000, 1863 0xffffffff, 1864 0x00000000, 1865 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1866 }, 1867 { 1868 VADisplayAttribRenderMode, 1869 0x00000000, 1870 0xffffffff, 1871 0x00000000, 1872 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1873 }, 1874 { 1875 VADisplayAttribRenderRect, 1876 0x00000000, 1877 0xffffffff, 1878 0x00000000, 1879 VA_DISPLAY_ATTRIB_GETTABLE | VA_DISPLAY_ATTRIB_SETTABLE 1880 } 1881}; 1882 1883/* 1884 * Query display attributes 1885 * The caller must provide a "attr_list" array that can hold at 1886 * least vaMaxNumDisplayAttributes() entries. The actual number of attributes 1887 * returned in "attr_list" is returned in "num_attributes". 1888 */ 1889VAStatus psb_QueryDisplayAttributes( 1890 VADriverContextP ctx, 1891 VADisplayAttribute *attr_list, /* out */ 1892 int *num_attributes /* out */ 1893) 1894{ 1895 VAStatus vaStatus = VA_STATUS_SUCCESS; 1896 1897 if (NULL == attr_list) { 1898 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1899 DEBUG_FAILURE; 1900 return vaStatus; 1901 } 1902 if (NULL == num_attributes) { 1903 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1904 DEBUG_FAILURE; 1905 return vaStatus; 1906 } 1907 *num_attributes = min(*num_attributes, PSB_MAX_DISPLAY_ATTRIBUTES); 1908 memcpy(attr_list, psb__DisplayAttribute, (*num_attributes)*sizeof(VADisplayAttribute)); 1909 return VA_STATUS_SUCCESS; 1910} 1911 1912/* 1913 * Get display attributes 1914 * This function returns the current attribute values in "attr_list". 1915 * Only attributes returned with VA_DISPLAY_ATTRIB_GETTABLE set in the "flags" field 1916 * from vaQueryDisplayAttributes() can have their values retrieved. 1917 */ 1918VAStatus psb_GetDisplayAttributes( 1919 VADriverContextP ctx, 1920 VADisplayAttribute *attr_list, /* in/out */ 1921 int num_attributes 1922) 1923{ 1924 INIT_DRIVER_DATA; 1925 VADisplayAttribute *p = attr_list; 1926 int i; 1927 VAStatus vaStatus = VA_STATUS_SUCCESS; 1928 1929 if (NULL == attr_list) { 1930 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1931 DEBUG_FAILURE; 1932 return vaStatus; 1933 } 1934 1935 if (num_attributes <= 0) { 1936 return VA_STATUS_ERROR_INVALID_PARAMETER; 1937 } 1938 1939 for (i = 0; i < num_attributes; i++) { 1940 switch (p->type) { 1941 case VADisplayAttribBrightness: 1942 /* -50*(1<<10) ~ 50*(1<<10) ==> 0~100*/ 1943 p->value = (driver_data->brightness.value / (1 << 10)) + 50; 1944 p->min_value = 0; 1945 p->max_value = 100; 1946 break; 1947 case VADisplayAttribContrast: 1948 /* 0 ~ 2*(1<<25) ==> 0~100 */ 1949 p->value = (driver_data->contrast.value / (1 << 25)) * 50; 1950 p->min_value = 0; 1951 p->max_value = 100; 1952 break; 1953 case VADisplayAttribHue: 1954 /* -30*(1<<25) ~ 30*(1<<25) ==> 0~100*/ 1955 p->value = ((driver_data->hue.value / (1 << 25)) + 30) * 10 / 6; 1956 p->min_value = 0; 1957 p->max_value = 100; 1958 break; 1959 case VADisplayAttribSaturation: 1960 /* 0 ~ 2*(1<<25) ==> 0~100 */ 1961 p->value = (driver_data->saturation.value / (1 << 25)) * 50; 1962 p->min_value = 0; 1963 p->max_value = 100; 1964 break; 1965 case VADisplayAttribBackgroundColor: 1966 p->value = driver_data->clear_color; 1967 break; 1968 case VADisplayAttribBlendColor: 1969 p->value = driver_data->blend_color; 1970 break; 1971 case VADisplayAttribOverlayColorKey: 1972 p->value = driver_data->color_key; 1973 p->min_value = 0; 1974 p->max_value = 0xFFFFFF; 1975 break; 1976 case VADisplayAttribOverlayAutoPaintColorKey: 1977 p->value = driver_data->overlay_auto_paint_color_key; 1978 p->min_value = 0; 1979 p->max_value = 1; 1980 break; 1981 case VADisplayAttribRotation: 1982 p->value = driver_data->va_rotate = p->value; 1983 p->min_value = VA_ROTATION_NONE; 1984 p->max_value = VA_ROTATION_270; 1985 break; 1986 case VADisplayAttribOutofLoopDeblock: 1987 p->value = driver_data->is_oold = p->value; 1988 p->min_value = VA_OOL_DEBLOCKING_FALSE; 1989 p->max_value = VA_OOL_DEBLOCKING_TRUE; 1990 break; 1991 case VADisplayAttribCSCMatrix: 1992 p->value = driver_data->load_csc_matrix = p->value; 1993 p->min_value = 0; 1994 p->max_value = 255; 1995 break; 1996 case VADisplayAttribRenderDevice: 1997 p->value = driver_data->render_device = p->value; 1998 p->min_value = 0; 1999 p->max_value = 255; 2000 break; 2001 case VADisplayAttribRenderMode: 2002 p->value = driver_data->render_mode = p->value; 2003 p->min_value = 0; 2004 p->max_value = 255; 2005 break; 2006 case VADisplayAttribRenderRect: 2007 ((VARectangle *)(p->value))->x = driver_data->render_rect.x = ((VARectangle *)(p->value))->x; 2008 ((VARectangle *)(p->value))->y = driver_data->render_rect.y = ((VARectangle *)(p->value))->y; 2009 ((VARectangle *)(p->value))->width = driver_data->render_rect.width = ((VARectangle *)(p->value))->width; 2010 ((VARectangle *)(p->value))->height = driver_data->render_rect.height = ((VARectangle *)(p->value))->height; 2011 p->min_value = 0; 2012 p->max_value = 255; 2013 break; 2014 2015 default: 2016 break; 2017 } 2018 p++; 2019 } 2020 2021 return VA_STATUS_SUCCESS; 2022} 2023 2024/* 2025 * Set display attributes 2026 * Only attributes returned with VA_DISPLAY_ATTRIB_SETTABLE set in the "flags" field 2027 * from vaQueryDisplayAttributes() can be set. If the attribute is not settable or 2028 * the value is out of range, the function returns VA_STATUS_ERROR_ATTR_NOT_SUPPORTED 2029 */ 2030#define CLAMP_ATTR(a,max,min) (a>max?max:(a<min?min:a)) 2031VAStatus psb_SetDisplayAttributes( 2032 VADriverContextP ctx, 2033 VADisplayAttribute *attr_list, 2034 int num_attributes 2035) 2036{ 2037 INIT_DRIVER_DATA; 2038 VAStatus vaStatus = VA_STATUS_SUCCESS; 2039 struct psb_texture_s *texture_priv = &driver_data->ctexture_priv; 2040 PsbPortPrivPtr overlay_priv = (PsbPortPrivPtr)(&driver_data->coverlay_priv); 2041 int j, k; 2042 2043 if (NULL == attr_list) { 2044 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 2045 DEBUG_FAILURE; 2046 return vaStatus; 2047 } 2048 2049 VADisplayAttribute *p = attr_list; 2050 int i, update_coeffs = 0; 2051 unsigned int *p_tmp; 2052 2053 if (num_attributes <= 0) { 2054 return VA_STATUS_ERROR_INVALID_PARAMETER; 2055 } 2056 2057 for (i = 0; i < num_attributes; i++) { 2058 switch (p->type) { 2059 case VADisplayAttribBrightness: 2060 /* 0~100 ==> -50*(1<<10) ~ 50*(1<<10)*/ 2061 driver_data->brightness.value = (p->value - 50) * (1 << 10); 2062 /* 0~100 ==> -50~50 */ 2063 overlay_priv->brightness.Value = texture_priv->brightness.Value = p->value - 50; 2064 update_coeffs = 1; 2065 break; 2066 case VADisplayAttribContrast: 2067 /* 0~100 ==> 0 ~ 2*(1<<25) */ 2068 driver_data->contrast.value = (p->value / 50) * (1 << 25); 2069 /* 0~100 ==> -100~100 */ 2070 overlay_priv->contrast.Value = texture_priv->contrast.Value = p->value * 2 - 100; 2071 update_coeffs = 1; 2072 break; 2073 case VADisplayAttribHue: 2074 /* 0~100 ==> -30*(1<<25) ~ 30*(1<<25) */ 2075 driver_data->hue.value = ((p->value * 2 - 100) * 3 / 10) * (1 << 25); 2076 /* 0~100 ==> -30~30 */ 2077 overlay_priv->hue.Value = texture_priv->hue.Value = (p->value * 2 - 100) * 3 / 10; 2078 update_coeffs = 1; 2079 break; 2080 case VADisplayAttribSaturation: 2081 /* 0~100 ==> 0 ~ 2*(1<<25) */ 2082 driver_data->contrast.value = (p->value / 50) * (1 << 25); 2083 /* 0~100 ==> 100~200 */ 2084 overlay_priv->saturation.Value = texture_priv->saturation.Value = p->value + 100; 2085 update_coeffs = 1; 2086 break; 2087 case VADisplayAttribBLEBlackMode: 2088 driver_data->ble_black_mode.value = p->value; 2089 update_coeffs = 1; 2090 break; 2091 case VADisplayAttribBLEWhiteMode: 2092 driver_data->ble_white_mode.value = p->value; 2093 update_coeffs = 1; 2094 break; 2095 case VADisplayAttribBlueStretch: 2096 driver_data->blueStretch_gain.value = p->value; 2097 update_coeffs = 1; 2098 break; 2099 case VADisplayAttribSkinColorCorrection: 2100 driver_data->skinColorCorrection_gain.value = p->value; 2101 update_coeffs = 1; 2102 break; 2103 case VADisplayAttribBackgroundColor: 2104 driver_data->clear_color = p->value; 2105 break; 2106 case VADisplayAttribOutofLoopDeblock: 2107 driver_data->is_oold = p->value; 2108 break; 2109 case VADisplayAttribRotation: 2110 driver_data->va_rotate = p->value; 2111 driver_data->rotation_dirty |= PSB_NEW_VA_ROTATION; 2112 break; 2113 2114 case VADisplayAttribCSCMatrix: 2115 driver_data->load_csc_matrix = 1; 2116 p_tmp = (unsigned int *)p->value; 2117 for (j = 0; j < CSC_MATRIX_Y; j++) 2118 for (k = 0; k < CSC_MATRIX_X; k++) { 2119 if (p_tmp) 2120 driver_data->csc_matrix[j][k] = *p_tmp; 2121 p_tmp++; 2122 } 2123 break; 2124 2125 case VADisplayAttribBlendColor: 2126 driver_data->blend_color = p->value; 2127 break; 2128 case VADisplayAttribOverlayColorKey: 2129 overlay_priv->colorKey = driver_data->color_key = p->value; 2130 break; 2131 case VADisplayAttribOverlayAutoPaintColorKey: 2132 driver_data->overlay_auto_paint_color_key = p->value; 2133 break; 2134 2135 case VADisplayAttribRenderDevice: 2136 driver_data->render_device = p->value & VA_RENDER_DEVICE_MASK; 2137 case VADisplayAttribRenderMode: 2138 if (p->value & VA_RENDER_MODE_EXTERNAL_GPU) { 2139 psb__error_message("%s:Invalid parameter.VARenderModeExternalGPU is not supported.\n", __FUNCTION__); 2140 return VA_STATUS_ERROR_INVALID_PARAMETER; 2141 } 2142 if (((p->value & VA_RENDER_MODE_LOCAL_OVERLAY) && (p->value & VA_RENDER_MODE_LOCAL_GPU)) || 2143 ((p->value & VA_RENDER_MODE_EXTERNAL_OVERLAY) && (p->value & VA_RENDER_MODE_EXTERNAL_GPU))) { 2144 psb__error_message("%s:Invalid parameter. Conflict setting for VADisplayAttribRenderMode.\n", __FUNCTION__); 2145 return VA_STATUS_ERROR_INVALID_PARAMETER; 2146 } 2147 driver_data->render_mode = p->value & VA_RENDER_MODE_MASK; 2148 break; 2149 case VADisplayAttribRenderRect: 2150 driver_data->render_rect.x = ((VARectangle *)(p->value))->x; 2151 driver_data->render_rect.y = ((VARectangle *)(p->value))->y; 2152 driver_data->render_rect.width = ((VARectangle *)(p->value))->width; 2153 driver_data->render_rect.height = ((VARectangle *)(p->value))->height; 2154 break; 2155 2156 default: 2157 break; 2158 } 2159 p++; 2160 } 2161 2162 if (update_coeffs) { 2163 /* TODO */ 2164#ifndef ANDROID 2165 texture_priv->update_coeffs = 1; 2166#endif 2167 } 2168 2169 return VA_STATUS_SUCCESS; 2170} 2171 2172