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