diff options
author | Luc Verhaegen <libv@skynet.be> | 2009-08-06 12:19:18 +0200 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2009-11-04 15:13:01 +0100 |
commit | d83fb0bb2b0c944f5da4b1270488d35ddb5815c7 (patch) | |
tree | 4e01393205cae9c6bd117be6b87b9182e854c035 | |
parent | 3f46f94324b73ce91f4e555d6c3568f8ef483fb6 (diff) |
XvMC: Implement SliceInit and SliceSend protocol.
-rw-r--r-- | lib/xvmc/xvmc_unichrome.c | 78 | ||||
-rw-r--r-- | lib/xvmc/xvmce.c | 76 | ||||
-rw-r--r-- | lib/xvmc/xvmce.h | 11 | ||||
-rw-r--r-- | lib/xvmc/xvmce_proto.h | 73 | ||||
-rw-r--r-- | src/via_xvmc.c | 110 |
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; } |