summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2009-08-01 03:31:49 +0200
committerLuc Verhaegen <libv@skynet.be>2009-11-04 15:13:00 +0100
commit50bf8d8dc4843c19fe4a887c5b2e91c0ab2e5723 (patch)
treef9f14be1f364a70bc4702ec4a4b1d4c820348644
parent4fd8a42f2091e544ffcd4dabe2f8adcb441e89ec (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.c117
-rw-r--r--lib/xvmc/xvmce.c31
-rw-r--r--lib/xvmc/xvmce.h5
-rw-r--r--lib/xvmc/xvmce_proto.h17
-rw-r--r--src/via_xvmc.c117
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;
}
/*