intel_xvmc.c revision fa225cbc
1/* 2 * Copyright © 2007 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Zhenyu Wang <zhenyu.z.wang@intel.com> 25 * 26 */ 27#include "intel_xvmc.h" 28#include "dri2.h" 29 30/* global */ 31struct _intel_xvmc_driver *xvmc_driver = NULL; 32 33/* Lookup tables to speed common calculations for coded_block_pattern */ 34/* each block is ((8*8) * sizeof(short)) */ 35unsigned int mb_bytes_420[] = { 36 0, /* 0 */ 37 128, /* 1 */ 38 128, /* 10 */ 39 256, /* 11 */ 40 128, /* 100 */ 41 256, /* 101 */ 42 256, /* 110 */ 43 384, /* 111 */ 44 128, /* 1000 */ 45 256, /* 1001 */ 46 256, /* 1010 */ 47 384, /* 1011 */ 48 256, /* 1100 */ 49 384, /* 1101 */ 50 384, /* 1110 */ 51 512, /* 1111 */ 52 128, /* 10000 */ 53 256, /* 10001 */ 54 256, /* 10010 */ 55 384, /* 10011 */ 56 256, /* 10100 */ 57 384, /* 10101 */ 58 384, /* 10110 */ 59 512, /* 10111 */ 60 256, /* 11000 */ 61 384, /* 11001 */ 62 384, /* 11010 */ 63 512, /* 11011 */ 64 384, /* 11100 */ 65 512, /* 11101 */ 66 512, /* 11110 */ 67 640, /* 11111 */ 68 128, /* 100000 */ 69 256, /* 100001 */ 70 256, /* 100010 */ 71 384, /* 100011 */ 72 256, /* 100100 */ 73 384, /* 100101 */ 74 384, /* 100110 */ 75 512, /* 100111 */ 76 256, /* 101000 */ 77 384, /* 101001 */ 78 384, /* 101010 */ 79 512, /* 101011 */ 80 384, /* 101100 */ 81 512, /* 101101 */ 82 512, /* 101110 */ 83 640, /* 101111 */ 84 256, /* 110000 */ 85 384, /* 110001 */ 86 384, /* 110010 */ 87 512, /* 110011 */ 88 384, /* 110100 */ 89 512, /* 110101 */ 90 512, /* 110110 */ 91 640, /* 110111 */ 92 384, /* 111000 */ 93 512, /* 111001 */ 94 512, /* 111010 */ 95 640, /* 111011 */ 96 512, /* 111100 */ 97 640, /* 111101 */ 98 640, /* 111110 */ 99 768 /* 111111 */ 100}; 101 102int DEBUG; 103 104static void intel_xvmc_debug_init(void) 105{ 106 if (getenv("INTEL_XVMC_DEBUG")) 107 DEBUG = 1; 108} 109 110void LOCK_HARDWARE(drm_context_t ctx) 111{ 112 char __ret = 0; 113 114 PPTHREAD_MUTEX_LOCK(); 115 assert(!xvmc_driver->locked); 116 117 xvmc_driver->locked = 1; 118} 119 120void UNLOCK_HARDWARE(drm_context_t ctx) 121{ 122 xvmc_driver->locked = 0; 123 124 PPTHREAD_MUTEX_UNLOCK(); 125} 126 127static intel_xvmc_context_ptr intel_xvmc_new_context(Display *dpy) 128{ 129 intel_xvmc_context_ptr ret; 130 131 ret = (intel_xvmc_context_ptr)calloc(1, sizeof(intel_xvmc_context_t)); 132 if (!ret) 133 return NULL; 134 135 if (!xvmc_driver->ctx_list) 136 ret->next = NULL; 137 else 138 ret->next = xvmc_driver->ctx_list; 139 xvmc_driver->ctx_list = ret; 140 xvmc_driver->num_ctx++; 141 142 return ret; 143 144} 145 146static void intel_xvmc_free_context(XID id) 147{ 148 intel_xvmc_context_ptr p = xvmc_driver->ctx_list; 149 intel_xvmc_context_ptr pre = p; 150 151 while(p) { 152 if (p->context && p->context->context_id == id) { 153 if (p == xvmc_driver->ctx_list) 154 xvmc_driver->ctx_list = p->next; 155 else 156 pre->next = p->next; 157 break; 158 } 159 pre = p; 160 p = p->next; 161 } 162 163 if (p) { 164 free(p); 165 xvmc_driver->num_ctx--; 166 } 167} 168 169intel_xvmc_context_ptr intel_xvmc_find_context(XID id) 170{ 171 intel_xvmc_context_ptr p = xvmc_driver->ctx_list; 172 173 while(p) { 174 if (p->context && p->context->context_id == id) 175 return p; 176 p = p->next; 177 } 178 return NULL; 179} 180 181static intel_xvmc_surface_ptr intel_xvmc_new_surface(Display *dpy) 182{ 183 intel_xvmc_surface_ptr ret; 184 185 ret = (intel_xvmc_surface_ptr)calloc(1, sizeof(intel_xvmc_surface_t)); 186 if (!ret) 187 return NULL; 188 189 if (!xvmc_driver->surf_list) 190 ret->next = NULL; 191 else 192 ret->next = xvmc_driver->surf_list; 193 xvmc_driver->surf_list = ret; 194 xvmc_driver->num_surf++; 195 196 ret->image = NULL; 197 ret->gc_init = FALSE; 198 199 return ret; 200 201} 202 203static void intel_xvmc_free_surface(XID id) 204{ 205 intel_xvmc_surface_ptr p = xvmc_driver->surf_list; 206 intel_xvmc_surface_ptr pre = p; 207 208 while(p) { 209 if (p->surface && p->surface->surface_id == id) { 210 if (p == xvmc_driver->surf_list) 211 xvmc_driver->surf_list = p->next; 212 else 213 pre->next = p->next; 214 break; 215 } 216 pre = p; 217 p = p->next; 218 } 219 220 if (p) { 221 free(p); 222 xvmc_driver->num_surf--; 223 } 224} 225 226intel_xvmc_surface_ptr intel_xvmc_find_surface(XID id) 227{ 228 intel_xvmc_surface_ptr p = xvmc_driver->surf_list; 229 230 while(p) { 231 if (p->surface && p->surface->surface_id == id) 232 return p; 233 p = p->next; 234 } 235 return NULL; 236} 237/* 238* Function: XvMCCreateContext 239* Description: Create a XvMC context for the given surface parameters. 240* Arguments: 241* display - Connection to the X server. 242* port - XvPortID to use as avertised by the X connection. 243* surface_type_id - Unique identifier for the Surface type. 244* width - Width of the surfaces. 245* height - Height of the surfaces. 246* flags - one or more of the following 247* XVMC_DIRECT - A direct rendered context is requested. 248* 249* Notes: surface_type_id and width/height parameters must match those 250* returned by XvMCListSurfaceTypes. 251* Returns: Status 252*/ 253_X_EXPORT Status XvMCCreateContext(Display *display, XvPortID port, 254 int surface_type_id, int width, int height, 255 int flags, XvMCContext *context) 256{ 257 Status ret; 258 CARD32 *priv_data = NULL; 259 struct _intel_xvmc_common *comm; 260 drm_magic_t magic; 261 int major, minor; 262 int error_base; 263 int event_base; 264 int priv_count; 265 int isCapable; 266 int screen = DefaultScreen(display); 267 intel_xvmc_context_ptr intel_ctx; 268 int fd; 269 char *driverName = NULL, *deviceName = NULL; 270 271 /* Verify Obvious things first */ 272 if (!display || !context) 273 return BadValue; 274 275 if (!(flags & XVMC_DIRECT)) { 276 XVMC_ERR("Indirect Rendering not supported! Using Direct."); 277 return BadValue; 278 } 279 280 intel_xvmc_debug_init(); 281 282 /* 283 Width, Height, and flags are checked against surface_type_id 284 and port for validity inside the X server, no need to check 285 here. 286 */ 287 context->surface_type_id = surface_type_id; 288 context->width = (unsigned short)((width + 15) & ~15); 289 context->height = (unsigned short)((height + 15) & ~15); 290 context->flags = flags; 291 context->port = port; 292 293 if (!XvMCQueryExtension(display, &event_base, &error_base)) { 294 XVMC_ERR("XvMCExtension is not available!"); 295 return BadValue; 296 } 297 ret = XvMCQueryVersion(display, &major, &minor); 298 if (ret) { 299 XVMC_ERR("XvMCQueryVersion Failed, unable to determine protocol version."); 300 return ret; 301 } 302 303 /* XXX: major and minor could be checked in future for XvMC 304 * protocol capability (i.e H.264/AVC decode available) 305 */ 306 307 /* 308 Pass control to the X server to create a drm_context_t for us and 309 validate the with/height and flags. 310 */ 311 if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) { 312 XVMC_ERR("Unable to create XvMC Context."); 313 return ret; 314 } 315 XVMC_DBG("new context %d created\n", (int)context->context_id); 316 317 comm = (struct _intel_xvmc_common *)priv_data; 318 319 if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { 320 switch (comm->type) { 321 case XVMC_I915_MPEG2_MC: 322 xvmc_driver = &i915_xvmc_mc_driver; 323 break; 324 case XVMC_I965_MPEG2_MC: 325 xvmc_driver = &i965_xvmc_mc_driver; 326 break; 327 case XVMC_I965_MPEG2_VLD: 328 xvmc_driver = &xvmc_vld_driver; 329 break; 330 case XVMC_I945_MPEG2_VLD: 331 default: 332 XVMC_ERR("unimplemented xvmc type %d", comm->type); 333 XFree(priv_data); 334 priv_data = NULL; 335 return BadValue; 336 } 337 } 338 339 if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { 340 XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type); 341 return BadValue; 342 } 343 344 XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type)); 345 346 xvmc_driver->kernel_exec_fencing = comm->kernel_exec_fencing; 347 348 /* assign local ctx info */ 349 intel_ctx = intel_xvmc_new_context(display); 350 if (!intel_ctx) { 351 XVMC_ERR("Intel XvMC context create fail\n"); 352 return BadAlloc; 353 } 354 intel_ctx->context = context; 355 356 /* check DRI2 */ 357 ret = Success; 358 xvmc_driver->fd = -1; 359 360 do { 361 if (!DRI2QueryExtension(display, &event_base, &error_base)) { 362 ret = BadValue; 363 break; 364 } 365 366 if (!DRI2QueryVersion(display, &major, &minor)) { 367 ret = BadValue; 368 break; 369 } 370 371 if (!DRI2Connect(display, RootWindow(display, screen), 372 &driverName, &deviceName)) { 373 ret = BadValue; 374 break; 375 } 376 377 xvmc_driver->fd = open(deviceName, O_RDWR); 378 379 if (xvmc_driver->fd < 0) { 380 XVMC_ERR("Failed to open drm device: %s\n", strerror(errno)); 381 ret = BadValue; 382 break; 383 } 384 385 if (drmGetMagic(xvmc_driver->fd, &magic)) { 386 XVMC_ERR("Failed to get magic\n"); 387 ret = BadValue; 388 break; 389 } 390 391 if (!DRI2Authenticate(display, RootWindow(display, screen), magic)) { 392 XVMC_ERR("Failed to authenticate magic %d\n", magic); 393 ret = BadValue; 394 break; 395 } 396 } while (0); 397 398 XFree(driverName); 399 XFree(deviceName); 400 401 if (ret != Success) { 402 XFree(priv_data); 403 context->privData = NULL; 404 405 if (xvmc_driver->fd >= 0) 406 close(xvmc_driver->fd); 407 408 xvmc_driver = NULL; 409 return ret; 410 } 411 412 if ((xvmc_driver->bufmgr = 413 intel_bufmgr_gem_init(xvmc_driver->fd, 1024*64)) == NULL) { 414 XVMC_ERR("Can't init bufmgr\n"); 415 return BadAlloc; 416 } 417 drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr); 418 419 /* call driver hook. 420 * driver hook should free priv_data after return if success.*/ 421 ret = (xvmc_driver->create_context)(display, context, priv_count, priv_data); 422 if (ret) { 423 XVMC_ERR("driver create context failed\n"); 424 XFree(priv_data); 425 context->privData = NULL; 426 xvmc_driver = NULL; 427 return ret; 428 } 429 430 pthread_mutex_init(&xvmc_driver->ctxmutex, NULL); 431 intelInitBatchBuffer(); 432 intel_xvmc_dump_open(); 433 434 return Success; 435} 436 437/* 438 * Function: XvMCDestroyContext 439 * Description: Destorys the specified context. 440 * 441 * Arguments: 442 * display - Specifies the connection to the server. 443 * context - The context to be destroyed. 444 * 445 */ 446_X_EXPORT Status XvMCDestroyContext(Display *display, XvMCContext *context) 447{ 448 Status ret; 449 int screen; 450 451 if (!display || !context) 452 return XvMCBadContext; 453 screen = DefaultScreen(display); 454 ret = (xvmc_driver->destroy_context)(display, context); 455 if (ret) { 456 XVMC_ERR("destroy context fail\n"); 457 return ret; 458 } 459 460 intelFiniBatchBuffer(); 461 462 dri_bufmgr_destroy(xvmc_driver->bufmgr); 463 464 intel_xvmc_free_context(context->context_id); 465 466 ret = _xvmc_destroy_context(display, context); 467 if (ret != Success) { 468 XVMC_ERR("_xvmc_destroy_context fail\n"); 469 return ret; 470 } 471 472 if (xvmc_driver->num_ctx == 0) { 473 pthread_mutex_destroy(&xvmc_driver->ctxmutex); 474 475 if (xvmc_driver->fd >= 0) 476 close(xvmc_driver->fd); 477 478 xvmc_driver->fd = -1; 479 intel_xvmc_dump_close(); 480 } 481 return Success; 482} 483 484/* 485 * Function: XvMCCreateSurface 486 */ 487_X_EXPORT Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) 488{ 489 Status ret; 490 int priv_count; 491 CARD32 *priv_data; 492 intel_xvmc_surface_ptr intel_surf = NULL; 493 494 if (!display || !context) 495 return XvMCBadContext; 496 497 if (!surface) 498 return XvMCBadSurface; 499 500 intel_surf = intel_xvmc_new_surface(display); 501 if (!intel_surf) 502 return BadAlloc; 503 intel_surf->surface = surface; 504 505 if ((ret = _xvmc_create_surface(display, context, surface, 506 &priv_count, &priv_data))) { 507 XVMC_ERR("Unable to create XvMCSurface."); 508 return ret; 509 } 510 511 intel_surf->image = XvCreateImage(display, context->port, 512 FOURCC_XVMC, (char *)&intel_surf->data, surface->width, 513 surface->height); 514 if (!intel_surf->image) { 515 XVMC_ERR("Can't create XvImage for surface\n"); 516 _xvmc_destroy_surface(display, surface); 517 intel_xvmc_free_surface(surface->surface_id); 518 return BadAlloc; 519 } 520 intel_surf->image->data = (char *)&intel_surf->data; 521 522 ret = (xvmc_driver->create_surface)(display, context, surface, priv_count, 523 priv_data); 524 if (ret) { 525 XVMC_ERR("create surface failed\n"); 526 return ret; 527 } 528 529 return Success; 530} 531 532 533/* 534 * Function: XvMCDestroySurface 535 */ 536_X_EXPORT Status XvMCDestroySurface(Display *display, XvMCSurface *surface) 537{ 538 intel_xvmc_surface_ptr intel_surf; 539 540 if (!display || !surface) 541 return XvMCBadSurface; 542 543 intel_surf = intel_xvmc_find_surface(surface->surface_id); 544 if (!intel_surf) 545 return XvMCBadSurface; 546 547 XFree(intel_surf->image); 548 if (intel_surf->gc_init) 549 XFreeGC(display, intel_surf->gc); 550 intel_xvmc_free_surface(surface->surface_id); 551 552 (xvmc_driver->destroy_surface)(display, surface); 553 554 _xvmc_destroy_surface(display, surface); 555 556 return Success; 557} 558 559/* 560 * Function: XvMCCreateBlocks 561 */ 562_X_EXPORT Status XvMCCreateBlocks(Display *display, XvMCContext *context, 563 unsigned int num_blocks, 564 XvMCBlockArray *block) 565{ 566 Status ret; 567 if (!display || !context || !num_blocks || !block) 568 return BadValue; 569 570 memset(block, 0, sizeof(XvMCBlockArray)); 571 572 if (!(block->blocks = (short *)malloc((num_blocks << 6) * sizeof(short)))) 573 return BadAlloc; 574 575 block->num_blocks = num_blocks; 576 block->context_id = context->context_id; 577 block->privData = NULL; 578 579 return Success; 580} 581 582/* 583 * Function: XvMCDestroyBlocks 584 */ 585_X_EXPORT Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *block) 586{ 587 Status ret; 588 if (!display || !block) 589 return BadValue; 590 591 if (block->blocks) 592 free(block->blocks); 593 594 block->context_id = 0; 595 block->num_blocks = 0; 596 block->blocks = NULL; 597 block->privData = NULL; 598 599 return Success; 600} 601 602/* 603 * Function: XvMCCreateMacroBlocks 604 */ 605_X_EXPORT Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, 606 unsigned int num_blocks, 607 XvMCMacroBlockArray *blocks) 608{ 609 if (!display || !context || !blocks || !num_blocks) 610 return BadValue; 611 612 memset(blocks, 0, sizeof(XvMCMacroBlockArray)); 613 blocks->macro_blocks = (XvMCMacroBlock *)malloc(num_blocks * sizeof(XvMCMacroBlock)); 614 615 if (!blocks->macro_blocks) 616 return BadAlloc; 617 618 blocks->num_blocks = num_blocks; 619 blocks->context_id = context->context_id; 620 blocks->privData = NULL; 621 622 return Success; 623} 624 625/* 626 * Function: XvMCDestroyMacroBlocks 627 */ 628_X_EXPORT Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *block) 629{ 630 if (!display || !block) 631 return BadValue; 632 if (block->macro_blocks) 633 free(block->macro_blocks); 634 635 block->context_id = 0; 636 block->num_blocks = 0; 637 block->macro_blocks = NULL; 638 block->privData = NULL; 639 640 return Success; 641} 642 643/* 644 * Function: XvMCRenderSurface 645 * 646 * Description: This function does the actual HWMC. Given a list of 647 * macroblock structures it dispatched the hardware commands to execute 648 * them. 649 */ 650_X_EXPORT Status XvMCRenderSurface(Display *display, XvMCContext *context, 651 unsigned int picture_structure, 652 XvMCSurface *target_surface, 653 XvMCSurface *past_surface, 654 XvMCSurface *future_surface, 655 unsigned int flags, 656 unsigned int num_macroblocks, 657 unsigned int first_macroblock, 658 XvMCMacroBlockArray *macroblock_array, 659 XvMCBlockArray *blocks) 660{ 661 Status ret; 662 663 if (!display || !context) { 664 XVMC_ERR("Invalid Display, Context or Target!"); 665 return XvMCBadContext; 666 } 667 if (!target_surface) 668 return XvMCBadSurface; 669 670 intel_xvmc_dump_render(context, picture_structure, target_surface, 671 past_surface, future_surface, flags, num_macroblocks, 672 first_macroblock, macroblock_array, blocks); 673 674 ret = (xvmc_driver->render_surface)(display, context, picture_structure, 675 target_surface, past_surface, future_surface, flags, 676 num_macroblocks, first_macroblock, macroblock_array, 677 blocks); 678 679 if (ret) { 680 XVMC_ERR("render surface fail\n"); 681 return ret; 682 } 683 return Success; 684} 685 686/* 687 * Function: XvMCPutSurface 688 * 689 * Description: 690 * Arguments: 691 * display: Connection to X server 692 * surface: Surface to be displayed 693 * draw: X Drawable on which to display the surface 694 * srcx: X coordinate of the top left corner of the region to be 695 * displayed within the surface. 696 * srcy: Y coordinate of the top left corner of the region to be 697 * displayed within the surface. 698 * srcw: Width of the region to be displayed. 699 * srch: Height of the region to be displayed. 700 * destx: X cordinate of the top left corner of the destination region 701 * in the drawable coordinates. 702 * desty: Y cordinate of the top left corner of the destination region 703 * in the drawable coordinates. 704 * destw: Width of the destination region. 705 * desth: Height of the destination region. 706 * flags: One or more of the following. 707 * XVMC_TOP_FIELD - Display only the Top field of the surface. 708 * XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface. 709 * XVMC_FRAME_PICTURE - Display both fields or frame. 710 */ 711_X_EXPORT Status XvMCPutSurface(Display *display,XvMCSurface *surface, 712 Drawable draw, short srcx, short srcy, 713 unsigned short srcw, unsigned short srch, 714 short destx, short desty, 715 unsigned short destw, unsigned short desth, 716 int flags) 717{ 718 Status ret = Success; 719 XvMCContext *context; 720 intel_xvmc_context_ptr intel_ctx; 721 intel_xvmc_surface_ptr intel_surf; 722 723 if (!display || !surface) 724 return XvMCBadSurface; 725 726 intel_ctx = intel_xvmc_find_context(surface->context_id); 727 intel_surf = intel_xvmc_find_surface(surface->surface_id); 728 if (!intel_ctx || !intel_surf) 729 return XvMCBadSurface; 730 context = intel_ctx->context; 731 732 if (intel_surf->gc_init == FALSE) { 733 intel_surf->gc = XCreateGC(display, draw, 0, NULL); 734 intel_surf->gc_init = TRUE; 735 } else if (draw != intel_surf->last_draw) { 736 XFreeGC(display, intel_surf->gc); 737 intel_surf->gc = XCreateGC(display, draw, 0, NULL); 738 } 739 intel_surf->last_draw = draw; 740 /* fill intel_surf->data */ 741 ret = (xvmc_driver->put_surface)(display, surface, draw, srcx, srcy, 742 srcw, srch, destx, desty, destw, desth, flags, &intel_surf->data); 743 if (ret) { 744 XVMC_ERR("put surface fail\n"); 745 return ret; 746 } 747 ret = XvPutImage(display, context->port, draw, intel_surf->gc, 748 intel_surf->image, srcx, srcy, srcw, srch, destx, desty, 749 destw, desth); 750 return ret; 751} 752 753/* 754 * Function: XvMCSyncSurface 755 * Arguments: 756 * display - Connection to the X server 757 * surface - The surface to synchronize 758 */ 759_X_EXPORT Status XvMCSyncSurface(Display *display, XvMCSurface *surface) 760{ 761 Status ret; 762 int stat = 0; 763 764 if (!display || !surface) 765 return XvMCBadSurface; 766 767 do { 768 ret = XvMCGetSurfaceStatus(display, surface, &stat); 769 } while (!ret && (stat & XVMC_RENDERING)); 770 771 return ret; 772} 773 774/* 775 * Function: XvMCFlushSurface 776 * Description: 777 * This function commits pending rendering requests to ensure that they 778 * wll be completed in a finite amount of time. 779 * Arguments: 780 * display - Connection to X server 781 * surface - Surface to flush 782 * Returns: Status 783 */ 784_X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface *surface) 785{ 786 if (!display || !surface) 787 return XvMCBadSurface; 788 return Success; 789} 790 791/* 792 * Function: XvMCGetSurfaceStatus 793 * Description: 794 * Arguments: 795 * display: connection to X server 796 * surface: The surface to query 797 * stat: One of the Following 798 * XVMC_RENDERING - The last XvMCRenderSurface command has not 799 * completed. 800 * XVMC_DISPLAYING - The surface is currently being displayed or a 801 * display is pending. 802 */ 803_X_EXPORT Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *stat) 804{ 805 Status ret; 806 807 if (!display || !surface || !stat) 808 return XvMCBadSurface; 809 810 ret = (xvmc_driver->get_surface_status)(display, surface, stat); 811 if (ret) { 812 XVMC_ERR("get surface status fail\n"); 813 return ret; 814 } 815 816 return Success; 817} 818 819/* 820 * Function: XvMCHideSurface 821 * Description: Stops the display of a surface. 822 * Arguments: 823 * display - Connection to the X server. 824 * surface - surface to be hidden. 825 * 826 * Returns: Status 827 */ 828_X_EXPORT Status XvMCHideSurface(Display *display, XvMCSurface *surface) 829{ 830 int stat = 0; 831 Status ret; 832 833 if (!display || !surface) 834 return XvMCBadSurface; 835 836 XvMCSyncSurface(display, surface); 837 838 /* 839 Get the status of the surface, if it is not currently displayed 840 we don't need to worry about it. 841 */ 842 if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success) 843 return ret; 844 845 if (!(stat & XVMC_DISPLAYING)) 846 return Success; 847 848 /* FIXME: */ 849 XVMC_ERR("XvMCHideSurface not implemented!\n"); 850 return BadValue; 851} 852 853/* 854 * Function: XvMCCreateSubpicture 855 * Description: This creates a subpicture by filling out the XvMCSubpicture 856 * structure passed to it and returning Success. 857 * Arguments: 858 * display - Connection to the X server. 859 * context - The context to create the subpicture for. 860 * subpicture - Pre-allocated XvMCSubpicture structure to be filled in. 861 * width - of subpicture 862 * height - of subpicture 863 * xvimage_id - The id describing the XvImage format. 864 * 865 * Returns: Status 866 */ 867_X_EXPORT Status XvMCCreateSubpicture(Display *display, XvMCContext *context, 868 XvMCSubpicture *subpicture, 869 unsigned short width, unsigned short height, 870 int xvimage_id) 871{ 872 XVMC_ERR("XvMCCreateSubpicture not implemented!\n"); 873 return BadValue; 874} 875 876/* 877 * Function: XvMCClearSubpicture 878 * Description: Clear the area of the given subpicture to "color". 879 * structure passed to it and returning Success. 880 * Arguments: 881 * display - Connection to the X server. 882 * subpicture - Subpicture to clear. 883 * x, y, width, height - rectangle in the subpicture to clear. 884 * color - The data to file the rectangle with. 885 * 886 * Returns: Status 887 */ 888_X_EXPORT Status XvMCClearSubpicture(Display *display, XvMCSubpicture *subpicture, 889 short x, short y, 890 unsigned short width, unsigned short height, 891 unsigned int color) 892{ 893 XVMC_ERR("XvMCClearSubpicture not implemented!"); 894 return BadValue; 895} 896 897/* 898 * Function: XvMCCompositeSubpicture 899 * Description: Composite the XvImae on the subpicture. This composit uses 900 * non-premultiplied alpha. Destination alpha is utilized 901 * except for with indexed subpictures. Indexed subpictures 902 * use a simple "replace". 903 * Arguments: 904 * display - Connection to the X server. 905 * subpicture - Subpicture to clear. 906 * image - the XvImage to be used as the source of the composite. 907 * srcx, srcy, width, height - The rectangle from the image to be used. 908 * dstx, dsty - location in the subpicture to composite the source. 909 * 910 * Returns: Status 911 */ 912_X_EXPORT Status XvMCCompositeSubpicture(Display *display, XvMCSubpicture *subpicture, 913 XvImage *image, 914 short srcx, short srcy, 915 unsigned short width, unsigned short height, 916 short dstx, short dsty) 917{ 918 XVMC_ERR("XvMCCompositeSubpicture not implemented!"); 919 return BadValue; 920} 921 922 923/* 924 * Function: XvMCDestroySubpicture 925 * Description: Destroys the specified subpicture. 926 * Arguments: 927 * display - Connection to the X server. 928 * subpicture - Subpicture to be destroyed. 929 * 930 * Returns: Status 931 */ 932_X_EXPORT Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture) 933{ 934 XVMC_ERR("XvMCDestroySubpicture not implemented!"); 935 return BadValue; 936} 937 938 939/* 940 * Function: XvMCSetSubpicturePalette 941 * Description: Set the subpictures palette 942 * Arguments: 943 * display - Connection to the X server. 944 * subpicture - Subpiture to set palette for. 945 * palette - A pointer to an array holding the palette data. The array 946 * is num_palette_entries * entry_bytes in size. 947 * Returns: Status 948 */ 949_X_EXPORT Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture, 950 unsigned char *palette) 951{ 952 XVMC_ERR("XvMCSetSubpicturePalette not implemented!"); 953 return BadValue; 954} 955 956/* 957 * Function: XvMCBlendSubpicture 958 * Description: 959 * The behavior of this function is different depending on whether 960 * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. 961 * i915 only support frontend behavior. 962 * 963 * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): 964 * 965 * XvMCBlendSubpicture is a no-op in this case. 966 * 967 * Arguments: 968 * display - Connection to the X server. 969 * subpicture - The subpicture to be blended into the video. 970 * target_surface - The surface to be displayed with the blended subpic. 971 * source_surface - Source surface prior to blending. 972 * subx, suby, subw, subh - The rectangle from the subpicture to use. 973 * surfx, surfy, surfw, surfh - The rectangle in the surface to blend 974 * blend the subpicture rectangle into. Scaling can ocure if 975 * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. 976 * 977 * Returns: Status 978 */ 979_X_EXPORT Status XvMCBlendSubpicture(Display *display, XvMCSurface *target_surface, 980 XvMCSubpicture *subpicture, 981 short subx, short suby, 982 unsigned short subw, unsigned short subh, 983 short surfx, short surfy, 984 unsigned short surfw, unsigned short surfh) 985{ 986 XVMC_ERR("XvMCBlendSubpicture not implemented!"); 987 return BadValue; 988} 989 990/* 991 * Function: XvMCBlendSubpicture2 992 * Description: 993 * The behavior of this function is different depending on whether 994 * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. 995 * i915 only supports frontend blending. 996 * 997 * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): 998 * 999 * XvMCBlendSubpicture2 blends the source_surface and subpicture and 1000 * puts it in the target_surface. This does not effect the status of 1001 * the source surface but will cause the target_surface to query 1002 * XVMC_RENDERING until the blend is completed. 1003 * 1004 * Arguments: 1005 * display - Connection to the X server. 1006 * subpicture - The subpicture to be blended into the video. 1007 * target_surface - The surface to be displayed with the blended subpic. 1008 * source_surface - Source surface prior to blending. 1009 * subx, suby, subw, subh - The rectangle from the subpicture to use. 1010 * surfx, surfy, surfw, surfh - The rectangle in the surface to blend 1011 * blend the subpicture rectangle into. Scaling can ocure if 1012 * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. 1013 * 1014 * Returns: Status 1015 */ 1016_X_EXPORT Status XvMCBlendSubpicture2(Display *display, 1017 XvMCSurface *source_surface, 1018 XvMCSurface *target_surface, 1019 XvMCSubpicture *subpicture, 1020 short subx, short suby, 1021 unsigned short subw, unsigned short subh, 1022 short surfx, short surfy, 1023 unsigned short surfw, unsigned short surfh) 1024{ 1025 XVMC_ERR("XvMCBlendSubpicture2 not implemented!"); 1026 return BadValue; 1027} 1028 1029/* 1030 * Function: XvMCSyncSubpicture 1031 * Description: This function blocks until all composite/clear requests on 1032 * the subpicture have been complete. 1033 * Arguments: 1034 * display - Connection to the X server. 1035 * subpicture - The subpicture to synchronize 1036 * 1037 * Returns: Status 1038 */ 1039_X_EXPORT Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture) 1040{ 1041 XVMC_ERR("XvMCSyncSubpicture not implemented!"); 1042 return BadValue; 1043} 1044 1045/* 1046 * Function: XvMCFlushSubpicture 1047 * Description: This function commits pending composite/clear requests to 1048 * ensure that they will be completed in a finite amount of 1049 * time. 1050 * Arguments: 1051 * display - Connection to the X server. 1052 * subpicture - The subpicture whos compsiting should be flushed 1053 * 1054 * Returns: Status 1055 */ 1056_X_EXPORT Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture) 1057{ 1058 XVMC_ERR("XvMCFlushSubpicture not implemented!"); 1059 return BadValue; 1060} 1061 1062/* 1063 * Function: XvMCGetSubpictureStatus 1064 * Description: This function gets the current status of a subpicture 1065 * 1066 * Arguments: 1067 * display - Connection to the X server. 1068 * subpicture - The subpicture whos status is being queried 1069 * stat - The status of the subpicture. It can be any of the following 1070 * OR'd together: 1071 * XVMC_RENDERING - Last composite or clear request not completed 1072 * XVMC_DISPLAYING - Suppicture currently being displayed. 1073 * 1074 * Returns: Status 1075 */ 1076_X_EXPORT Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture, 1077 int *stat) 1078{ 1079 XVMC_ERR("XvMCGetSubpictureStatus not implemented!"); 1080 return BadValue; 1081} 1082 1083/* 1084 * Function: XvMCQueryAttributes 1085 * Description: An array of XvAttributes of size "number" is returned by 1086 * this function. If there are no attributes, NULL is returned and number 1087 * is set to 0. The array may be freed with xfree(). 1088 * 1089 * Arguments: 1090 * display - Connection to the X server. 1091 * context - The context whos attributes we are querying. 1092 * number - The returned number of recognized atoms 1093 * 1094 * Returns: 1095 * An array of XvAttributes. 1096 */ 1097_X_EXPORT XvAttribute *XvMCQueryAttributes(Display *display, XvMCContext *context, 1098 int *number) 1099{ 1100 /* now XvMC has no extra attribs than Xv */ 1101 *number = 0; 1102 return NULL; 1103} 1104 1105/* 1106 * Function: XvMCSetAttribute 1107 * Description: This function sets a context-specific attribute. 1108 * 1109 * Arguments: 1110 * display - Connection to the X server. 1111 * context - The context whos attributes we are querying. 1112 * attribute - The X atom of the attribute to be changed. 1113 * value - The new value for the attribute. 1114 * 1115 * Returns: 1116 * Status 1117 */ 1118_X_EXPORT Status XvMCSetAttribute(Display *display, XvMCContext *context, 1119 Atom attribute, int value) 1120{ 1121 return Success; 1122} 1123 1124/* 1125 * Function: XvMCGetAttribute 1126 * Description: This function queries a context-specific attribute and 1127 * returns the value. 1128 * 1129 * Arguments: 1130 * display - Connection to the X server. 1131 * context - The context whos attributes we are querying. 1132 * attribute - The X atom of the attribute to be queried 1133 * value - The returned attribute value 1134 * 1135 * Returns: 1136 * Status 1137 */ 1138_X_EXPORT Status XvMCGetAttribute(Display *display, XvMCContext *context, 1139 Atom attribute, int *value) 1140{ 1141 return Success; 1142} 1143 1144_X_EXPORT Status XvMCBeginSurface(Display *display, XvMCContext *context, 1145 XvMCSurface *target, 1146 XvMCSurface *past, 1147 XvMCSurface *future, 1148 const XvMCMpegControl *control) 1149{ 1150 if (xvmc_driver->begin_surface(display, context, 1151 target, past, future, control)) { 1152 XVMC_ERR("BeginSurface fail\n"); 1153 return BadValue; 1154 } 1155 return Success; 1156} 1157 1158_X_EXPORT Status XvMCLoadQMatrix(Display *display, XvMCContext *context, 1159 const XvMCQMatrix *qmx) 1160{ 1161 if (xvmc_driver->load_qmatrix(display, context, qmx)) { 1162 XVMC_ERR("LoadQMatrix fail\n"); 1163 return BadValue; 1164 } 1165 return Success; 1166} 1167 1168_X_EXPORT Status XvMCPutSlice(Display *display, XvMCContext *context, 1169 char *slice, int nbytes) 1170{ 1171 if (xvmc_driver->put_slice(display, context, slice, nbytes)) { 1172 XVMC_ERR("PutSlice fail\n"); 1173 return BadValue; 1174 } 1175 return Success; 1176} 1177 1178_X_EXPORT Status XvMCPutSlice2(Display *display, XvMCContext *context, 1179 char *slice, int nbytes, int slice_code) 1180{ 1181 if (xvmc_driver->put_slice2(display, context, slice, nbytes, slice_code)) { 1182 XVMC_ERR("PutSlice2 fail\n"); 1183 return BadValue; 1184 } 1185 return Success; 1186} 1187