/* * Function: XvMCCreateContext * Description: Create a XvMC context for the given surface parameters. * Arguments: * display - Connection to the X server. * port - XvPortID to use as avertised by the X connection. * surface_type_id - Unique identifier for the Surface type. * width - Width of the surfaces. * height - Height of the surfaces. * flags - one or more of the following * XVMC_DIRECT - A direct rendered context is requested. * * Notes: surface_type_id and width/height parameters must match those * returned by XvMCListSurfaceTypes. * Returns: Status */ _X_EXPORT Status XvMCCreateContext(Display * display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext * context) { Status ret; CARD32 *priv_data = NULL; struct intel_xvmc_hw_context *comm; int major, minor; int error_base; int event_base; int priv_count; /* Verify Obvious things first */ if (!display || !context) return BadValue; if (!(flags & XVMC_DIRECT)) { XVMC_ERR("Indirect Rendering not supported! Using Direct."); return BadValue; } /* Width, Height, and flags are checked against surface_type_id and port for validity inside the X server, no need to check here. */ context->surface_type_id = surface_type_id; context->width = (unsigned short)((width + 15) & ~15); context->height = (unsigned short)((height + 15) & ~15); context->flags = flags; context->port = port; if (!XvMCQueryExtension(display, &event_base, &error_base)) { XVMC_ERR("XvMCExtension is not available!"); return BadValue; } ret = XvMCQueryVersion(display, &major, &minor); if (ret) { XVMC_ERR ("XvMCQueryVersion Failed, unable to determine protocol version."); return ret; } /* XXX: major and minor could be checked in future for XvMC * protocol capability (i.e H.264/AVC decode available) */ /* Pass control to the X server to create a drm_context_t for us and validate the with/height and flags. */ if ((ret = _xvmc_create_context(display, context, &priv_count, &priv_data))) { XVMC_ERR("Unable to create XvMC Context."); return ret; } comm = (struct intel_xvmc_hw_context *)priv_data; if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { switch (comm->type) { case XVMC_I915_MPEG2_MC: xvmc_driver = &i915_xvmc_mc_driver; break; case XVMC_I965_MPEG2_MC: xvmc_driver = &i965_xvmc_mc_driver; break; case XVMC_I965_MPEG2_VLD: xvmc_driver = &xvmc_vld_driver; break; case XVMC_I945_MPEG2_VLD: default: XVMC_ERR("unimplemented xvmc type %d", comm->type); XFree(priv_data); priv_data = NULL; return BadValue; } } if (xvmc_driver == NULL || xvmc_driver->type != comm->type) { XVMC_ERR("fail to load xvmc driver for type %d\n", comm->type); return BadValue; } XVMC_INFO("decoder type is %s", intel_xvmc_decoder_string(comm->type)); /* check DRI2 */ ret = Success; xvmc_driver->fd = -1; ret = dri2_connect(display); if (ret != Success) { XFree(priv_data); context->privData = NULL; if (xvmc_driver->fd >= 0) close(xvmc_driver->fd); xvmc_driver = NULL; return ret; } if ((xvmc_driver->bufmgr = intel_bufmgr_gem_init(xvmc_driver->fd, 1024 * 64)) == NULL) { XVMC_ERR("Can't init bufmgr\n"); return BadAlloc; } drm_intel_bufmgr_gem_enable_reuse(xvmc_driver->bufmgr); /* call driver hook. * driver hook should free priv_data after return if success.*/ ret = (xvmc_driver->create_context) (display, context, priv_count, priv_data); if (ret) { XVMC_ERR("driver create context failed\n"); XFree(priv_data); context->privData = NULL; xvmc_driver = NULL; return ret; } pthread_mutex_init(&xvmc_driver->ctxmutex, NULL); intelInitBatchBuffer(); intel_xvmc_dump_open(); return Success; }
static Bool GetPortId(Display *dpy, XvPortID *portID, int *surface_type) { int i, j, k, numAdapt, numTypes, eventBase, errorBase; XvMCSurfaceInfo *surfaceInfo; XvAdaptorInfo *info; Bool result = 0; if(!XvMCQueryExtension(dpy, &eventBase, &errorBase)) return 0; if(Success != XvQueryAdaptors(dpy,DefaultRootWindow(dpy),&numAdapt,&info)) return 0; for(i = 0; i < numAdapt; i++) { if(info[i].type & XvImageMask) { surfaceInfo = XvMCListSurfaceTypes(display, info[i].base_id, &numTypes); if(surfaceInfo) { for(j = 0; j < numTypes; j++) { if((surfaceInfo[j].chroma_format == XVMC_CHROMA_FORMAT_420) && (surfaceInfo[j].max_width >= coded_picture_width) && (surfaceInfo[j].max_height >= coded_picture_height) && ((surfaceInfo[j].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)) || (surfaceInfo[j].mc_type == (XVMC_IDCT | XVMC_MPEG_2)))) { if(use_idct != -1) { if(use_idct == 1) { if(surfaceInfo[j].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)) continue; } else { if(surfaceInfo[j].mc_type == (XVMC_IDCT | XVMC_MPEG_2)) continue; } } for(k = 0; k < info[i].num_ports; k++) { /* try to grab a port */ if(Success == XvGrabPort(dpy, info[i].base_id + k, CurrentTime)) { *portID = info[i].base_id + k; *surface_type = surfaceInfo[j].surface_type_id; result = 1; break; } } if(result) { if(surfaceInfo[j].flags & XVMC_INTRA_UNSIGNED) unsignedIntra = 1; if(surfaceInfo[j].mc_type == (XVMC_IDCT | XVMC_MPEG_2)) useIDCT = 1; break; } } } XFree(surfaceInfo); } } } XvFreeAdaptorInfo(info); return result; }