summaryrefslogtreecommitdiff
path: root/src/xvmc/intel_xvmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xvmc/intel_xvmc.c')
-rw-r--r--src/xvmc/intel_xvmc.c1075
1 files changed, 1075 insertions, 0 deletions
diff --git a/src/xvmc/intel_xvmc.c b/src/xvmc/intel_xvmc.c
new file mode 100644
index 000000000..883dadae3
--- /dev/null
+++ b/src/xvmc/intel_xvmc.c
@@ -0,0 +1,1075 @@
+/*
+ * Copyright © 2007 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Zhenyu Wang <zhenyu.z.wang@intel.com>
+ *
+ */
+#include "intel_xvmc.h"
+#include <xcb/xcb.h>
+#include <xcb/xcb_aux.h>
+#include <xcb/dri2.h>
+#include <X11/Xlib-xcb.h>
+#include <X11/extensions/dri2tokens.h>
+
+/* global */
+struct _intel_xvmc_driver *xvmc_driver = NULL;
+
+/* Lookup tables to speed common calculations for coded_block_pattern */
+/* each block is ((8*8) * sizeof(short)) */
+unsigned int mb_bytes_420[] = {
+ 0, /* 0 */
+ 128, /* 1 */
+ 128, /* 10 */
+ 256, /* 11 */
+ 128, /* 100 */
+ 256, /* 101 */
+ 256, /* 110 */
+ 384, /* 111 */
+ 128, /* 1000 */
+ 256, /* 1001 */
+ 256, /* 1010 */
+ 384, /* 1011 */
+ 256, /* 1100 */
+ 384, /* 1101 */
+ 384, /* 1110 */
+ 512, /* 1111 */
+ 128, /* 10000 */
+ 256, /* 10001 */
+ 256, /* 10010 */
+ 384, /* 10011 */
+ 256, /* 10100 */
+ 384, /* 10101 */
+ 384, /* 10110 */
+ 512, /* 10111 */
+ 256, /* 11000 */
+ 384, /* 11001 */
+ 384, /* 11010 */
+ 512, /* 11011 */
+ 384, /* 11100 */
+ 512, /* 11101 */
+ 512, /* 11110 */
+ 640, /* 11111 */
+ 128, /* 100000 */
+ 256, /* 100001 */
+ 256, /* 100010 */
+ 384, /* 100011 */
+ 256, /* 100100 */
+ 384, /* 100101 */
+ 384, /* 100110 */
+ 512, /* 100111 */
+ 256, /* 101000 */
+ 384, /* 101001 */
+ 384, /* 101010 */
+ 512, /* 101011 */
+ 384, /* 101100 */
+ 512, /* 101101 */
+ 512, /* 101110 */
+ 640, /* 101111 */
+ 256, /* 110000 */
+ 384, /* 110001 */
+ 384, /* 110010 */
+ 512, /* 110011 */
+ 384, /* 110100 */
+ 512, /* 110101 */
+ 512, /* 110110 */
+ 640, /* 110111 */
+ 384, /* 111000 */
+ 512, /* 111001 */
+ 512, /* 111010 */
+ 640, /* 111011 */
+ 512, /* 111100 */
+ 640, /* 111101 */
+ 640, /* 111110 */
+ 768 /* 111111 */
+};
+
+void LOCK_HARDWARE(drm_context_t ctx)
+{
+ PPTHREAD_MUTEX_LOCK();
+ assert(!xvmc_driver->locked);
+
+ xvmc_driver->locked = 1;
+}
+
+void UNLOCK_HARDWARE(drm_context_t ctx)
+{
+ xvmc_driver->locked = 0;
+
+ PPTHREAD_MUTEX_UNLOCK();
+}
+
+static int
+dri2_connect(Display *display)
+{
+ xcb_dri2_query_version_cookie_t query_version_cookie;
+ xcb_dri2_query_version_reply_t *query_version_reply;
+ xcb_dri2_connect_cookie_t connect_cookie;
+ xcb_dri2_connect_reply_t *connect_reply;
+ xcb_dri2_authenticate_cookie_t auth_cookie;
+ xcb_dri2_authenticate_reply_t *auth_reply;
+ xcb_screen_t *root;
+ xcb_connection_t *c = XGetXCBConnection(display);
+ drm_magic_t magic;
+ const xcb_query_extension_reply_t *dri2_reply;
+ char *device_name;
+ int len;
+
+ root = xcb_aux_get_screen(c, DefaultScreen(display));
+
+ dri2_reply = xcb_get_extension_data(c, &xcb_dri2_id);
+
+ if (!dri2_reply) {
+ XVMC_ERR("DRI2 required");
+ return BadValue;
+ }
+
+ /* Query the extension and make our first use of it at the same time. */
+ query_version_cookie = xcb_dri2_query_version(c, 1, 0);
+ connect_cookie = xcb_dri2_connect(c, root->root, DRI2DriverDRI);
+
+ query_version_reply =
+ xcb_dri2_query_version_reply(c, query_version_cookie, NULL);
+ connect_reply = xcb_dri2_connect_reply(c, connect_cookie, NULL);
+
+ if (!query_version_reply) {
+ XVMC_ERR("DRI2 required");
+ return BadValue;
+ }
+ free(query_version_reply);
+
+ len = xcb_dri2_connect_device_name_length(connect_reply);
+ device_name = malloc(len + 1);
+ if (!device_name) {
+ XVMC_ERR("malloc failure");
+ return BadAlloc;
+ }
+ strncpy(device_name, xcb_dri2_connect_device_name(connect_reply), len);
+ device_name[len] = 0;
+ xvmc_driver->fd = open(device_name, O_RDWR);
+ free(device_name);
+ free(connect_reply);
+ if (xvmc_driver->fd < 0) {
+ XVMC_ERR("Failed to open drm device: %s\n", strerror(errno));
+ return BadValue;
+ }
+
+ if (drmGetMagic(xvmc_driver->fd, &magic)) {
+ XVMC_ERR("Failed to get magic\n");
+ return BadValue;
+ }
+
+ auth_cookie = xcb_dri2_authenticate(c, root->root, magic);
+ auth_reply = xcb_dri2_authenticate_reply(c, auth_cookie, NULL);
+ if (!auth_reply) {
+ XVMC_ERR("Failed to authenticate magic %d\n", magic);
+ return BadValue;
+ }
+ free(auth_reply);
+
+ return Success;
+}
+
+/*
+* 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;
+}
+
+/*
+ * Function: XvMCDestroyContext
+ * Description: Destorys the specified context.
+ *
+ * Arguments:
+ * display - Specifies the connection to the server.
+ * context - The context to be destroyed.
+ *
+ */
+_X_EXPORT Status XvMCDestroyContext(Display * display, XvMCContext * context)
+{
+ Status ret;
+ int screen;
+
+ if (!display || !context)
+ return XvMCBadContext;
+ screen = DefaultScreen(display);
+ ret = (xvmc_driver->destroy_context) (display, context);
+ if (ret) {
+ XVMC_ERR("destroy context fail\n");
+ return ret;
+ }
+
+ intelFiniBatchBuffer();
+
+ dri_bufmgr_destroy(xvmc_driver->bufmgr);
+
+ ret = _xvmc_destroy_context(display, context);
+ if (ret != Success) {
+ XVMC_ERR("_xvmc_destroy_context fail\n");
+ return ret;
+ }
+
+ if (xvmc_driver->num_ctx == 0) {
+ pthread_mutex_destroy(&xvmc_driver->ctxmutex);
+
+ if (xvmc_driver->fd >= 0)
+ close(xvmc_driver->fd);
+
+ xvmc_driver->fd = -1;
+ intel_xvmc_dump_close();
+ }
+ return Success;
+}
+
+/*
+ * Function: XvMCCreateSurface
+ */
+_X_EXPORT Status XvMCCreateSurface(Display * display, XvMCContext * context,
+ XvMCSurface * surface)
+{
+ Status ret;
+ int priv_count;
+ CARD32 *priv_data;
+ intel_xvmc_surface_ptr intel_surf = NULL;
+ struct intel_xvmc_context *intel_ctx;
+
+ if (!display || !context)
+ return XvMCBadContext;
+
+ if (!surface)
+ return XvMCBadSurface;
+
+ intel_ctx = context->privData;
+
+ if ((ret = _xvmc_create_surface(display, context, surface,
+ &priv_count, &priv_data))) {
+ XVMC_ERR("Unable to create XvMCSurface.");
+ return ret;
+ }
+
+ XFree(priv_data);
+
+ surface->privData = calloc(1, sizeof(struct intel_xvmc_surface));
+
+ if (!(intel_surf = surface->privData)) {
+ PPTHREAD_MUTEX_UNLOCK();
+ return BadAlloc;
+ }
+
+ intel_surf->bo = drm_intel_bo_alloc(xvmc_driver->bufmgr,
+ "surface",
+ intel_ctx->surface_bo_size,
+ GTT_PAGE_SIZE);
+ if (!intel_surf->bo) {
+ free(intel_surf);
+ return BadAlloc;
+ }
+
+ drm_intel_bo_disable_reuse(intel_surf->bo);
+
+ intel_surf = surface->privData;
+ intel_surf->context = context;
+
+ intel_surf->image = XvCreateImage(display, context->port,
+ FOURCC_XVMC,
+ (char *) &intel_surf->gem_handle,
+ surface->width, surface->height);
+ if (!intel_surf->image) {
+ XVMC_ERR("Can't create XvImage for surface\n");
+ free(intel_surf);
+ _xvmc_destroy_surface(display, surface);
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+/*
+ * Function: XvMCDestroySurface
+ */
+_X_EXPORT Status XvMCDestroySurface(Display * display, XvMCSurface * surface)
+{
+ intel_xvmc_surface_ptr intel_surf;
+
+ if (!display || !surface)
+ return XvMCBadSurface;
+
+ intel_surf = surface->privData;
+ if (!intel_surf)
+ return XvMCBadSurface;
+
+ XFree(intel_surf->image);
+ if (intel_surf->gc_init)
+ XFreeGC(display, intel_surf->gc);
+
+ drm_intel_bo_unreference(intel_surf->bo);
+
+ free(intel_surf);
+
+ _xvmc_destroy_surface(display, surface);
+
+ return Success;
+}
+
+/*
+ * Function: XvMCCreateBlocks
+ */
+_X_EXPORT Status XvMCCreateBlocks(Display * display, XvMCContext * context,
+ unsigned int num_blocks,
+ XvMCBlockArray * block)
+{
+ if (!display || !context || !num_blocks || !block)
+ return BadValue;
+
+ memset(block, 0, sizeof(XvMCBlockArray));
+
+ if (!
+ (block->blocks =
+ (short *)malloc((num_blocks << 6) * sizeof(short))))
+ return BadAlloc;
+
+ block->num_blocks = num_blocks;
+ block->context_id = context->context_id;
+ block->privData = NULL;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCDestroyBlocks
+ */
+_X_EXPORT Status XvMCDestroyBlocks(Display * display, XvMCBlockArray * block)
+{
+ if (!display || !block)
+ return BadValue;
+
+ if (block->blocks)
+ free(block->blocks);
+
+ block->context_id = 0;
+ block->num_blocks = 0;
+ block->blocks = NULL;
+ block->privData = NULL;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCCreateMacroBlocks
+ */
+_X_EXPORT Status XvMCCreateMacroBlocks(Display * display, XvMCContext * context,
+ unsigned int num_blocks,
+ XvMCMacroBlockArray * blocks)
+{
+ if (!display || !context || !blocks || !num_blocks)
+ return BadValue;
+
+ memset(blocks, 0, sizeof(XvMCMacroBlockArray));
+ blocks->macro_blocks =
+ (XvMCMacroBlock *) malloc(num_blocks * sizeof(XvMCMacroBlock));
+
+ if (!blocks->macro_blocks)
+ return BadAlloc;
+
+ blocks->num_blocks = num_blocks;
+ blocks->context_id = context->context_id;
+ blocks->privData = NULL;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCDestroyMacroBlocks
+ */
+_X_EXPORT Status XvMCDestroyMacroBlocks(Display * display,
+ XvMCMacroBlockArray * block)
+{
+ if (!display || !block)
+ return BadValue;
+ if (block->macro_blocks)
+ free(block->macro_blocks);
+
+ block->context_id = 0;
+ block->num_blocks = 0;
+ block->macro_blocks = NULL;
+ block->privData = NULL;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCRenderSurface
+ *
+ * Description: This function does the actual HWMC. Given a list of
+ * macroblock structures it dispatched the hardware commands to execute
+ * them.
+ */
+_X_EXPORT Status XvMCRenderSurface(Display * display, XvMCContext * context,
+ unsigned int picture_structure,
+ XvMCSurface * target_surface,
+ XvMCSurface * past_surface,
+ XvMCSurface * future_surface,
+ unsigned int flags,
+ unsigned int num_macroblocks,
+ unsigned int first_macroblock,
+ XvMCMacroBlockArray * macroblock_array,
+ XvMCBlockArray * blocks)
+{
+ Status ret;
+
+ if (!display || !context) {
+ XVMC_ERR("Invalid Display, Context or Target!");
+ return XvMCBadContext;
+ }
+ if (!target_surface)
+ return XvMCBadSurface;
+
+ intel_xvmc_dump_render(context, picture_structure, target_surface,
+ past_surface, future_surface, flags,
+ num_macroblocks, first_macroblock,
+ macroblock_array, blocks);
+
+ ret =
+ (xvmc_driver->render_surface) (display, context, picture_structure,
+ target_surface, past_surface,
+ future_surface, flags,
+ num_macroblocks, first_macroblock,
+ macroblock_array, blocks);
+
+ if (ret) {
+ XVMC_ERR("render surface fail\n");
+ return ret;
+ }
+ return Success;
+}
+
+/*
+ * Function: XvMCPutSurface
+ *
+ * Description:
+ * Arguments:
+ * display: Connection to X server
+ * surface: Surface to be displayed
+ * draw: X Drawable on which to display the surface
+ * srcx: X coordinate of the top left corner of the region to be
+ * displayed within the surface.
+ * srcy: Y coordinate of the top left corner of the region to be
+ * displayed within the surface.
+ * srcw: Width of the region to be displayed.
+ * srch: Height of the region to be displayed.
+ * destx: X cordinate of the top left corner of the destination region
+ * in the drawable coordinates.
+ * desty: Y cordinate of the top left corner of the destination region
+ * in the drawable coordinates.
+ * destw: Width of the destination region.
+ * desth: Height of the destination region.
+ * flags: One or more of the following.
+ * XVMC_TOP_FIELD - Display only the Top field of the surface.
+ * XVMC_BOTTOM_FIELD - Display only the Bottom Field of the surface.
+ * XVMC_FRAME_PICTURE - Display both fields or frame.
+ */
+_X_EXPORT Status XvMCPutSurface(Display * display, XvMCSurface * surface,
+ Drawable draw, short srcx, short srcy,
+ unsigned short srcw, unsigned short srch,
+ short destx, short desty,
+ unsigned short destw, unsigned short desth,
+ int flags)
+{
+ Status ret = Success;
+ XvMCContext *context;
+ intel_xvmc_surface_ptr intel_surf;
+
+ if (!display || !surface)
+ return XvMCBadSurface;
+
+ intel_surf = surface->privData;
+ context = intel_surf->context;
+ if (!context || !intel_surf)
+ return XvMCBadSurface;
+
+ if (intel_surf->gc_init == FALSE) {
+ intel_surf->gc = XCreateGC(display, draw, 0, NULL);
+ intel_surf->gc_init = TRUE;
+ } else if (draw != intel_surf->last_draw) {
+ XFreeGC(display, intel_surf->gc);
+ intel_surf->gc = XCreateGC(display, draw, 0, NULL);
+ }
+ intel_surf->last_draw = draw;
+
+ drm_intel_bo_flink(intel_surf->bo, &intel_surf->gem_handle);
+
+ ret = XvPutImage(display, context->port, draw, intel_surf->gc,
+ intel_surf->image, srcx, srcy, srcw, srch, destx,
+ desty, destw, desth);
+ return ret;
+}
+
+/*
+ * Function: XvMCSyncSurface
+ * Arguments:
+ * display - Connection to the X server
+ * surface - The surface to synchronize
+ */
+_X_EXPORT Status XvMCSyncSurface(Display * display, XvMCSurface * surface)
+{
+ if (!display || !surface)
+ return XvMCBadSurface;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCFlushSurface
+ * Description:
+ * This function commits pending rendering requests to ensure that they
+ * wll be completed in a finite amount of time.
+ * Arguments:
+ * display - Connection to X server
+ * surface - Surface to flush
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCFlushSurface(Display * display, XvMCSurface * surface)
+{
+ if (!display || !surface)
+ return XvMCBadSurface;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCGetSurfaceStatus
+ * Description:
+ * Arguments:
+ * display: connection to X server
+ * surface: The surface to query
+ * stat: One of the Following
+ * XVMC_RENDERING - The last XvMCRenderSurface command has not
+ * completed.
+ * XVMC_DISPLAYING - The surface is currently being displayed or a
+ * display is pending.
+ */
+_X_EXPORT Status XvMCGetSurfaceStatus(Display * display, XvMCSurface * surface,
+ int *stat)
+{
+ if (!display || !surface || !stat)
+ return XvMCBadSurface;
+
+ *stat = 0;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCHideSurface
+ * Description: Stops the display of a surface.
+ * Arguments:
+ * display - Connection to the X server.
+ * surface - surface to be hidden.
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCHideSurface(Display * display, XvMCSurface * surface)
+{
+ if (!display || !surface)
+ return XvMCBadSurface;
+
+ return Success;
+}
+
+/*
+ * Function: XvMCCreateSubpicture
+ * Description: This creates a subpicture by filling out the XvMCSubpicture
+ * structure passed to it and returning Success.
+ * Arguments:
+ * display - Connection to the X server.
+ * context - The context to create the subpicture for.
+ * subpicture - Pre-allocated XvMCSubpicture structure to be filled in.
+ * width - of subpicture
+ * height - of subpicture
+ * xvimage_id - The id describing the XvImage format.
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCCreateSubpicture(Display * display, XvMCContext * context,
+ XvMCSubpicture * subpicture,
+ unsigned short width,
+ unsigned short height, int xvimage_id)
+{
+ XVMC_ERR("XvMCCreateSubpicture not implemented!\n");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCClearSubpicture
+ * Description: Clear the area of the given subpicture to "color".
+ * structure passed to it and returning Success.
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - Subpicture to clear.
+ * x, y, width, height - rectangle in the subpicture to clear.
+ * color - The data to file the rectangle with.
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCClearSubpicture(Display * display,
+ XvMCSubpicture * subpicture, short x,
+ short y, unsigned short width,
+ unsigned short height, unsigned int color)
+{
+ XVMC_ERR("XvMCClearSubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCCompositeSubpicture
+ * Description: Composite the XvImae on the subpicture. This composit uses
+ * non-premultiplied alpha. Destination alpha is utilized
+ * except for with indexed subpictures. Indexed subpictures
+ * use a simple "replace".
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - Subpicture to clear.
+ * image - the XvImage to be used as the source of the composite.
+ * srcx, srcy, width, height - The rectangle from the image to be used.
+ * dstx, dsty - location in the subpicture to composite the source.
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCCompositeSubpicture(Display * display,
+ XvMCSubpicture * subpicture,
+ XvImage * image, short srcx,
+ short srcy, unsigned short width,
+ unsigned short height, short dstx,
+ short dsty)
+{
+ XVMC_ERR("XvMCCompositeSubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCDestroySubpicture
+ * Description: Destroys the specified subpicture.
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - Subpicture to be destroyed.
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCDestroySubpicture(Display * display,
+ XvMCSubpicture * subpicture)
+{
+ XVMC_ERR("XvMCDestroySubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCSetSubpicturePalette
+ * Description: Set the subpictures palette
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - Subpiture to set palette for.
+ * palette - A pointer to an array holding the palette data. The array
+ * is num_palette_entries * entry_bytes in size.
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCSetSubpicturePalette(Display * display,
+ XvMCSubpicture * subpicture,
+ unsigned char *palette)
+{
+ XVMC_ERR("XvMCSetSubpicturePalette not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCBlendSubpicture
+ * Description:
+ * The behavior of this function is different depending on whether
+ * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+ * i915 only support frontend behavior.
+ *
+ * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+ *
+ * XvMCBlendSubpicture is a no-op in this case.
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture to be blended into the video.
+ * target_surface - The surface to be displayed with the blended subpic.
+ * source_surface - Source surface prior to blending.
+ * subx, suby, subw, subh - The rectangle from the subpicture to use.
+ * surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+ * blend the subpicture rectangle into. Scaling can ocure if
+ * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCBlendSubpicture(Display * display,
+ XvMCSurface * target_surface,
+ XvMCSubpicture * subpicture, short subx,
+ short suby, unsigned short subw,
+ unsigned short subh, short surfx,
+ short surfy, unsigned short surfw,
+ unsigned short surfh)
+{
+ XVMC_ERR("XvMCBlendSubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCBlendSubpicture2
+ * Description:
+ * The behavior of this function is different depending on whether
+ * or not the XVMC_BACKEND_SUBPICTURE flag is set in the XvMCSurfaceInfo.
+ * i915 only supports frontend blending.
+ *
+ * XVMC_BACKEND_SUBPICTURE not set ("frontend" behavior):
+ *
+ * XvMCBlendSubpicture2 blends the source_surface and subpicture and
+ * puts it in the target_surface. This does not effect the status of
+ * the source surface but will cause the target_surface to query
+ * XVMC_RENDERING until the blend is completed.
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture to be blended into the video.
+ * target_surface - The surface to be displayed with the blended subpic.
+ * source_surface - Source surface prior to blending.
+ * subx, suby, subw, subh - The rectangle from the subpicture to use.
+ * surfx, surfy, surfw, surfh - The rectangle in the surface to blend
+ * blend the subpicture rectangle into. Scaling can ocure if
+ * XVMC_SUBPICTURE_INDEPENDENT_SCALING is set.
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCBlendSubpicture2(Display * display,
+ XvMCSurface * source_surface,
+ XvMCSurface * target_surface,
+ XvMCSubpicture * subpicture,
+ short subx, short suby,
+ unsigned short subw, unsigned short subh,
+ short surfx, short surfy,
+ unsigned short surfw,
+ unsigned short surfh)
+{
+ XVMC_ERR("XvMCBlendSubpicture2 not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCSyncSubpicture
+ * Description: This function blocks until all composite/clear requests on
+ * the subpicture have been complete.
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture to synchronize
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCSyncSubpicture(Display * display,
+ XvMCSubpicture * subpicture)
+{
+ XVMC_ERR("XvMCSyncSubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCFlushSubpicture
+ * Description: This function commits pending composite/clear requests to
+ * ensure that they will be completed in a finite amount of
+ * time.
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture whos compsiting should be flushed
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCFlushSubpicture(Display * display,
+ XvMCSubpicture * subpicture)
+{
+ XVMC_ERR("XvMCFlushSubpicture not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCGetSubpictureStatus
+ * Description: This function gets the current status of a subpicture
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * subpicture - The subpicture whos status is being queried
+ * stat - The status of the subpicture. It can be any of the following
+ * OR'd together:
+ * XVMC_RENDERING - Last composite or clear request not completed
+ * XVMC_DISPLAYING - Suppicture currently being displayed.
+ *
+ * Returns: Status
+ */
+_X_EXPORT Status XvMCGetSubpictureStatus(Display * display,
+ XvMCSubpicture * subpicture, int *stat)
+{
+ XVMC_ERR("XvMCGetSubpictureStatus not implemented!");
+ return BadValue;
+}
+
+/*
+ * Function: XvMCQueryAttributes
+ * Description: An array of XvAttributes of size "number" is returned by
+ * this function. If there are no attributes, NULL is returned and number
+ * is set to 0. The array may be freed with free().
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * context - The context whos attributes we are querying.
+ * number - The returned number of recognized atoms
+ *
+ * Returns:
+ * An array of XvAttributes.
+ */
+_X_EXPORT XvAttribute *XvMCQueryAttributes(Display * display,
+ XvMCContext * context, int *number)
+{
+ /* now XvMC has no extra attribs than Xv */
+ *number = 0;
+ return NULL;
+}
+
+/*
+ * Function: XvMCSetAttribute
+ * Description: This function sets a context-specific attribute.
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * context - The context whos attributes we are querying.
+ * attribute - The X atom of the attribute to be changed.
+ * value - The new value for the attribute.
+ *
+ * Returns:
+ * Status
+ */
+_X_EXPORT Status XvMCSetAttribute(Display * display, XvMCContext * context,
+ Atom attribute, int value)
+{
+ return Success;
+}
+
+/*
+ * Function: XvMCGetAttribute
+ * Description: This function queries a context-specific attribute and
+ * returns the value.
+ *
+ * Arguments:
+ * display - Connection to the X server.
+ * context - The context whos attributes we are querying.
+ * attribute - The X atom of the attribute to be queried
+ * value - The returned attribute value
+ *
+ * Returns:
+ * Status
+ */
+_X_EXPORT Status XvMCGetAttribute(Display * display, XvMCContext * context,
+ Atom attribute, int *value)
+{
+ return Success;
+}
+
+_X_EXPORT Status XvMCBeginSurface(Display * display, XvMCContext * context,
+ XvMCSurface * target,
+ XvMCSurface * past,
+ XvMCSurface * future,
+ const XvMCMpegControl * control)
+{
+ if (xvmc_driver->begin_surface(display, context,
+ target, past, future, control)) {
+ XVMC_ERR("BeginSurface fail\n");
+ return BadValue;
+ }
+ return Success;
+}
+
+_X_EXPORT Status XvMCLoadQMatrix(Display * display, XvMCContext * context,
+ const XvMCQMatrix * qmx)
+{
+ if (xvmc_driver->load_qmatrix(display, context, qmx)) {
+ XVMC_ERR("LoadQMatrix fail\n");
+ return BadValue;
+ }
+ return Success;
+}
+
+_X_EXPORT Status XvMCPutSlice(Display * display, XvMCContext * context,
+ char *slice, int nbytes)
+{
+ if (xvmc_driver->put_slice(display, context, (unsigned char *) slice, nbytes)) {
+ XVMC_ERR("PutSlice fail\n");
+ return BadValue;
+ }
+ return Success;
+}
+
+_X_EXPORT Status XvMCPutSlice2(Display * display, XvMCContext * context,
+ char *slice, int nbytes, int slice_code)
+{
+ if (xvmc_driver->put_slice2
+ (display, context, (unsigned char *) slice, nbytes, slice_code)) {
+ XVMC_ERR("PutSlice2 fail\n");
+ return BadValue;
+ }
+ return Success;
+}