1428d7b3dSmrg/* 2428d7b3dSmrg * Copyright © 2007 Intel Corporation 3428d7b3dSmrg * 4428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5428d7b3dSmrg * copy of this software and associated documentation files (the "Software"), 6428d7b3dSmrg * to deal in the Software without restriction, including without limitation 7428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the 9428d7b3dSmrg * Software is furnished to do so, subject to the following conditions: 10428d7b3dSmrg * 11428d7b3dSmrg * The above copyright notice and this permission notice (including the next 12428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the 13428d7b3dSmrg * Software. 14428d7b3dSmrg * 15428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20428d7b3dSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21428d7b3dSmrg * SOFTWARE. 22428d7b3dSmrg * 23428d7b3dSmrg * Authors: 24428d7b3dSmrg * Zhenyu Wang <zhenyu.z.wang@intel.com> 25428d7b3dSmrg * 26428d7b3dSmrg */ 27428d7b3dSmrg#include "intel_xvmc_private.h" 28428d7b3dSmrg#include <xcb/xcb.h> 29428d7b3dSmrg#include <xcb/xcb_aux.h> 30428d7b3dSmrg#include <xcb/dri2.h> 31428d7b3dSmrg#include <X11/Xlib-xcb.h> 32428d7b3dSmrg#include <X11/extensions/dri2tokens.h> 33428d7b3dSmrg 34428d7b3dSmrg/* global */ 35428d7b3dSmrgstruct _intel_xvmc_driver *xvmc_driver = NULL; 36428d7b3dSmrg 37428d7b3dSmrg/* Lookup tables to speed common calculations for coded_block_pattern */ 38428d7b3dSmrg/* each block is ((8*8) * sizeof(short)) */ 39428d7b3dSmrgunsigned int mb_bytes_420[] = { 40428d7b3dSmrg 0, /* 0 */ 41428d7b3dSmrg 128, /* 1 */ 42428d7b3dSmrg 128, /* 10 */ 43428d7b3dSmrg 256, /* 11 */ 44428d7b3dSmrg 128, /* 100 */ 45428d7b3dSmrg 256, /* 101 */ 46428d7b3dSmrg 256, /* 110 */ 47428d7b3dSmrg 384, /* 111 */ 48428d7b3dSmrg 128, /* 1000 */ 49428d7b3dSmrg 256, /* 1001 */ 50428d7b3dSmrg 256, /* 1010 */ 51428d7b3dSmrg 384, /* 1011 */ 52428d7b3dSmrg 256, /* 1100 */ 53428d7b3dSmrg 384, /* 1101 */ 54428d7b3dSmrg 384, /* 1110 */ 55428d7b3dSmrg 512, /* 1111 */ 56428d7b3dSmrg 128, /* 10000 */ 57428d7b3dSmrg 256, /* 10001 */ 58428d7b3dSmrg 256, /* 10010 */ 59428d7b3dSmrg 384, /* 10011 */ 60428d7b3dSmrg 256, /* 10100 */ 61428d7b3dSmrg 384, /* 10101 */ 62428d7b3dSmrg 384, /* 10110 */ 63428d7b3dSmrg 512, /* 10111 */ 64428d7b3dSmrg 256, /* 11000 */ 65428d7b3dSmrg 384, /* 11001 */ 66428d7b3dSmrg 384, /* 11010 */ 67428d7b3dSmrg 512, /* 11011 */ 68428d7b3dSmrg 384, /* 11100 */ 69428d7b3dSmrg 512, /* 11101 */ 70428d7b3dSmrg 512, /* 11110 */ 71428d7b3dSmrg 640, /* 11111 */ 72428d7b3dSmrg 128, /* 100000 */ 73428d7b3dSmrg 256, /* 100001 */ 74428d7b3dSmrg 256, /* 100010 */ 75428d7b3dSmrg 384, /* 100011 */ 76428d7b3dSmrg 256, /* 100100 */ 77428d7b3dSmrg 384, /* 100101 */ 78428d7b3dSmrg 384, /* 100110 */ 79428d7b3dSmrg 512, /* 100111 */ 80428d7b3dSmrg 256, /* 101000 */ 81428d7b3dSmrg 384, /* 101001 */ 82428d7b3dSmrg 384, /* 101010 */ 83428d7b3dSmrg 512, /* 101011 */ 84428d7b3dSmrg 384, /* 101100 */ 85428d7b3dSmrg 512, /* 101101 */ 86428d7b3dSmrg 512, /* 101110 */ 87428d7b3dSmrg 640, /* 101111 */ 88428d7b3dSmrg 256, /* 110000 */ 89428d7b3dSmrg 384, /* 110001 */ 90428d7b3dSmrg 384, /* 110010 */ 91428d7b3dSmrg 512, /* 110011 */ 92428d7b3dSmrg 384, /* 110100 */ 93428d7b3dSmrg 512, /* 110101 */ 94428d7b3dSmrg 512, /* 110110 */ 95428d7b3dSmrg 640, /* 110111 */ 96428d7b3dSmrg 384, /* 111000 */ 97428d7b3dSmrg 512, /* 111001 */ 98428d7b3dSmrg 512, /* 111010 */ 99428d7b3dSmrg 640, /* 111011 */ 100428d7b3dSmrg 512, /* 111100 */ 101428d7b3dSmrg 640, /* 111101 */ 102428d7b3dSmrg 640, /* 111110 */ 103428d7b3dSmrg 768 /* 111111 */ 104428d7b3dSmrg}; 105428d7b3dSmrg 106428d7b3dSmrgstatic int 107428d7b3dSmrgdri2_connect(Display *display) 108428d7b3dSmrg{ 109428d7b3dSmrg xcb_dri2_query_version_cookie_t query_version_cookie; 110428d7b3dSmrg xcb_dri2_query_version_reply_t *query_version_reply; 111428d7b3dSmrg xcb_dri2_connect_cookie_t connect_cookie; 112428d7b3dSmrg xcb_dri2_connect_reply_t *connect_reply; 113428d7b3dSmrg xcb_dri2_authenticate_cookie_t auth_cookie; 114428d7b3dSmrg xcb_dri2_authenticate_reply_t *auth_reply; 115428d7b3dSmrg xcb_screen_t *root; 116428d7b3dSmrg xcb_connection_t *c = XGetXCBConnection(display); 117428d7b3dSmrg drm_magic_t magic; 118428d7b3dSmrg const xcb_query_extension_reply_t *dri2_reply; 119428d7b3dSmrg char *device_name; 120428d7b3dSmrg int len; 121428d7b3dSmrg 122428d7b3dSmrg root = xcb_aux_get_screen(c, DefaultScreen(display)); 123428d7b3dSmrg 124428d7b3dSmrg dri2_reply = xcb_get_extension_data(c, &xcb_dri2_id); 125428d7b3dSmrg 126428d7b3dSmrg if (!dri2_reply) { 127428d7b3dSmrg XVMC_ERR("DRI2 required"); 128428d7b3dSmrg return BadValue; 129428d7b3dSmrg } 130428d7b3dSmrg 131428d7b3dSmrg /* Query the extension and make our first use of it at the same time. */ 132428d7b3dSmrg query_version_cookie = xcb_dri2_query_version(c, 1, 0); 133428d7b3dSmrg connect_cookie = xcb_dri2_connect(c, root->root, DRI2DriverDRI); 134428d7b3dSmrg 135428d7b3dSmrg query_version_reply = 136428d7b3dSmrg xcb_dri2_query_version_reply(c, query_version_cookie, NULL); 137428d7b3dSmrg connect_reply = xcb_dri2_connect_reply(c, connect_cookie, NULL); 138428d7b3dSmrg 139428d7b3dSmrg if (!query_version_reply) { 140428d7b3dSmrg XVMC_ERR("DRI2 required"); 141428d7b3dSmrg return BadValue; 142428d7b3dSmrg } 143428d7b3dSmrg free(query_version_reply); 144428d7b3dSmrg 145428d7b3dSmrg len = xcb_dri2_connect_device_name_length(connect_reply); 146428d7b3dSmrg device_name = malloc(len + 1); 147428d7b3dSmrg if (!device_name) { 148428d7b3dSmrg XVMC_ERR("malloc failure"); 149428d7b3dSmrg return BadAlloc; 150428d7b3dSmrg } 151428d7b3dSmrg strncpy(device_name, xcb_dri2_connect_device_name(connect_reply), len); 152428d7b3dSmrg device_name[len] = 0; 153428d7b3dSmrg xvmc_driver->fd = open(device_name, O_RDWR); 154428d7b3dSmrg free(device_name); 155428d7b3dSmrg free(connect_reply); 156428d7b3dSmrg if (xvmc_driver->fd < 0) { 157428d7b3dSmrg XVMC_ERR("Failed to open drm device: %s\n", strerror(errno)); 158428d7b3dSmrg return BadValue; 159428d7b3dSmrg } 160428d7b3dSmrg 161428d7b3dSmrg if (drmGetMagic(xvmc_driver->fd, &magic)) { 162428d7b3dSmrg XVMC_ERR("Failed to get magic\n"); 163428d7b3dSmrg return BadValue; 164428d7b3dSmrg } 165428d7b3dSmrg 166428d7b3dSmrg auth_cookie = xcb_dri2_authenticate(c, root->root, magic); 167428d7b3dSmrg auth_reply = xcb_dri2_authenticate_reply(c, auth_cookie, NULL); 168428d7b3dSmrg if (!auth_reply) { 169428d7b3dSmrg XVMC_ERR("Failed to authenticate magic %d\n", magic); 170428d7b3dSmrg return BadValue; 171428d7b3dSmrg } 172428d7b3dSmrg free(auth_reply); 173428d7b3dSmrg 174428d7b3dSmrg return Success; 175428d7b3dSmrg} 176428d7b3dSmrg 177428d7b3dSmrg/* 178428d7b3dSmrg* Function: XvMCCreateContext 179428d7b3dSmrg* Description: Create a XvMC context for the given surface parameters. 180428d7b3dSmrg* Arguments: 181428d7b3dSmrg* display - Connection to the X server. 182428d7b3dSmrg* port - XvPortID to use as avertised by the X connection. 183428d7b3dSmrg* surface_type_id - Unique identifier for the Surface type. 184428d7b3dSmrg* width - Width of the surfaces. 185428d7b3dSmrg* height - Height of the surfaces. 186428d7b3dSmrg* flags - one or more of the following 187428d7b3dSmrg* XVMC_DIRECT - A direct rendered context is requested. 188428d7b3dSmrg* 189428d7b3dSmrg* Notes: surface_type_id and width/height parameters must match those 190428d7b3dSmrg* returned by XvMCListSurfaceTypes. 191428d7b3dSmrg* Returns: Status 192428d7b3dSmrg*/ 193428d7b3dSmrg_X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port, 194428d7b3dSmrg int surface_type_id, int width, int height, 195428d7b3dSmrg int flags, XvMCContext * context) 196428d7b3dSmrg{ 197428d7b3dSmrg Status ret; 198428d7b3dSmrg CARD32 *priv_data = NULL; 199428d7b3dSmrg struct intel_xvmc_hw_context *comm; 200428d7b3dSmrg int major, minor; 201428d7b3dSmrg int error_base; 202428d7b3dSmrg int event_base; 203428d7b3dSmrg int priv_count; 204428d7b3dSmrg 205428d7b3dSmrg /* Verify Obvious things first */ 206428d7b3dSmrg if (!display || !context) 207428d7b3dSmrg return BadValue; 208428d7b3dSmrg 209428d7b3dSmrg if (!(flags & XVMC_DIRECT)) { 210428d7b3dSmrg XVMC_ERR("Indirect Rendering not supported! Using Direct."); 211428d7b3dSmrg return BadValue; 212428d7b3dSmrg } 213428d7b3dSmrg 214428d7b3dSmrg /* 215428d7b3dSmrg Width, Height, and flags are checked against surface_type_id 216428d7b3dSmrg and port for validity inside the X server, no need to check 217428d7b3dSmrg here. 218428d7b3dSmrg */ 219428d7b3dSmrg context->surface_type_id = surface_type_id; 220428d7b3dSmrg context->width = (unsigned short)((width + 15) & ~15); 221428d7b3dSmrg context->height = (unsigned short)((height + 15) & ~15); 222428d7b3dSmrg context->flags = flags; 223428d7b3dSmrg context->port = port; 224428d7b3dSmrg 225428d7b3dSmrg if (!XvMCQueryExtension(display, &event_base, &error_base)) { 226428d7b3dSmrg XVMC_ERR("XvMCExtension is not available!"); 227428d7b3dSmrg return BadValue; 228428d7b3dSmrg } 229428d7b3dSmrg 230428d7b3dSmrg ret = XvMCQueryVersion(display, &major, &minor); 231428d7b3dSmrg if (ret) { 232428d7b3dSmrg XVMC_ERR 233428d7b3dSmrg ("XvMCQueryVersion Failed, unable to determine protocol version."); 234428d7b3dSmrg return ret; 235428d7b3dSmrg } 236428d7b3dSmrg 237428d7b3dSmrg /* XXX: major and minor could be checked in future for XvMC 238428d7b3dSmrg * protocol capability (i.e H.264/AVC decode available) 239428d7b3dSmrg */ 240428d7b3dSmrg 241428d7b3dSmrg /* 242428d7b3dSmrg Pass control to the X server to create a drm_context_t for us and 243428d7b3dSmrg validate the with/height and flags. 244428d7b3dSmrg */ 245428d7b3dSmrg if ((ret = 246428d7b3dSmrg _xvmc_create_context(display, context, &priv_count, &priv_data))) { 247428d7b3dSmrg XVMC_ERR("Unable to create XvMC Context."); 248428d7b3dSmrg return ret; 249428d7b3dSmrg } 250428d7b3dSmrg 251428d7b3dSmrg comm = (struct intel_xvmc_hw_context *)priv_data; 252428d7b3dSmrg 253428d7b3dSmrg if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { 254428d7b3dSmrg switch (comm->type) { 255428d7b3dSmrg case XVMC_I915_MPEG2_MC: 256428d7b3dSmrg xvmc_driver = &i915_xvmc_mc_driver; 257428d7b3dSmrg break; 258428d7b3dSmrg case XVMC_I965_MPEG2_MC: 259428d7b3dSmrg xvmc_driver = &i965_xvmc_mc_driver; 260428d7b3dSmrg break; 261428d7b3dSmrg case XVMC_I965_MPEG2_VLD: 262428d7b3dSmrg xvmc_driver = &xvmc_vld_driver; 263428d7b3dSmrg break; 264428d7b3dSmrg case XVMC_I945_MPEG2_VLD: 265428d7b3dSmrg default: 266428d7b3dSmrg XVMC_ERR("unimplemented xvmc type %d", comm->type); 267428d7b3dSmrg XFree(priv_data); 268428d7b3dSmrg priv_data = NULL; 269428d7b3dSmrg return BadValue; 270428d7b3dSmrg } 271428d7b3dSmrg } 272428d7b3dSmrg 273428d7b3dSmrg if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { 274428d7b3dSmrg XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type); 275428d7b3dSmrg return BadValue; 276428d7b3dSmrg } 277428d7b3dSmrg 278428d7b3dSmrg XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type)); 279428d7b3dSmrg 280428d7b3dSmrg /* check DRI2 */ 281428d7b3dSmrg ret = Success; 282428d7b3dSmrg xvmc_driver->fd = -1; 283428d7b3dSmrg 284428d7b3dSmrg ret = dri2_connect(display); 285428d7b3dSmrg if (ret != Success) { 286428d7b3dSmrg XFree(priv_data); 287428d7b3dSmrg context->privData = NULL; 288428d7b3dSmrg if (xvmc_driver->fd >= 0) 289428d7b3dSmrg close(xvmc_driver->fd); 290428d7b3dSmrg xvmc_driver = NULL; 291428d7b3dSmrg return ret; 292428d7b3dSmrg } 293428d7b3dSmrg 294428d7b3dSmrg if ((xvmc_driver->bufmgr = 295428d7b3dSmrg intel_bufmgr_gem_init(xvmc_driver->fd, 1024 * 64)) == NULL) { 296428d7b3dSmrg XVMC_ERR("Can't init bufmgr\n"); 297428d7b3dSmrg return BadAlloc; 298428d7b3dSmrg } 299428d7b3dSmrg drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr); 300428d7b3dSmrg 301428d7b3dSmrg if (!intelInitBatchBuffer()) { 302428d7b3dSmrg XFree(priv_data); 303428d7b3dSmrg context->privData = NULL; 304428d7b3dSmrg 305428d7b3dSmrg dri_bufmgr_destroy(xvmc_driver->bufmgr); 306428d7b3dSmrg xvmc_driver = NULL; 307428d7b3dSmrg 308428d7b3dSmrg return BadAlloc; 309428d7b3dSmrg } 310428d7b3dSmrg 311428d7b3dSmrg /* call driver hook. 312428d7b3dSmrg * driver hook should free priv_data after return if success.*/ 313428d7b3dSmrg ret = 314428d7b3dSmrg (xvmc_driver->create_context) (display, context, priv_count, 315428d7b3dSmrg priv_data); 316428d7b3dSmrg if (ret) { 317428d7b3dSmrg XVMC_ERR("driver create context failed\n"); 318428d7b3dSmrg intelFiniBatchBuffer(); 319428d7b3dSmrg 320428d7b3dSmrg XFree(priv_data); 321428d7b3dSmrg context->privData = NULL; 322428d7b3dSmrg 323428d7b3dSmrg dri_bufmgr_destroy(xvmc_driver->bufmgr); 324428d7b3dSmrg xvmc_driver = NULL; 325428d7b3dSmrg return ret; 326428d7b3dSmrg } 327428d7b3dSmrg 328428d7b3dSmrg sigfillset(&xvmc_driver->sa_mask); 329428d7b3dSmrg sigdelset(&xvmc_driver->sa_mask, SIGFPE); 330428d7b3dSmrg sigdelset(&xvmc_driver->sa_mask, SIGILL); 331428d7b3dSmrg sigdelset(&xvmc_driver->sa_mask, SIGSEGV); 332428d7b3dSmrg sigdelset(&xvmc_driver->sa_mask, SIGBUS); 333428d7b3dSmrg sigdelset(&xvmc_driver->sa_mask, SIGKILL); 334428d7b3dSmrg pthread_mutex_init(&xvmc_driver->ctxmutex, NULL); 335428d7b3dSmrg 336428d7b3dSmrg intel_xvmc_dump_open(); 337428d7b3dSmrg 338428d7b3dSmrg return Success; 339428d7b3dSmrg} 340428d7b3dSmrg 341428d7b3dSmrg/* 342428d7b3dSmrg * Function: XvMCDestroyContext 343428d7b3dSmrg * Description: Destorys the specified context. 344428d7b3dSmrg * 345428d7b3dSmrg * Arguments: 346428d7b3dSmrg * display - Specifies the connection to the server. 347428d7b3dSmrg * context - The context to be destroyed. 348428d7b3dSmrg * 349428d7b3dSmrg */ 350428d7b3dSmrg_X_EXPORT Status XvMCDestroyContext(Display * display, XvMCContext * context) 351428d7b3dSmrg{ 352428d7b3dSmrg Status ret; 353428d7b3dSmrg int screen; 354428d7b3dSmrg 355428d7b3dSmrg if (!display || !context) 356428d7b3dSmrg return XvMCBadContext; 357428d7b3dSmrg screen = DefaultScreen(display); 358428d7b3dSmrg ret = (xvmc_driver->destroy_context) (display, context); 359428d7b3dSmrg if (ret) { 360428d7b3dSmrg XVMC_ERR("destroy context fail\n"); 361428d7b3dSmrg return ret; 362428d7b3dSmrg } 363428d7b3dSmrg 364428d7b3dSmrg intelFiniBatchBuffer(); 365428d7b3dSmrg 366428d7b3dSmrg dri_bufmgr_destroy(xvmc_driver->bufmgr); 367428d7b3dSmrg 368428d7b3dSmrg ret = _xvmc_destroy_context(display, context); 369428d7b3dSmrg if (ret != Success) { 370428d7b3dSmrg XVMC_ERR("_xvmc_destroy_context fail\n"); 371428d7b3dSmrg return ret; 372428d7b3dSmrg } 373428d7b3dSmrg 374428d7b3dSmrg if (xvmc_driver->num_ctx == 0) { 375428d7b3dSmrg pthread_mutex_destroy(&xvmc_driver->ctxmutex); 376428d7b3dSmrg 377428d7b3dSmrg if (xvmc_driver->fd >= 0) 378428d7b3dSmrg close(xvmc_driver->fd); 379428d7b3dSmrg 380428d7b3dSmrg xvmc_driver->fd = -1; 381428d7b3dSmrg intel_xvmc_dump_close(); 382428d7b3dSmrg } 383428d7b3dSmrg return Success; 384428d7b3dSmrg} 385428d7b3dSmrg 386428d7b3dSmrg/* 387428d7b3dSmrg * Function: XvMCCreateSurface 388428d7b3dSmrg */ 389428d7b3dSmrg_X_EXPORT Status XvMCCreateSurface(Display * display, XvMCContext * context, 390428d7b3dSmrg XvMCSurface * surface) 391428d7b3dSmrg{ 392428d7b3dSmrg Status ret; 393428d7b3dSmrg int priv_count; 394428d7b3dSmrg CARD32 *priv_data; 395428d7b3dSmrg intel_xvmc_surface_ptr intel_surf = NULL; 396428d7b3dSmrg struct intel_xvmc_context *intel_ctx; 397428d7b3dSmrg 398428d7b3dSmrg if (!display || !context) 399428d7b3dSmrg return XvMCBadContext; 400428d7b3dSmrg 401428d7b3dSmrg if (!surface) 402428d7b3dSmrg return XvMCBadSurface; 403428d7b3dSmrg 404428d7b3dSmrg intel_ctx = context->privData; 405428d7b3dSmrg 406428d7b3dSmrg if ((ret = _xvmc_create_surface(display, context, surface, 407428d7b3dSmrg &priv_count, &priv_data))) { 408428d7b3dSmrg XVMC_ERR("Unable to create XvMCSurface."); 409428d7b3dSmrg return ret; 410428d7b3dSmrg } 411428d7b3dSmrg 412428d7b3dSmrg XFree(priv_data); 413428d7b3dSmrg 414428d7b3dSmrg surface->privData = calloc(1, sizeof(struct intel_xvmc_surface)); 415428d7b3dSmrg 416428d7b3dSmrg if (!(intel_surf = surface->privData)) 417428d7b3dSmrg goto out_xvmc; 418428d7b3dSmrg 419428d7b3dSmrg intel_surf->bo = drm_intel_bo_alloc(xvmc_driver->bufmgr, 420428d7b3dSmrg "surface", 421428d7b3dSmrg intel_ctx->surface_bo_size, 422428d7b3dSmrg GTT_PAGE_SIZE); 423428d7b3dSmrg if (!intel_surf->bo) 424428d7b3dSmrg goto out_surf; 425428d7b3dSmrg 426428d7b3dSmrg if (drm_intel_bo_flink(intel_surf->bo, &intel_surf->gem_handle)) 427428d7b3dSmrg goto out_bo; 428428d7b3dSmrg 429428d7b3dSmrg intel_surf = surface->privData; 430428d7b3dSmrg intel_surf->context = context; 431428d7b3dSmrg 432428d7b3dSmrg intel_surf->image = XvCreateImage(display, context->port, 433428d7b3dSmrg FOURCC_XVMC, 434428d7b3dSmrg (char *) &intel_surf->gem_handle, 435428d7b3dSmrg surface->width, surface->height); 436428d7b3dSmrg if (!intel_surf->image) { 437428d7b3dSmrg XVMC_ERR("Can't create XvImage for surface\n"); 438428d7b3dSmrg goto out_bo; 439428d7b3dSmrg } 440428d7b3dSmrg 441428d7b3dSmrg return Success; 442428d7b3dSmrg 443428d7b3dSmrgout_bo: 444428d7b3dSmrg drm_intel_bo_unreference(intel_surf->bo); 445428d7b3dSmrgout_surf: 446428d7b3dSmrg free(intel_surf); 447428d7b3dSmrgout_xvmc: 448428d7b3dSmrg _xvmc_destroy_surface(display, surface); 449428d7b3dSmrg return BadAlloc; 450428d7b3dSmrg} 451428d7b3dSmrg 452428d7b3dSmrg/* 453428d7b3dSmrg * Function: XvMCDestroySurface 454428d7b3dSmrg */ 455428d7b3dSmrg_X_EXPORT Status XvMCDestroySurface(Display * display, XvMCSurface * surface) 456428d7b3dSmrg{ 457428d7b3dSmrg intel_xvmc_surface_ptr intel_surf; 458428d7b3dSmrg 459428d7b3dSmrg if (!display || !surface) 460428d7b3dSmrg return XvMCBadSurface; 461428d7b3dSmrg 462428d7b3dSmrg intel_surf = surface->privData; 463428d7b3dSmrg if (!intel_surf) 464428d7b3dSmrg return XvMCBadSurface; 465428d7b3dSmrg 466428d7b3dSmrg XFree(intel_surf->image); 467428d7b3dSmrg if (intel_surf->gc_init) 468428d7b3dSmrg XFreeGC(display, intel_surf->gc); 469428d7b3dSmrg 470428d7b3dSmrg drm_intel_bo_unreference(intel_surf->bo); 471428d7b3dSmrg 472428d7b3dSmrg free(intel_surf); 473428d7b3dSmrg 474428d7b3dSmrg _xvmc_destroy_surface(display, surface); 475428d7b3dSmrg 476428d7b3dSmrg return Success; 477428d7b3dSmrg} 478428d7b3dSmrg 479428d7b3dSmrg/* 480428d7b3dSmrg * Function: XvMCCreateBlocks 481428d7b3dSmrg */ 482428d7b3dSmrg_X_EXPORT Status XvMCCreateBlocks(Display * display, XvMCContext * context, 483428d7b3dSmrg unsigned int num_blocks, 484428d7b3dSmrg XvMCBlockArray * block) 485428d7b3dSmrg{ 486428d7b3dSmrg if (!display || !context || !num_blocks || !block) 487428d7b3dSmrg return BadValue; 488428d7b3dSmrg 489428d7b3dSmrg memset(block, 0, sizeof(XvMCBlockArray)); 490428d7b3dSmrg 491428d7b3dSmrg if (! 492428d7b3dSmrg (block->blocks = 493428d7b3dSmrg (short *)malloc((num_blocks << 6) * sizeof(short)))) 494428d7b3dSmrg return BadAlloc; 495428d7b3dSmrg 496428d7b3dSmrg block->num_blocks = num_blocks; 497428d7b3dSmrg block->context_id = context->context_id; 498428d7b3dSmrg block->privData = NULL; 499428d7b3dSmrg 500428d7b3dSmrg return Success; 501428d7b3dSmrg} 502428d7b3dSmrg 503428d7b3dSmrg/* 504428d7b3dSmrg * Function: XvMCDestroyBlocks 505428d7b3dSmrg */ 506428d7b3dSmrg_X_EXPORT Status XvMCDestroyBlocks(Display * display, XvMCBlockArray * block) 507428d7b3dSmrg{ 508428d7b3dSmrg if (!display || !block) 509428d7b3dSmrg return BadValue; 510428d7b3dSmrg 511428d7b3dSmrg if (block->blocks) 512428d7b3dSmrg free(block->blocks); 513428d7b3dSmrg 514428d7b3dSmrg block->context_id = 0; 515428d7b3dSmrg block->num_blocks = 0; 516428d7b3dSmrg block->blocks = NULL; 517428d7b3dSmrg block->privData = NULL; 518428d7b3dSmrg 519428d7b3dSmrg return Success; 520428d7b3dSmrg} 521428d7b3dSmrg 522428d7b3dSmrg/* 523428d7b3dSmrg * Function: XvMCCreateMacroBlocks 524428d7b3dSmrg */ 525428d7b3dSmrg_X_EXPORT Status XvMCCreateMacroBlocks(Display * display, XvMCContext * context, 526428d7b3dSmrg unsigned int num_blocks, 527428d7b3dSmrg XvMCMacroBlockArray * blocks) 528428d7b3dSmrg{ 529428d7b3dSmrg if (!display || !context || !blocks || !num_blocks) 530428d7b3dSmrg return BadValue; 531428d7b3dSmrg 532428d7b3dSmrg memset(blocks, 0, sizeof(XvMCMacroBlockArray)); 533428d7b3dSmrg blocks->macro_blocks = 534428d7b3dSmrg (XvMCMacroBlock *) malloc(num_blocks * sizeof(XvMCMacroBlock)); 535428d7b3dSmrg 536428d7b3dSmrg if (!blocks->macro_blocks) 537428d7b3dSmrg return BadAlloc; 538428d7b3dSmrg 539428d7b3dSmrg blocks->num_blocks = num_blocks; 540428d7b3dSmrg blocks->context_id = context->context_id; 541428d7b3dSmrg blocks->privData = NULL; 542428d7b3dSmrg 543428d7b3dSmrg return Success; 544428d7b3dSmrg} 545428d7b3dSmrg 546428d7b3dSmrg/* 547428d7b3dSmrg * Function: XvMCDestroyMacroBlocks 548428d7b3dSmrg */ 549428d7b3dSmrg_X_EXPORT Status XvMCDestroyMacroBlocks(Display * display, 550428d7b3dSmrg XvMCMacroBlockArray * block) 551428d7b3dSmrg{ 552428d7b3dSmrg if (!display || !block) 553428d7b3dSmrg return BadValue; 554428d7b3dSmrg if (block->macro_blocks) 555428d7b3dSmrg free(block->macro_blocks); 556428d7b3dSmrg 557428d7b3dSmrg block->context_id = 0; 558428d7b3dSmrg block->num_blocks = 0; 559428d7b3dSmrg block->macro_blocks = NULL; 560428d7b3dSmrg block->privData = NULL; 561428d7b3dSmrg 562428d7b3dSmrg return Success; 563428d7b3dSmrg} 564428d7b3dSmrg 565428d7b3dSmrg/* 566428d7b3dSmrg * Function: XvMCRenderSurface 567428d7b3dSmrg * 568428d7b3dSmrg * Description: This function does the actual HWMC. Given a list of 569428d7b3dSmrg * macroblock structures it dispatched the hardware commands to execute 570428d7b3dSmrg * them. 571428d7b3dSmrg */ 572428d7b3dSmrg_X_EXPORT Status XvMCRenderSurface(Display * display, XvMCContext * context, 573428d7b3dSmrg unsigned int picture_structure, 574428d7b3dSmrg XvMCSurface * target_surface, 575428d7b3dSmrg XvMCSurface * past_surface, 576428d7b3dSmrg XvMCSurface * future_surface, 577428d7b3dSmrg unsigned int flags, 578428d7b3dSmrg unsigned int num_macroblocks, 579428d7b3dSmrg unsigned int first_macroblock, 580428d7b3dSmrg XvMCMacroBlockArray * macroblock_array, 581428d7b3dSmrg XvMCBlockArray * blocks) 582428d7b3dSmrg{ 583428d7b3dSmrg Status ret; 584428d7b3dSmrg 585428d7b3dSmrg if (!display || !context) { 586428d7b3dSmrg XVMC_ERR("Invalid Display, Context or Target!"); 587428d7b3dSmrg return XvMCBadContext; 588428d7b3dSmrg } 589428d7b3dSmrg if (!target_surface) 590428d7b3dSmrg return XvMCBadSurface; 591428d7b3dSmrg 592428d7b3dSmrg intel_xvmc_dump_render(context, picture_structure, target_surface, 593428d7b3dSmrg past_surface, future_surface, flags, 594428d7b3dSmrg num_macroblocks, first_macroblock, 595428d7b3dSmrg macroblock_array, blocks); 596428d7b3dSmrg 597428d7b3dSmrg ret = 598428d7b3dSmrg (xvmc_driver->render_surface) (display, context, picture_structure, 599428d7b3dSmrg target_surface, past_surface, 600428d7b3dSmrg future_surface, flags, 601428d7b3dSmrg num_macroblocks, first_macroblock, 602428d7b3dSmrg macroblock_array, blocks); 603428d7b3dSmrg 604428d7b3dSmrg if (ret) { 605428d7b3dSmrg XVMC_ERR("render surface fail\n"); 606428d7b3dSmrg return ret; 607428d7b3dSmrg } 608428d7b3dSmrg return Success; 609428d7b3dSmrg} 610428d7b3dSmrg 611428d7b3dSmrg/* 612428d7b3dSmrg * Function: XvMCPutSurface 613428d7b3dSmrg * 614428d7b3dSmrg * Description: 615428d7b3dSmrg * Arguments: 616428d7b3dSmrg * display: Connection to X server 617428d7b3dSmrg * surface: Surface to be displayed 618428d7b3dSmrg * draw: X Drawable on which to display the surface 619428d7b3dSmrg * srcx: X coordinate of the top left corner of the region to be 620428d7b3dSmrg * displayed within the surface. 621428d7b3dSmrg * srcy: Y coordinate of the top left corner of the region to be 622428d7b3dSmrg * displayed within the surface. 623428d7b3dSmrg * srcw: Width of the region to be displayed. 624428d7b3dSmrg * srch: Height of the region to be displayed. 625428d7b3dSmrg * destx: X cordinate of the top left corner of the destination region 626428d7b3dSmrg * in the drawable coordinates. 627428d7b3dSmrg * desty: Y cordinate of the top left corner of the destination region 628428d7b3dSmrg * in the drawable coordinates. 629428d7b3dSmrg * destw: Width of the destination region. 630428d7b3dSmrg * desth: Height of the destination region. 631428d7b3dSmrg * flags: One or more of the following. 632428d7b3dSmrg * XVMC_TOP_FIELD - Display only the Top field of the surface. 633428d7b3dSmrg * XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface. 634428d7b3dSmrg * XVMC_FRAME_PICTURE - Display both fields or frame. 635428d7b3dSmrg */ 636428d7b3dSmrg_X_EXPORT Status XvMCPutSurface(Display * display, XvMCSurface * surface, 637428d7b3dSmrg Drawable draw, short srcx, short srcy, 638428d7b3dSmrg unsigned short srcw, unsigned short srch, 639428d7b3dSmrg short destx, short desty, 640428d7b3dSmrg unsigned short destw, unsigned short desth, 641428d7b3dSmrg int flags) 642428d7b3dSmrg{ 643428d7b3dSmrg XvMCContext *context; 644428d7b3dSmrg intel_xvmc_surface_ptr intel_surf; 645428d7b3dSmrg 646428d7b3dSmrg if (!display || !surface) 647428d7b3dSmrg return XvMCBadSurface; 648428d7b3dSmrg 649428d7b3dSmrg intel_surf = surface->privData; 650428d7b3dSmrg if (!intel_surf) 651428d7b3dSmrg return XvMCBadSurface; 652428d7b3dSmrg 653428d7b3dSmrg context = intel_surf->context; 654428d7b3dSmrg if (!context) 655428d7b3dSmrg return XvMCBadSurface; 656428d7b3dSmrg 657428d7b3dSmrg if (intel_surf->gc_init == FALSE) { 658428d7b3dSmrg intel_surf->gc = XCreateGC(display, draw, 0, NULL); 659428d7b3dSmrg intel_surf->gc_init = TRUE; 660428d7b3dSmrg } else if (draw != intel_surf->last_draw) { 661428d7b3dSmrg XFreeGC(display, intel_surf->gc); 662428d7b3dSmrg intel_surf->gc = XCreateGC(display, draw, 0, NULL); 663428d7b3dSmrg } 664428d7b3dSmrg intel_surf->last_draw = draw; 665428d7b3dSmrg 666428d7b3dSmrg return XvPutImage(display, context->port, draw, intel_surf->gc, 667428d7b3dSmrg intel_surf->image, srcx, srcy, srcw, srch, destx, 668428d7b3dSmrg desty, destw, desth); 669428d7b3dSmrg} 670428d7b3dSmrg 671428d7b3dSmrg/* 672428d7b3dSmrg * Function: XvMCSyncSurface 673428d7b3dSmrg * Arguments: 674428d7b3dSmrg * display - Connection to the X server 675428d7b3dSmrg * surface - The surface to synchronize 676428d7b3dSmrg */ 677428d7b3dSmrg_X_EXPORT Status XvMCSyncSurface(Display * display, XvMCSurface * surface) 678428d7b3dSmrg{ 679428d7b3dSmrg if (!display || !surface) 680428d7b3dSmrg return XvMCBadSurface; 681428d7b3dSmrg 682428d7b3dSmrg return Success; 683428d7b3dSmrg} 684428d7b3dSmrg 685428d7b3dSmrg/* 686428d7b3dSmrg * Function: XvMCFlushSurface 687428d7b3dSmrg * Description: 688428d7b3dSmrg * This function commits pending rendering requests to ensure that they 689428d7b3dSmrg * wll be completed in a finite amount of time. 690428d7b3dSmrg * Arguments: 691428d7b3dSmrg * display - Connection to X server 692428d7b3dSmrg * surface - Surface to flush 693428d7b3dSmrg * Returns: Status 694428d7b3dSmrg */ 695428d7b3dSmrg_X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface * surface) 696428d7b3dSmrg{ 697428d7b3dSmrg if (!display || !surface) 698428d7b3dSmrg return XvMCBadSurface; 699428d7b3dSmrg 700428d7b3dSmrg return Success; 701428d7b3dSmrg} 702428d7b3dSmrg 703428d7b3dSmrg/* 704428d7b3dSmrg * Function: XvMCGetSurfaceStatus 705428d7b3dSmrg * Description: 706428d7b3dSmrg * Arguments: 707428d7b3dSmrg * display: connection to X server 708428d7b3dSmrg * surface: The surface to query 709428d7b3dSmrg * stat: One of the Following 710428d7b3dSmrg * XVMC_RENDERING - The last XvMCRenderSurface command has not 711428d7b3dSmrg * completed. 712428d7b3dSmrg * XVMC_DISPLAYING - The surface is currently being displayed or a 713428d7b3dSmrg * display is pending. 714428d7b3dSmrg */ 715428d7b3dSmrg_X_EXPORT Status XvMCGetSurfaceStatus(Display * display, XvMCSurface * surface, 716428d7b3dSmrg int *stat) 717428d7b3dSmrg{ 718428d7b3dSmrg if (!display || !surface || !stat) 719428d7b3dSmrg return XvMCBadSurface; 720428d7b3dSmrg 721428d7b3dSmrg *stat = 0; 722428d7b3dSmrg 723428d7b3dSmrg return Success; 724428d7b3dSmrg} 725428d7b3dSmrg 726428d7b3dSmrg/* 727428d7b3dSmrg * Function: XvMCHideSurface 728428d7b3dSmrg * Description: Stops the display of a surface. 729428d7b3dSmrg * Arguments: 730428d7b3dSmrg * display - Connection to the X server. 731428d7b3dSmrg * surface - surface to be hidden. 732428d7b3dSmrg * 733428d7b3dSmrg * Returns: Status 734428d7b3dSmrg */ 735428d7b3dSmrg_X_EXPORT Status XvMCHideSurface(Display * display, XvMCSurface * surface) 736428d7b3dSmrg{ 737428d7b3dSmrg if (!display || !surface) 738428d7b3dSmrg return XvMCBadSurface; 739428d7b3dSmrg 740428d7b3dSmrg return Success; 741428d7b3dSmrg} 742428d7b3dSmrg 743428d7b3dSmrg/* 744428d7b3dSmrg * Function: XvMCCreateSubpicture 745428d7b3dSmrg * Description: This creates a subpicture by filling out the XvMCSubpicture 746428d7b3dSmrg * structure passed to it and returning Success. 747428d7b3dSmrg * Arguments: 748428d7b3dSmrg * display - Connection to the X server. 749428d7b3dSmrg * context - The context to create the subpicture for. 750428d7b3dSmrg * subpicture - Pre-allocated XvMCSubpicture structure to be filled in. 751428d7b3dSmrg * width - of subpicture 752428d7b3dSmrg * height - of subpicture 753428d7b3dSmrg * xvimage_id - The id describing the XvImage format. 754428d7b3dSmrg * 755428d7b3dSmrg * Returns: Status 756428d7b3dSmrg */ 757428d7b3dSmrg_X_EXPORT Status XvMCCreateSubpicture(Display * display, XvMCContext * context, 758428d7b3dSmrg XvMCSubpicture * subpicture, 759428d7b3dSmrg unsigned short width, 760428d7b3dSmrg unsigned short height, int xvimage_id) 761428d7b3dSmrg{ 762428d7b3dSmrg XVMC_ERR("XvMCCreateSubpicture not implemented!\n"); 763428d7b3dSmrg return BadValue; 764428d7b3dSmrg} 765428d7b3dSmrg 766428d7b3dSmrg/* 767428d7b3dSmrg * Function: XvMCClearSubpicture 768428d7b3dSmrg * Description: Clear the area of the given subpicture to "color". 769428d7b3dSmrg * structure passed to it and returning Success. 770428d7b3dSmrg * Arguments: 771428d7b3dSmrg * display - Connection to the X server. 772428d7b3dSmrg * subpicture - Subpicture to clear. 773428d7b3dSmrg * x, y, width, height - rectangle in the subpicture to clear. 774428d7b3dSmrg * color - The data to file the rectangle with. 775428d7b3dSmrg * 776428d7b3dSmrg * Returns: Status 777428d7b3dSmrg */ 778428d7b3dSmrg_X_EXPORT Status XvMCClearSubpicture(Display * display, 779428d7b3dSmrg XvMCSubpicture * subpicture, short x, 780428d7b3dSmrg short y, unsigned short width, 781428d7b3dSmrg unsigned short height, unsigned int color) 782428d7b3dSmrg{ 783428d7b3dSmrg XVMC_ERR("XvMCClearSubpicture not implemented!"); 784428d7b3dSmrg return BadValue; 785428d7b3dSmrg} 786428d7b3dSmrg 787428d7b3dSmrg/* 788428d7b3dSmrg * Function: XvMCCompositeSubpicture 789428d7b3dSmrg * Description: Composite the XvImae on the subpicture. This composit uses 790428d7b3dSmrg * non-premultiplied alpha. Destination alpha is utilized 791428d7b3dSmrg * except for with indexed subpictures. Indexed subpictures 792428d7b3dSmrg * use a simple "replace". 793428d7b3dSmrg * Arguments: 794428d7b3dSmrg * display - Connection to the X server. 795428d7b3dSmrg * subpicture - Subpicture to clear. 796428d7b3dSmrg * image - the XvImage to be used as the source of the composite. 797428d7b3dSmrg * srcx, srcy, width, height - The rectangle from the image to be used. 798428d7b3dSmrg * dstx, dsty - location in the subpicture to composite the source. 799428d7b3dSmrg * 800428d7b3dSmrg * Returns: Status 801428d7b3dSmrg */ 802428d7b3dSmrg_X_EXPORT Status XvMCCompositeSubpicture(Display * display, 803428d7b3dSmrg XvMCSubpicture * subpicture, 804428d7b3dSmrg XvImage * image, short srcx, 805428d7b3dSmrg short srcy, unsigned short width, 806428d7b3dSmrg unsigned short height, short dstx, 807428d7b3dSmrg short dsty) 808428d7b3dSmrg{ 809428d7b3dSmrg XVMC_ERR("XvMCCompositeSubpicture not implemented!"); 810428d7b3dSmrg return BadValue; 811428d7b3dSmrg} 812428d7b3dSmrg 813428d7b3dSmrg/* 814428d7b3dSmrg * Function: XvMCDestroySubpicture 815428d7b3dSmrg * Description: Destroys the specified subpicture. 816428d7b3dSmrg * Arguments: 817428d7b3dSmrg * display - Connection to the X server. 818428d7b3dSmrg * subpicture - Subpicture to be destroyed. 819428d7b3dSmrg * 820428d7b3dSmrg * Returns: Status 821428d7b3dSmrg */ 822428d7b3dSmrg_X_EXPORT Status XvMCDestroySubpicture(Display * display, 823428d7b3dSmrg XvMCSubpicture * subpicture) 824428d7b3dSmrg{ 825428d7b3dSmrg XVMC_ERR("XvMCDestroySubpicture not implemented!"); 826428d7b3dSmrg return BadValue; 827428d7b3dSmrg} 828428d7b3dSmrg 829428d7b3dSmrg/* 830428d7b3dSmrg * Function: XvMCSetSubpicturePalette 831428d7b3dSmrg * Description: Set the subpictures palette 832428d7b3dSmrg * Arguments: 833428d7b3dSmrg * display - Connection to the X server. 834428d7b3dSmrg * subpicture - Subpiture to set palette for. 835428d7b3dSmrg * palette - A pointer to an array holding the palette data. The array 836428d7b3dSmrg * is num_palette_entries * entry_bytes in size. 837428d7b3dSmrg * Returns: Status 838428d7b3dSmrg */ 839428d7b3dSmrg_X_EXPORT Status XvMCSetSubpicturePalette(Display * display, 840428d7b3dSmrg XvMCSubpicture * subpicture, 841428d7b3dSmrg unsigned char *palette) 842428d7b3dSmrg{ 843428d7b3dSmrg XVMC_ERR("XvMCSetSubpicturePalette not implemented!"); 844428d7b3dSmrg return BadValue; 845428d7b3dSmrg} 846428d7b3dSmrg 847428d7b3dSmrg/* 848428d7b3dSmrg * Function: XvMCBlendSubpicture 849428d7b3dSmrg * Description: 850428d7b3dSmrg * The behavior of this function is different depending on whether 851428d7b3dSmrg * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. 852428d7b3dSmrg * i915 only support frontend behavior. 853428d7b3dSmrg * 854428d7b3dSmrg * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): 855428d7b3dSmrg * 856428d7b3dSmrg * XvMCBlendSubpicture is a no-op in this case. 857428d7b3dSmrg * 858428d7b3dSmrg * Arguments: 859428d7b3dSmrg * display - Connection to the X server. 860428d7b3dSmrg * subpicture - The subpicture to be blended into the video. 861428d7b3dSmrg * target_surface - The surface to be displayed with the blended subpic. 862428d7b3dSmrg * source_surface - Source surface prior to blending. 863428d7b3dSmrg * subx, suby, subw, subh - The rectangle from the subpicture to use. 864428d7b3dSmrg * surfx, surfy, surfw, surfh - The rectangle in the surface to blend 865428d7b3dSmrg * blend the subpicture rectangle into. Scaling can ocure if 866428d7b3dSmrg * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. 867428d7b3dSmrg * 868428d7b3dSmrg * Returns: Status 869428d7b3dSmrg */ 870428d7b3dSmrg_X_EXPORT Status XvMCBlendSubpicture(Display * display, 871428d7b3dSmrg XvMCSurface * target_surface, 872428d7b3dSmrg XvMCSubpicture * subpicture, short subx, 873428d7b3dSmrg short suby, unsigned short subw, 874428d7b3dSmrg unsigned short subh, short surfx, 875428d7b3dSmrg short surfy, unsigned short surfw, 876428d7b3dSmrg unsigned short surfh) 877428d7b3dSmrg{ 878428d7b3dSmrg XVMC_ERR("XvMCBlendSubpicture not implemented!"); 879428d7b3dSmrg return BadValue; 880428d7b3dSmrg} 881428d7b3dSmrg 882428d7b3dSmrg/* 883428d7b3dSmrg * Function: XvMCBlendSubpicture2 884428d7b3dSmrg * Description: 885428d7b3dSmrg * The behavior of this function is different depending on whether 886428d7b3dSmrg * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo. 887428d7b3dSmrg * i915 only supports frontend blending. 888428d7b3dSmrg * 889428d7b3dSmrg * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior): 890428d7b3dSmrg * 891428d7b3dSmrg * XvMCBlendSubpicture2 blends the source_surface and subpicture and 892428d7b3dSmrg * puts it in the target_surface. This does not effect the status of 893428d7b3dSmrg * the source surface but will cause the target_surface to query 894428d7b3dSmrg * XVMC_RENDERING until the blend is completed. 895428d7b3dSmrg * 896428d7b3dSmrg * Arguments: 897428d7b3dSmrg * display - Connection to the X server. 898428d7b3dSmrg * subpicture - The subpicture to be blended into the video. 899428d7b3dSmrg * target_surface - The surface to be displayed with the blended subpic. 900428d7b3dSmrg * source_surface - Source surface prior to blending. 901428d7b3dSmrg * subx, suby, subw, subh - The rectangle from the subpicture to use. 902428d7b3dSmrg * surfx, surfy, surfw, surfh - The rectangle in the surface to blend 903428d7b3dSmrg * blend the subpicture rectangle into. Scaling can ocure if 904428d7b3dSmrg * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set. 905428d7b3dSmrg * 906428d7b3dSmrg * Returns: Status 907428d7b3dSmrg */ 908428d7b3dSmrg_X_EXPORT Status XvMCBlendSubpicture2(Display * display, 909428d7b3dSmrg XvMCSurface * source_surface, 910428d7b3dSmrg XvMCSurface * target_surface, 911428d7b3dSmrg XvMCSubpicture * subpicture, 912428d7b3dSmrg short subx, short suby, 913428d7b3dSmrg unsigned short subw, unsigned short subh, 914428d7b3dSmrg short surfx, short surfy, 915428d7b3dSmrg unsigned short surfw, 916428d7b3dSmrg unsigned short surfh) 917428d7b3dSmrg{ 918428d7b3dSmrg XVMC_ERR("XvMCBlendSubpicture2 not implemented!"); 919428d7b3dSmrg return BadValue; 920428d7b3dSmrg} 921428d7b3dSmrg 922428d7b3dSmrg/* 923428d7b3dSmrg * Function: XvMCSyncSubpicture 924428d7b3dSmrg * Description: This function blocks until all composite/clear requests on 925428d7b3dSmrg * the subpicture have been complete. 926428d7b3dSmrg * Arguments: 927428d7b3dSmrg * display - Connection to the X server. 928428d7b3dSmrg * subpicture - The subpicture to synchronize 929428d7b3dSmrg * 930428d7b3dSmrg * Returns: Status 931428d7b3dSmrg */ 932428d7b3dSmrg_X_EXPORT Status XvMCSyncSubpicture(Display * display, 933428d7b3dSmrg XvMCSubpicture * subpicture) 934428d7b3dSmrg{ 935428d7b3dSmrg XVMC_ERR("XvMCSyncSubpicture not implemented!"); 936428d7b3dSmrg return BadValue; 937428d7b3dSmrg} 938428d7b3dSmrg 939428d7b3dSmrg/* 940428d7b3dSmrg * Function: XvMCFlushSubpicture 941428d7b3dSmrg * Description: This function commits pending composite/clear requests to 942428d7b3dSmrg * ensure that they will be completed in a finite amount of 943428d7b3dSmrg * time. 944428d7b3dSmrg * Arguments: 945428d7b3dSmrg * display - Connection to the X server. 946428d7b3dSmrg * subpicture - The subpicture whos compsiting should be flushed 947428d7b3dSmrg * 948428d7b3dSmrg * Returns: Status 949428d7b3dSmrg */ 950428d7b3dSmrg_X_EXPORT Status XvMCFlushSubpicture(Display * display, 951428d7b3dSmrg XvMCSubpicture * subpicture) 952428d7b3dSmrg{ 953428d7b3dSmrg XVMC_ERR("XvMCFlushSubpicture not implemented!"); 954428d7b3dSmrg return BadValue; 955428d7b3dSmrg} 956428d7b3dSmrg 957428d7b3dSmrg/* 958428d7b3dSmrg * Function: XvMCGetSubpictureStatus 959428d7b3dSmrg * Description: This function gets the current status of a subpicture 960428d7b3dSmrg * 961428d7b3dSmrg * Arguments: 962428d7b3dSmrg * display - Connection to the X server. 963428d7b3dSmrg * subpicture - The subpicture whos status is being queried 964428d7b3dSmrg * stat - The status of the subpicture. It can be any of the following 965428d7b3dSmrg * OR'd together: 966428d7b3dSmrg * XVMC_RENDERING - Last composite or clear request not completed 967428d7b3dSmrg * XVMC_DISPLAYING - Suppicture currently being displayed. 968428d7b3dSmrg * 969428d7b3dSmrg * Returns: Status 970428d7b3dSmrg */ 971428d7b3dSmrg_X_EXPORT Status XvMCGetSubpictureStatus(Display * display, 972428d7b3dSmrg XvMCSubpicture * subpicture, int *stat) 973428d7b3dSmrg{ 974428d7b3dSmrg XVMC_ERR("XvMCGetSubpictureStatus not implemented!"); 975428d7b3dSmrg return BadValue; 976428d7b3dSmrg} 977428d7b3dSmrg 978428d7b3dSmrg/* 979428d7b3dSmrg * Function: XvMCQueryAttributes 980428d7b3dSmrg * Description: An array of XvAttributes of size "number" is returned by 981428d7b3dSmrg * this function. If there are no attributes, NULL is returned and number 982428d7b3dSmrg * is set to 0. The array may be freed with free(). 983428d7b3dSmrg * 984428d7b3dSmrg * Arguments: 985428d7b3dSmrg * display - Connection to the X server. 986428d7b3dSmrg * context - The context whos attributes we are querying. 987428d7b3dSmrg * number - The returned number of recognized atoms 988428d7b3dSmrg * 989428d7b3dSmrg * Returns: 990428d7b3dSmrg * An array of XvAttributes. 991428d7b3dSmrg */ 992428d7b3dSmrg_X_EXPORT XvAttribute *XvMCQueryAttributes(Display * display, 993428d7b3dSmrg XvMCContext * context, int *number) 994428d7b3dSmrg{ 995428d7b3dSmrg /* now XvMC has no extra attribs than Xv */ 996428d7b3dSmrg *number = 0; 997428d7b3dSmrg return NULL; 998428d7b3dSmrg} 999428d7b3dSmrg 1000428d7b3dSmrg/* 1001428d7b3dSmrg * Function: XvMCSetAttribute 1002428d7b3dSmrg * Description: This function sets a context-specific attribute. 1003428d7b3dSmrg * 1004428d7b3dSmrg * Arguments: 1005428d7b3dSmrg * display - Connection to the X server. 1006428d7b3dSmrg * context - The context whos attributes we are querying. 1007428d7b3dSmrg * attribute - The X atom of the attribute to be changed. 1008428d7b3dSmrg * value - The new value for the attribute. 1009428d7b3dSmrg * 1010428d7b3dSmrg * Returns: 1011428d7b3dSmrg * Status 1012428d7b3dSmrg */ 1013428d7b3dSmrg_X_EXPORT Status XvMCSetAttribute(Display * display, XvMCContext * context, 1014428d7b3dSmrg Atom attribute, int value) 1015428d7b3dSmrg{ 1016428d7b3dSmrg return Success; 1017428d7b3dSmrg} 1018428d7b3dSmrg 1019428d7b3dSmrg/* 1020428d7b3dSmrg * Function: XvMCGetAttribute 1021428d7b3dSmrg * Description: This function queries a context-specific attribute and 1022428d7b3dSmrg * returns the value. 1023428d7b3dSmrg * 1024428d7b3dSmrg * Arguments: 1025428d7b3dSmrg * display - Connection to the X server. 1026428d7b3dSmrg * context - The context whos attributes we are querying. 1027428d7b3dSmrg * attribute - The X atom of the attribute to be queried 1028428d7b3dSmrg * value - The returned attribute value 1029428d7b3dSmrg * 1030428d7b3dSmrg * Returns: 1031428d7b3dSmrg * Status 1032428d7b3dSmrg */ 1033428d7b3dSmrg_X_EXPORT Status XvMCGetAttribute(Display * display, XvMCContext * context, 1034428d7b3dSmrg Atom attribute, int *value) 1035428d7b3dSmrg{ 1036428d7b3dSmrg return Success; 1037428d7b3dSmrg} 1038428d7b3dSmrg 1039428d7b3dSmrg_X_EXPORT Status XvMCBeginSurface(Display * display, XvMCContext * context, 1040428d7b3dSmrg XvMCSurface * target, 1041428d7b3dSmrg XvMCSurface * past, 1042428d7b3dSmrg XvMCSurface * future, 1043428d7b3dSmrg const XvMCMpegControl * control) 1044428d7b3dSmrg{ 1045428d7b3dSmrg if (xvmc_driver->begin_surface(display, context, 1046428d7b3dSmrg target, past, future, control)) { 1047428d7b3dSmrg XVMC_ERR("BeginSurface fail\n"); 1048428d7b3dSmrg return BadValue; 1049428d7b3dSmrg } 1050428d7b3dSmrg return Success; 1051428d7b3dSmrg} 1052428d7b3dSmrg 1053428d7b3dSmrg_X_EXPORT Status XvMCLoadQMatrix(Display * display, XvMCContext * context, 1054428d7b3dSmrg const XvMCQMatrix * qmx) 1055428d7b3dSmrg{ 1056428d7b3dSmrg if (xvmc_driver->load_qmatrix(display, context, qmx)) { 1057428d7b3dSmrg XVMC_ERR("LoadQMatrix fail\n"); 1058428d7b3dSmrg return BadValue; 1059428d7b3dSmrg } 1060428d7b3dSmrg return Success; 1061428d7b3dSmrg} 1062428d7b3dSmrg 1063428d7b3dSmrg_X_EXPORT Status XvMCPutSlice(Display * display, XvMCContext * context, 1064428d7b3dSmrg char *slice, int nbytes) 1065428d7b3dSmrg{ 1066428d7b3dSmrg if (xvmc_driver->put_slice(display, context, (unsigned char *) slice, nbytes)) { 1067428d7b3dSmrg XVMC_ERR("PutSlice fail\n"); 1068428d7b3dSmrg return BadValue; 1069428d7b3dSmrg } 1070428d7b3dSmrg return Success; 1071428d7b3dSmrg} 1072428d7b3dSmrg 1073428d7b3dSmrg_X_EXPORT Status XvMCPutSlice2(Display * display, XvMCContext * context, 1074428d7b3dSmrg char *slice, int nbytes, int slice_code) 1075428d7b3dSmrg{ 1076428d7b3dSmrg if (xvmc_driver->put_slice2 1077428d7b3dSmrg (display, context, (unsigned char *) slice, nbytes, slice_code)) { 1078428d7b3dSmrg XVMC_ERR("PutSlice2 fail\n"); 1079428d7b3dSmrg return BadValue; 1080428d7b3dSmrg } 1081428d7b3dSmrg return Success; 1082428d7b3dSmrg} 1083