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