diff options
author | Luc Verhaegen <libv@skynet.be> | 2009-08-01 03:31:49 +0200 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2009-11-04 15:13:00 +0100 |
commit | 50bf8d8dc4843c19fe4a887c5b2e91c0ab2e5723 (patch) | |
tree | f9f14be1f364a70bc4702ec4a4b1d4c820348644 | |
parent | 4fd8a42f2091e544ffcd4dabe2f8adcb441e89ec (diff) |
XvMC: Add qmatrix proto and fill out context and surface handling.
Qmatrix is part of the newly created X protocol.
Surface and context creation/destruction, XID based, is using plain old
XvMC.
Verbosity was increased on both sides of the thing, to clearly track
and verify the workings of the above code.
-rw-r--r-- | lib/xvmc/xvmc_unichrome.c | 117 | ||||
-rw-r--r-- | lib/xvmc/xvmce.c | 31 | ||||
-rw-r--r-- | lib/xvmc/xvmce.h | 5 | ||||
-rw-r--r-- | lib/xvmc/xvmce_proto.h | 17 | ||||
-rw-r--r-- | src/via_xvmc.c | 117 |
5 files changed, 248 insertions, 39 deletions
diff --git a/lib/xvmc/xvmc_unichrome.c b/lib/xvmc/xvmc_unichrome.c index f43b44e..d034715 100644 --- a/lib/xvmc/xvmc_unichrome.c +++ b/lib/xvmc/xvmc_unichrome.c @@ -35,6 +35,7 @@ #include <X11/extensions/vldXvMC.h> #include "xvmce.h" +#include "xvmce_proto.h" /* Oh you must be kidding me. What a bunch of clueless idiots. */ extern Status _xvmc_create_context(Display *dpy, XvMCContext *context, @@ -61,6 +62,9 @@ static int XvMC_ErrorBase; static int XvMCE_EventBase; static int XvMCE_ErrorBase; +static XID current_surface_id = 0; +static int current_surface_size = 0; + /* * */ @@ -109,12 +113,10 @@ XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, /* now call the old, raped X extension hooks */ status =_xvmc_create_context(display, context, &priv_count, &priv_data); - if (status != Success) { + if (status != Success) printf("%s: _xvmc_create_context failed: %d\n", __func__, status); - return status; - } - return Success; + return status; } @@ -129,7 +131,7 @@ XvMCDestroyContext(Display *display, XvMCContext *context) if (!display || !context) return BadValue; - return Success; + return _xvmc_destroy_context(display, context); } @@ -139,6 +141,10 @@ XvMCDestroyContext(Display *display, XvMCContext *context) _X_EXPORT Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) { + Status status; + int priv_count; + CARD32 *priv_data = NULL; + printf("%s\n", __func__); if (!display || !context) @@ -147,7 +153,14 @@ XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface) if (!surface) return XvMCBadSurface; - return Success; + status = _xvmc_create_surface(display, context, surface, + &priv_count, &priv_data); + if (status != Success) + printf("%s: _xvmc_create_surface failed: %d\n", __func__, status); + + printf("%s: Claimed 0x%08X.\n", __func__, surface->surface_id); + + return status; } @@ -159,7 +172,12 @@ XvMCDestroySurface(Display *display, XvMCSurface *surface) { printf("%s\n", __func__); - return Success; + if (!display || !surface) + return BadValue; + + printf("%s: releasing 0x%08X\n", __func__, surface->surface_id); + + return _xvmc_destroy_surface(display, surface); } /* @@ -171,7 +189,7 @@ XvMCPutSurface(Display *display, XvMCSurface *surface, Drawable draw, unsigned short src_h, short dst_x, short dst_y, unsigned short dst_w, unsigned short dst_h, int flags) { - printf("%s\n", __func__); + printf("%s: 0x%08X\n", __func__, surface->surface_id); return Success; } @@ -295,7 +313,7 @@ XvMCBlendSubpicture2(Display *display, XvMCSurface *source, XvMCSurface *target, _X_EXPORT Status XvMCSyncSurface(Display *display, XvMCSurface *surface) { - printf("%s\n", __func__); + printf("%s: 0x%08X\n", __func__, surface->surface_id); return Success; } @@ -307,7 +325,7 @@ XvMCSyncSurface(Display *display, XvMCSurface *surface) _X_EXPORT Status XvMCFlushSurface(Display *display, XvMCSurface *surface) { - //printf("%s\n", __func__); + printf("%s: 0x%08X (%dbytes)\n", __func__, surface->surface_id, current_surface_size); return Success; } @@ -384,7 +402,7 @@ _X_EXPORT Status XvMCCreateBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCBlockArray *blocks) { - printf("%s\n", __func__); + fprintf(stderr, "%s is not implemented.\n", __func__); return BadImplementation; } @@ -396,7 +414,7 @@ XvMCCreateBlocks(Display *display, XvMCContext *context, _X_EXPORT Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *blocks) { - printf("%s\n", __func__); + fprintf(stderr, "%s is not implemented.\n", __func__); return Success; } @@ -409,7 +427,7 @@ _X_EXPORT Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCMacroBlockArray *blocks) { - printf("%s\n", __func__); + fprintf(stderr, "%s is not implemented.\n", __func__); return BadImplementation; } @@ -421,7 +439,7 @@ XvMCCreateMacroBlocks(Display *display, XvMCContext *context, _X_EXPORT Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *blocks) { - printf("%s\n", __func__); + fprintf(stderr, "%s is not implemented.\n", __func__); return Success; } @@ -458,7 +476,6 @@ XvMCGetAttribute(Display *display, XvMCContext *context, } - /* * */ @@ -467,16 +484,17 @@ XvMCBeginSurface(Display *display, XvMCContext *context, XvMCSurface *target, XvMCSurface *past, XvMCSurface *future, const XvMCMpegControl *control) { - static int i = 0; - - i++; + if (current_surface_id == target->surface_id) + return BadValue; - printf("%s\n", __func__); + printf("%s: 0x%08X (0x%08X <- | -> 0x%08X)\n", __func__, + target->surface_id, + past ? past->surface_id : 0, + future? future->surface_id : 0); + current_surface_id = target->surface_id; + current_surface_size = 0; - if (i & 0x01) - return Success; - else - return BadValue; + return Success; } @@ -487,9 +505,48 @@ _X_EXPORT Status XvMCLoadQMatrix(Display *display, XvMCContext *context, const XvMCQMatrix *qmatrix) { - printf("%s\n", __func__); + Status status = Success; - return BadImplementation; + if (!display || !context) + return XvMCBadContext; + + if (!qmatrix) + return BadValue; + + if (qmatrix->load_intra_quantiser_matrix) { + status = XvMCEQMatrixSend(display, context->port, XVMCE_QMATRIX_INTRA, + qmatrix->intra_quantiser_matrix); + if (status != Success) + printf("%s: XvMCEQMatrixSend %s failed: %d\n", __func__, + "INTRA", status); + } + + if (qmatrix->load_non_intra_quantiser_matrix) { + status = XvMCEQMatrixSend(display, context->port, XVMCE_QMATRIX_NONINTRA, + qmatrix->non_intra_quantiser_matrix); + if (status != Success) + printf("%s: XvMCEQMatrixSend %s failed: %d\n", __func__, + "NONINTRA", status); + } + + if (qmatrix->load_chroma_intra_quantiser_matrix) { + status = XvMCEQMatrixSend(display, context->port, XVMCE_QMATRIX_INTRA_CHROMA, + qmatrix->chroma_intra_quantiser_matrix); + if (status != Success) + printf("%s: XvMCEQMatrixSend %s failed: %d\n", __func__, + "INTRA_CHROMA", status); + } + + if (qmatrix->load_chroma_non_intra_quantiser_matrix) { + status = XvMCEQMatrixSend(display, context->port, XVMCE_QMATRIX_NONINTRA_CHROMA, + qmatrix->chroma_non_intra_quantiser_matrix); + if (status != Success) + printf("%s: XvMCEQMatrixSend %s failed: %d\n", __func__, + "NONINTRA_CHROME", status); + } + + /* return last failure/success */ + return status; } @@ -500,7 +557,10 @@ _X_EXPORT Status XvMCPutSlice(Display *display, XvMCContext *context, char *slice, int size) { - //printf("%s\n", __func__); + printf("%s:0x%08X (%dbytes)\n", __func__, + current_surface_id, size); + + current_surface_size += size; return Success; } @@ -513,7 +573,10 @@ _X_EXPORT Status XvMCPutSlice2(Display *display, XvMCContext *context, char *slice, int size, int slicecode) { - //printf("%s\n", __func__); + printf("%s: 0x%08X: %02X (%dbytes)\n", __func__, + current_surface_id, slicecode, size); + + current_surface_size += size; return Success; } diff --git a/lib/xvmc/xvmce.c b/lib/xvmc/xvmce.c index 0576e60..69827d1 100644 --- a/lib/xvmc/xvmce.c +++ b/lib/xvmc/xvmce.c @@ -30,6 +30,7 @@ #include <X11/Xlib.h> #include <X11/extensions/Xv.h> #include <X11/extensions/Xvlib.h> +#include <X11/extensions/vldXvMC.h> #include <stdio.h> @@ -78,7 +79,7 @@ XEXT_GENERATE_FIND_DISPLAY(XvMCEFindDisplay, XvMCEExtInfo, XVMCE_EXT_NAME, dpy->bufptr += SIZEOF(xvmce##name##Req);\ dpy->request++ -#define XvmceGetReqExtra(name, req, len) \ +#define XvMCEGetReqExtra(name, req, len) \ WORD64ALIGN\ if ((dpy->bufptr + SIZEOF(xvmce##name##Req)) > dpy->bufmax)\ _XFlush(dpy);\ @@ -131,3 +132,31 @@ XvMCEQueryExtension(Display *dpy, int *Version, int *Release, return status; } + +/* + * + */ +Status +XvMCEQMatrixSend(Display *dpy, XvPortID port, char type, + const unsigned char qmatrix[64]) +{ + XExtDisplayInfo *info = XvMCEFindDisplay(dpy); + xvmceQMatrixSendReq *req; + + XvMCECheckExtension(dpy, info, BadImplementation); + + LockDisplay(dpy); + + XvMCEGetReqExtra(QMatrixSend, req, 64); + + req->Port = port; + req->Type = type; + + _XSend(dpy, (char *) qmatrix, 64); + + UnlockDisplay(dpy); + SyncHandle(); + + return Success; +} + diff --git a/lib/xvmc/xvmce.h b/lib/xvmc/xvmce.h index b196faf..49038c2 100644 --- a/lib/xvmc/xvmce.h +++ b/lib/xvmc/xvmce.h @@ -24,6 +24,9 @@ #ifndef XVMCE_H #define XVMCE_H -Status XvMCEQueryExtension(Display *dpy, int *Version, int *Release, int *event_basep, int *error_basep); +Status XvMCEQueryExtension(Display *display, int *Version, int *Release, + int *event_basep, int *error_basep); +Status XvMCEQMatrixSend(Display *display, XvPortID port, char type, + const unsigned char qmatrix[64]); #endif /* XVMCE_H */ diff --git a/lib/xvmc/xvmce_proto.h b/lib/xvmc/xvmce_proto.h index 38c42d6..bd4706b 100644 --- a/lib/xvmc/xvmce_proto.h +++ b/lib/xvmc/xvmce_proto.h @@ -33,6 +33,7 @@ #define XVMCE_RELEASE 0 #define xvmce_QueryExtension 0 +#define xvmce_QMatrixSend 1 /* * Version, are we compatible? @@ -58,4 +59,20 @@ typedef struct { } xvmceQueryExtensionReply; #define sz_xvmceQueryExtensionReply 32 +/* + * QMatrixSend, upload a Quantization matrix to the MPEG engine. + */ +typedef struct { + CARD8 reqType; + CARD8 xvmceReqType; /* xvmce_QMatrixSend */ + CARD16 length B16; + CARD32 Port B32; +#define XVMCE_QMATRIX_INTRA 0 +#define XVMCE_QMATRIX_NONINTRA 1 +#define XVMCE_QMATRIX_INTRA_CHROMA 2 +#define XVMCE_QMATRIX_NONINTRA_CHROMA 3 + CARD32 Type B32; +} xvmceQMatrixSendReq; +#define sz_xvmceQMatrixSendReq 12 + #endif /* XVMCE_PROTO_H */ diff --git a/src/via_xvmc.c b/src/via_xvmc.c index c98dab2..1abe972 100644 --- a/src/via_xvmc.c +++ b/src/via_xvmc.c @@ -54,13 +54,13 @@ struct XvMCEPrivates static int XvMCEProcQueryExtension(ClientPtr client) { - ExtensionEntry *MPEGExt; + ExtensionEntry *XvMCE_Ext; xvmceQueryExtensionReply rep; REQUEST_SIZE_MATCH(xvmceQueryExtensionReq); - MPEGExt = CheckExtension(XVMCE_EXT_NAME); - if(!MPEGExt || !MPEGExt->extPrivate) + XvMCE_Ext = CheckExtension(XVMCE_EXT_NAME); + if(!XvMCE_Ext || !XvMCE_Ext->extPrivate) return BadMatch; rep.type = X_Reply; @@ -78,6 +78,49 @@ XvMCEProcQueryExtension(ClientPtr client) * */ static int +XvMCEProcQMatrixSend(ClientPtr client) +{ + ExtensionEntry *XvMCE_Ext; + struct XvMCEPrivates *Private; + ScrnInfoPtr pScrn; + XvPortPtr Port; + + REQUEST(xvmceQMatrixSendReq); + REQUEST_AT_LEAST_SIZE(xvmceQMatrixSendReq); + + XvMCE_Ext = CheckExtension(XVMCE_EXT_NAME); + if (!XvMCE_Ext || !XvMCE_Ext->extPrivate) { + xf86Msg(X_WARNING, "%s: Extension not initialised.\n", __func__); + return BadMatch; + } + + Private = XvMCE_Ext->extPrivate; + pScrn = xf86Screens[Private->scrnIndex]; + + /* Does our client own this port? */ + Port = LookupIDByType(stuff->Port, XvGetRTPort()); + if (!Port) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "%s: Client doesn't own this Xv Port.\n", __func__); + return BadAccess; + } + + /* check size: 16 = 64Bytes / 4, from 8x8 QMatrix */ + if (client->req_len != ((sz_xvmceQMatrixSendReq >> 2) + 16)) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "%s: Request has wrong length.\n", __func__); + return BadLength; + } + + ViaDebug(pScrn->scrnIndex, "%s: type %1X\n", __func__, stuff->Type); + + return (client->noClientException); +} + +/* + * + */ +static int XvMCEHandler(ClientPtr client) { REQUEST(xReq); @@ -85,6 +128,8 @@ XvMCEHandler(ClientPtr client) switch (stuff->data) { case xvmce_QueryExtension: return XvMCEProcQueryExtension(client); + case xvmce_QMatrixSend: + return XvMCEProcQMatrixSend(client); default: break; } @@ -107,11 +152,11 @@ XvMCESHandler(ClientPtr client) * */ static void -XvMCEClose(ExtensionEntry *MPEGExt) +XvMCEClose(ExtensionEntry *XvMCE_Ext) { - if (MPEGExt->extPrivate) { - xfree(MPEGExt->extPrivate); - MPEGExt->extPrivate = NULL; + if (XvMCE_Ext->extPrivate) { + xfree(XvMCE_Ext->extPrivate); + XvMCE_Ext->extPrivate = NULL; } } @@ -166,6 +211,14 @@ static XF86MCSurfaceInfoRec ViaMCMpeg2Surface = { static XF86MCSurfaceInfoPtr ViaMCSurfaces[1] = {&ViaMCMpeg2Surface}; +/* Just some placeholders to be able to flesh out the library */ +static XID ViaMCContextID = 0; +static int ViaMCContextWidth = 0; +static int ViaMCContextHeight = 0; + +#define VIAMC_SURFACE_COUNT 8 +static XID ViaMCSurfacesIDs[VIAMC_SURFACE_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0}; + /* * */ @@ -173,12 +226,17 @@ static int ViaMCCreateContext(ScrnInfoPtr pScrn, XvMCContextPtr context, int *num_priv, CARD32 **priv) { - VIAFUNC(pScrn); - ViaDebug(pScrn->scrnIndex, "%s: adapter %d, surfaceid %08X (%dx%d); %08X\n", __func__, context->adapt_num, context->surface_type_id, context->width, context->height, context->flags); + if (ViaMCContextID) + return BadAccess; + + ViaMCContextID = context->context_id; + ViaMCContextWidth = context->height; + ViaMCContextHeight = context->flags; + return Success; } @@ -189,6 +247,13 @@ static void ViaMCDestroyContext(ScrnInfoPtr pScrn, XvMCContextPtr context) { VIAFUNC(pScrn); + + if (ViaMCContextID != context->context_id) + return; + + ViaMCContextID = 0; + ViaMCContextWidth = 0; + ViaMCContextHeight = 0; } /* @@ -198,9 +263,25 @@ static int ViaMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface, int *num_priv, CARD32 **priv) { + int i; + VIAFUNC(pScrn); - return BadAlloc; + if (ViaMCContextID != surface->context->context_id) + return BadAccess; + + for (i = 0; i < VIAMC_SURFACE_COUNT; i++) + if (!ViaMCSurfacesIDs[i]) + break; + + if (i == VIAMC_SURFACE_COUNT) + return BadAlloc; + + ViaDebug(pScrn->scrnIndex, "%s: claimed %d (%08X)\n", + __func__, i, surface->surface_id); + ViaMCSurfacesIDs[i] = surface->surface_id; + + return Success; } /* @@ -209,7 +290,23 @@ ViaMCCreateSurface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface, static void ViaMCDestroySurface(ScrnInfoPtr pScrn, XvMCSurfacePtr surface) { + int i; + VIAFUNC(pScrn); + + if (ViaMCContextID != surface->context->context_id) + return; + + for (i = 0; i < VIAMC_SURFACE_COUNT; i++) + if (ViaMCSurfacesIDs[i] == surface->surface_id) + break; + + if (i == VIAMC_SURFACE_COUNT) + return; + + ViaDebug(pScrn->scrnIndex, "%s: released %d (%08X)\n", + __func__, i, surface->surface_id); + ViaMCSurfacesIDs[i] = 0; } /* |