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