summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2009-08-06 12:19:18 +0200
committerLuc Verhaegen <libv@skynet.be>2009-11-04 15:13:01 +0100
commitd83fb0bb2b0c944f5da4b1270488d35ddb5815c7 (patch)
tree4e01393205cae9c6bd117be6b87b9182e854c035
parent3f46f94324b73ce91f4e555d6c3568f8ef483fb6 (diff)
XvMC: Implement SliceInit and SliceSend protocol.
-rw-r--r--lib/xvmc/xvmc_unichrome.c78
-rw-r--r--lib/xvmc/xvmce.c76
-rw-r--r--lib/xvmc/xvmce.h11
-rw-r--r--lib/xvmc/xvmce_proto.h73
-rw-r--r--src/via_xvmc.c110
5 files changed, 343 insertions, 5 deletions
diff --git a/lib/xvmc/xvmc_unichrome.c b/lib/xvmc/xvmc_unichrome.c
index e2932b8..46bd7b0 100644
--- a/lib/xvmc/xvmc_unichrome.c
+++ b/lib/xvmc/xvmc_unichrome.c
@@ -199,6 +199,8 @@ XvMCPutSurface(Display *display, XvMCSurface *surface, Drawable draw,
{
printf("%s: 0x%08X\n", __func__, surface->surface_id);
+ /* XvPutImage here. */
+
return Success;
}
@@ -211,6 +213,8 @@ XvMCHideSurface(Display *display, XvMCSurface *surface)
{
printf("%s\n", __func__);
+ /* XvStopVideo */
+
return BadImplementation;
}
@@ -302,15 +306,65 @@ XvMCBeginSurface(Display *display, XvMCContext *context, XvMCSurface *target,
XvMCSurface *past, XvMCSurface *future,
const XvMCMpegControl *control)
{
+ Status status;
+ CARD8 PictureType, SliceFlags;
+
if (current_surface_id == target->surface_id)
return BadValue;
+ current_surface_id = target->surface_id;
+ current_surface_size = 0;
+
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;
+
+ printf("Backwards vertical: %d\n", control->BVMV_range);
+ printf("Backwards horizontal: %d\n", control->BHMV_range);
+ printf("Forwards vertical: %d\n", control->FVMV_range);
+ printf("Forwards horizontal: %d\n", control->FHMV_range);
+
+ printf("Picture Structure: %d\n", control->picture_structure);
+
+ printf("intra_dc_precision: %d\n", control->intra_dc_precision);
+ printf("picture_coding_type: %d\n", control->picture_coding_type);
+ printf("mpeg_coding: %d\n", control->mpeg_coding);
+ printf("flags: 0x%08X\n", control->flags);
+
+ PictureType = 0;
+ PictureType |= control->picture_structure &
+ XVMCE_PICTURETYPE_STRUCTURE_MASK;
+ PictureType |= (control->picture_coding_type << 2) &
+ XVMCE_PICTURETYPE_FRAMETYPE_MASK;
+ if (control->flags & XVMC_ALTERNATE_SCAN)
+ PictureType |= XVMCE_PICTURETYPE_SCAN_ALTERNATE;
+
+ SliceFlags = 0;
+ if (control->flags & XVMC_PRED_DCT_FRAME)
+ SliceFlags |= XVMCE_SLICEFLAGS_PREDICTION_FRAME;
+ if (control->flags & XVMC_TOP_FIELD_FIRST)
+ SliceFlags |= XVMCE_SLICEFLAGS_FIELD_FIRST_TOP;
+ if (control->flags & XVMC_CONCEALMENT_MOTION_VECTORS)
+ SliceFlags |= XVMCE_SLICEFLAGS_INTRA_HAS_MV;
+ if (control->flags & XVMC_INTRA_VLC_FORMAT)
+ SliceFlags |= XVMCE_SLICEFLAGS_INTRA_DC_TABLE_MASK;
+ SliceFlags |= (control->intra_dc_precision << 4) &
+ XVMCE_SLICEFLAGS_INTRA_PRECISION_MASK;
+ if (control->flags & XVMC_Q_SCALE_TYPE)
+ SliceFlags |= XVMCE_SLICEFLAGS_QUANTIZATION_TABLE_MASK;
+
+ status = XVMCEBufferSliceInit(display, XvMCPortID, target->surface_id,
+ PictureType, SliceFlags,
+ past ? 1 : 0, past ? past->surface_id : 0,
+ future ? 1 : 0, future ? future->surface_id : 0,
+ control->BHMV_range, control->BVMV_range,
+ control->FHMV_range, control->FVMV_range);
+ if (status != Success) {
+ fprintf(stderr, "%s: XVMCEBufferSliceInit failed: %d\n",
+ __func__, status);
+ return status;
+ }
return Success;
}
@@ -323,12 +377,20 @@ _X_EXPORT Status
XvMCPutSlice(Display *display, XvMCContext *context,
char *slice, int size)
{
+ Status status;
+
printf("%s:0x%08X (%dbytes)\n", __func__,
current_surface_id, size);
current_surface_size += size;
- return Success;
+ status = XVMCEBufferSliceSend(display, XvMCPortID, current_surface_id,
+ size, slice);
+ if (status != Success)
+ fprintf(stderr, "%s: XVMCEBufferSliceSend failed: %d\n",
+ __func__, status);
+
+ return status;
}
@@ -339,12 +401,20 @@ _X_EXPORT Status
XvMCPutSlice2(Display *display, XvMCContext *context,
char *slice, int size, int slicecode)
{
+ Status status;
+
printf("%s: 0x%08X: %02X (%dbytes)\n", __func__,
current_surface_id, slicecode, size);
current_surface_size += size;
- return Success;
+ status = XVMCEBufferSliceSend(display, XvMCPortID, current_surface_id,
+ size, slice);
+ if (status != Success)
+ fprintf(stderr, "%s: XVMCEBufferSliceSend failed: %d\n",
+ __func__, status);
+
+ return status;
}
diff --git a/lib/xvmc/xvmce.c b/lib/xvmc/xvmce.c
index 88b8473..fc59494 100644
--- a/lib/xvmc/xvmce.c
+++ b/lib/xvmc/xvmce.c
@@ -193,3 +193,79 @@ XVMCEBufferStatus(Display *dpy, XvPortID port, XID Buffer, int *StatusFlags)
return status;
}
+
+/*
+ *
+ */
+Status
+XVMCEBufferSliceInit(Display *dpy, XvPortID port, XID Buffer,
+ CARD8 PictureType, CARD8 SliceFlags,
+ Bool HasBackwardsReference, XID BackwardsReference,
+ Bool HasForwardsReference, XID ForwardsReference,
+ CARD8 MVRange_BackwardsHorizontal,
+ CARD8 MVRange_BackwardsVertical,
+ CARD8 MVRange_ForwardsHorizontal,
+ CARD8 MVRange_ForwardsVertical)
+{
+ XExtDisplayInfo *info = XvMCEFindDisplay(dpy);
+ xvmceBufferSliceInitReq *req;
+
+
+ XvMCECheckExtension(dpy, info, BadImplementation);
+
+ LockDisplay(dpy);
+
+ XvMCEGetReq(BufferSliceInit, req);
+
+ req->Port = port;
+ req->Buffer = Buffer;
+ req->PictureType = PictureType;
+ req->SliceFlags = SliceFlags;
+
+ req->ReferencesPresent = 0;
+ if (HasBackwardsReference)
+ req->ReferencesPresent |= XVMCE_BACKWARDS_PRESENT;
+ if (HasForwardsReference)
+ req->ReferencesPresent |= XVMCE_FORWARDS_PRESENT;
+
+ req->BackwardsReferenceBuffer = BackwardsReference;
+ req->ForwardsReferenceBuffer = ForwardsReference;
+
+ req->MVRange_BackwardsHorizontal = MVRange_BackwardsHorizontal;
+ req->MVRange_BackwardsVertical = MVRange_BackwardsVertical;
+ req->MVRange_ForwardsHorizontal = MVRange_ForwardsHorizontal;
+ req->MVRange_ForwardsVertical = MVRange_ForwardsVertical;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+/*
+ *
+ */
+Status
+XVMCEBufferSliceSend(Display *dpy, XvPortID port, XID Buffer,
+ int SliceSize, char *Slice)
+{
+ XExtDisplayInfo *info = XvMCEFindDisplay(dpy);
+ xvmceBufferSliceSendReq *req;
+
+ XvMCECheckExtension(dpy, info, BadImplementation);
+
+ LockDisplay(dpy);
+
+ XvMCEGetReqExtra(BufferSliceSend, req, SliceSize);
+
+ req->Port = port;
+ req->Buffer = Buffer;
+ req->SliceLength = SliceSize;
+
+ _XSend(dpy, Slice, SliceSize);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
diff --git a/lib/xvmc/xvmce.h b/lib/xvmc/xvmce.h
index de59de2..8454dbc 100644
--- a/lib/xvmc/xvmce.h
+++ b/lib/xvmc/xvmce.h
@@ -30,5 +30,14 @@ Status XvMCEQMatrixSend(Display *display, XvPortID port, char type,
const unsigned char qmatrix[64]);
Status XVMCEBufferStatus(Display *dpy, XvPortID port, XID Buffer,
int *StatusFlags);
-
+Status XVMCEBufferSliceInit(Display *dpy, XvPortID port, XID Buffer,
+ CARD8 PictureType, CARD8 SliceFlags,
+ Bool HasBackwardsReference, XID BackwardsReference,
+ Bool HasForwardsReference, XID ForwardsReference,
+ CARD8 MVRange_BackwardsHorizontal,
+ CARD8 MVRange_BackwardsVertical,
+ CARD8 MVRange_ForwardsHorizontal,
+ CARD8 MVRange_ForwardsVertical);
+Status XVMCEBufferSliceSend(Display *dpy, XvPortID port, XID Buffer,
+ int SliceSize, char *Slice);
#endif /* XVMCE_H */
diff --git a/lib/xvmc/xvmce_proto.h b/lib/xvmc/xvmce_proto.h
index 3a3989c..cdbe720 100644
--- a/lib/xvmc/xvmce_proto.h
+++ b/lib/xvmc/xvmce_proto.h
@@ -35,6 +35,8 @@
#define xvmce_QueryExtension 0
#define xvmce_QMatrixSend 1
#define xvmce_BufferStatus 2
+#define xvmce_BufferSliceInit 3
+#define xvmce_BufferSliceSend 4
/*
* Version, are we compatible?
@@ -106,4 +108,75 @@ typedef struct {
} xvmceBufferStatusReply;
#define sz_xvmceBufferStatusReply 32
+
+/*
+ *
+ */
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvmceReqType; /* xvmce_BufferSliceInit */
+ CARD16 length B16;
+ CARD32 Port B32;
+ CARD32 Buffer B32;
+
+#define XVMCE_PICTURETYPE_FIELD_TOP 0x01
+#define XVMCE_PICTURETYPE_FIELD_BOTTOM 0x02
+#define XVMCE_PICTURETYPE_FRAME 0x03 /* frame, so progressive. */
+#define XVMCE_PICTURETYPE_STRUCTURE_MASK 0x03
+
+#define XVMCE_PICTURETYPE_FRAMETYPE_I 0x01 << 2
+#define XVMCE_PICTURETYPE_FRAMETYPE_P 0x02 << 2
+#define XVMCE_PICTURETYPE_FRAMETYPE_B 0x03 << 2
+#define XVMCE_PICTURETYPE_FRAMETYPE_MASK 0x03 << 2
+
+#define XVMCE_PICTURETYPE_SCAN_ZIGZAG 0x00 << 4
+#define XVMCE_PICTURETYPE_SCAN_ALTERNATE 0x01 << 4
+#define XVMCE_PICTURETYPE_SCAN_MASK 0x01 << 4
+ CARD8 PictureType;
+
+#define XVMCE_SLICEFLAGS_PREDICTION_FIELD 0x00
+#define XVMCE_SLICEFLAGS_PREDICTION_FRAME 0x01
+#define XVMCE_SLICEFLAGS_PREDICTION_MASK 0x01
+
+#define XVMCE_SLICEFLAGS_FIELD_FIRST_BOTTOM 0x00 << 1
+#define XVMCE_SLICEFLAGS_FIELD_FIRST_TOP 0x01 << 1
+#define XVMCE_SLICEFLAGS_FIELD_FIRST_MASK 0x01 << 1
+
+#define XVMCE_SLICEFLAGS_INTRA_HAS_MV 0x01 << 2
+
+#define XVMCE_SLICEFLAGS_INTRA_DC_TABLE_MASK 0x01 << 3
+
+#define XVMCE_SLICEFLAGS_INTRA_PRECISION_MASK 0x03 << 4
+
+#define XVMCE_SLICEFLAGS_QUANTIZATION_TABLE_MASK 0x01 << 6
+ CARD8 SliceFlags;
+
+ CARD8 PadByte;
+#define XVMCE_BACKWARDS_PRESENT 1
+#define XVMCE_FORWARDS_PRESENT 2
+ CARD8 ReferencesPresent;
+
+ CARD32 BackwardsReferenceBuffer B32;
+ CARD32 ForwardsReferenceBuffer B32;
+
+ CARD8 MVRange_BackwardsHorizontal;
+ CARD8 MVRange_BackwardsVertical;
+ CARD8 MVRange_ForwardsHorizontal;
+ CARD8 MVRange_ForwardsVertical;
+} xvmceBufferSliceInitReq;
+#define sz_xvmceBufferSliceInitReq 28
+
+/*
+ *
+ */
+typedef struct {
+ CARD8 reqType;
+ CARD8 xvmceReqType; /* xvmce_BufferSliceSend */
+ CARD16 length B16;
+ CARD32 Port B32;
+ CARD32 Buffer B32;
+ CARD32 SliceLength B32;
+} xvmceBufferSliceSendReq;
+#define sz_xvmceBufferSliceSendReq 16
+
#endif /* XVMCE_PROTO_H */
diff --git a/src/via_xvmc.c b/src/via_xvmc.c
index ebd1103..f638cef 100644
--- a/src/via_xvmc.c
+++ b/src/via_xvmc.c
@@ -187,6 +187,112 @@ XvMCEProcBufferStatus(ClientPtr client)
*
*/
static int
+XvMCEProcBufferSliceInit(ClientPtr client)
+{
+ ExtensionEntry *XvMCE_Ext;
+ struct XvMCEPrivates *Private;
+ ScrnInfoPtr pScrn;
+ XvPortPtr Port;
+ int i;
+
+ REQUEST(xvmceBufferSliceInitReq);
+ REQUEST_SIZE_MATCH(xvmceBufferSliceInitReq);
+
+ 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;
+ }
+
+ for (i = 0; i < VIAMC_BUFFER_COUNT; i++)
+ if (ViaMCBufferIDs[i] == stuff->Buffer)
+ break;
+
+ if (i == VIAMC_BUFFER_COUNT) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Buffer 0x%08X does not "
+ "exist.\n", __func__, (unsigned int) stuff->Buffer);
+ return BadAccess;
+ }
+
+ ViaDebug(pScrn->scrnIndex, "%s: Buffer 0x%08X\n", __func__, stuff->Buffer);
+ ViaDebug(pScrn->scrnIndex, "\t PictureType: 0x%02X, SliceFlags: 0x%02X\n",
+ stuff->PictureType, stuff->SliceFlags);
+ ViaDebug(pScrn->scrnIndex, "\t Present %01X: backwards 0x%08X, forwards 0x%08X\n",
+ stuff->ReferencesPresent, stuff->BackwardsReferenceBuffer,
+ stuff->ForwardsReferenceBuffer);
+ ViaDebug(pScrn->scrnIndex, "\t Ranges BH %d, BV %d, FH %d, FV %d\n",
+ stuff->MVRange_BackwardsHorizontal, stuff->MVRange_BackwardsVertical,
+ stuff->MVRange_ForwardsHorizontal, stuff->MVRange_ForwardsVertical);
+
+ /* !!!! Setup hw here. !!!! */
+
+ return (client->noClientException);
+}
+/*
+ *
+ */
+static int
+XvMCEProcBufferSliceSend(ClientPtr client)
+{
+ ExtensionEntry *XvMCE_Ext;
+ struct XvMCEPrivates *Private;
+ ScrnInfoPtr pScrn;
+ XvPortPtr Port;
+ int i;
+
+ REQUEST(xvmceBufferSliceSendReq);
+ REQUEST_AT_LEAST_SIZE(xvmceBufferSliceSendReq);
+
+ 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;
+ }
+
+ for (i = 0; i < VIAMC_BUFFER_COUNT; i++)
+ if (ViaMCBufferIDs[i] == stuff->Buffer)
+ break;
+
+ if (i == VIAMC_BUFFER_COUNT) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Buffer 0x%08X does not "
+ "exist.\n", __func__, (unsigned int) stuff->Buffer);
+ return BadAccess;
+ }
+
+ ViaDebug(pScrn->scrnIndex, "%s: Buffer 0x%08X: Slice %dbytes\n",
+ __func__, stuff->Buffer, stuff->SliceLength);
+
+ /* !!!! dump the slice to the hw here. !!!! */
+
+ return (client->noClientException);
+}
+
+/*
+ *
+ */
+static int
XvMCEHandler(ClientPtr client)
{
REQUEST(xReq);
@@ -198,6 +304,10 @@ XvMCEHandler(ClientPtr client)
return XvMCEProcQMatrixSend(client);
case xvmce_BufferStatus:
return XvMCEProcBufferStatus(client);
+ case xvmce_BufferSliceInit:
+ return XvMCEProcBufferSliceInit(client);
+ case xvmce_BufferSliceSend:
+ return XvMCEProcBufferSliceSend(client);
default:
break;
}