PUBLIC Status XvMCDestroyContext(Display *dpy, XvMCContext *context) { XvMCContextPrivate *context_priv; XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying context %p.\n", context); assert(dpy); if (!context || !context->privData) return XvMCBadContext; context_priv = context->privData; context_priv->decoder->destroy(context_priv->decoder); vl_compositor_cleanup_state(&context_priv->cstate); vl_compositor_cleanup(&context_priv->compositor); context_priv->pipe->destroy(context_priv->pipe); vl_screen_destroy(context_priv->vscreen); FREE(context_priv); context->privData = NULL; XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p destroyed.\n", context); return Success; }
PUBLIC Status XvMCDestroyContext(Display *dpy, XvMCContext *context) { struct vl_screen *vscreen; struct vl_context *vctx; XvMCContextPrivate *context_priv; XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying context %p.\n", context); assert(dpy); if (!context || !context->privData) return XvMCBadContext; context_priv = context->privData; vctx = context_priv->vctx; vscreen = vctx->vscreen; pipe_surface_reference(&context_priv->drawable_surface, NULL); context_priv->decoder->destroy(context_priv->decoder); vl_compositor_cleanup(&context_priv->compositor); vl_video_destroy(vctx); vl_screen_destroy(vscreen); FREE(context_priv); context->privData = NULL; XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p destroyed.\n", context); return Success; }
PUBLIC Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context) { bool found_port; int scrn = 0; int chroma_format = 0; int mc_type = 0; int surface_flags = 0; unsigned short subpic_max_w = 0; unsigned short subpic_max_h = 0; Status ret; struct vl_screen *vscreen; struct pipe_context *pipe; struct pipe_video_codec templat = {0}; XvMCContextPrivate *context_priv; vl_csc_matrix csc; XVMC_MSG(XVMC_TRACE, "[XvMC] Creating context %p.\n", context); assert(dpy); if (!context) return XvMCBadContext; ret = Validate(dpy, port, surface_type_id, width, height, flags, &found_port, &scrn, &chroma_format, &mc_type, &surface_flags, &subpic_max_w, &subpic_max_h); /* Success and XvBadPort have the same value */ if (ret != Success || !found_port) return ret; /* XXX: Current limits */ if (chroma_format != XVMC_CHROMA_FORMAT_420) { XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsupported chroma format.\n"); return BadImplementation; } if ((mc_type & ~XVMC_IDCT) != (XVMC_MOCOMP | XVMC_MPEG_2)) { XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Non-MPEG2/Mocomp/iDCT acceleration unsupported.\n"); return BadImplementation; } if (surface_flags & XVMC_INTRA_UNSIGNED) { XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsigned intra unsupported.\n"); return BadImplementation; } context_priv = CALLOC(1, sizeof(XvMCContextPrivate)); if (!context_priv) return BadAlloc; /* TODO: Reuse screen if process creates another context */ vscreen = vl_screen_create(dpy, scrn); if (!vscreen) { XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL screen.\n"); FREE(context_priv); return BadAlloc; } pipe = vscreen->pscreen->context_create(vscreen->pscreen, vscreen, 0); if (!pipe) { XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL context.\n"); vl_screen_destroy(vscreen); FREE(context_priv); return BadAlloc; } templat.profile = ProfileToPipe(mc_type); templat.entrypoint = (mc_type & XVMC_IDCT) ? PIPE_VIDEO_ENTRYPOINT_IDCT : PIPE_VIDEO_ENTRYPOINT_MC; templat.chroma_format = FormatToPipe(chroma_format); templat.width = width; templat.height = height; templat.max_references = 2; templat.expect_chunked_decode = true; context_priv->decoder = pipe->create_video_codec(pipe, &templat); if (!context_priv->decoder) { XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL decoder.\n"); pipe->destroy(pipe); vl_screen_destroy(vscreen); FREE(context_priv); return BadAlloc; } if (!vl_compositor_init(&context_priv->compositor, pipe)) { XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor.\n"); context_priv->decoder->destroy(context_priv->decoder); pipe->destroy(pipe); vl_screen_destroy(vscreen); FREE(context_priv); return BadAlloc; } if (!vl_compositor_init_state(&context_priv->cstate, pipe)) { XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor state.\n"); vl_compositor_cleanup(&context_priv->compositor); context_priv->decoder->destroy(context_priv->decoder); pipe->destroy(pipe); vl_screen_destroy(vscreen); FREE(context_priv); return BadAlloc; } context_priv->color_standard = debug_get_bool_option("G3DVL_NO_CSC", FALSE) ? VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601; context_priv->procamp = vl_default_procamp; vl_csc_get_matrix ( context_priv->color_standard, &context_priv->procamp, true, &csc ); vl_compositor_set_csc_matrix(&context_priv->cstate, (const vl_csc_matrix *)&csc); context_priv->vscreen = vscreen; context_priv->pipe = pipe; context_priv->subpicture_max_width = subpic_max_w; context_priv->subpicture_max_height = subpic_max_h; context->context_id = XAllocID(dpy); context->surface_type_id = surface_type_id; context->width = width; context->height = height; context->flags = flags; context->port = port; context->privData = context_priv; SyncHandle(); XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p created.\n", context); return Success; }