summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuc Verhaegen <libv@skynet.be>2009-08-06 17:51:49 +0200
committerLuc Verhaegen <libv@skynet.be>2009-11-04 15:13:01 +0100
commit0f4f1c981e72c6f7e10b000248057e4415471a61 (patch)
tree262b9c537a5f81469ebf1c0941cdf8b937971515
parentd83fb0bb2b0c944f5da4b1270488d35ddb5815c7 (diff)
XvMC: Hook up Xv and PutImage the surface XID into the driver.
Next up, attaching hw code!
-rw-r--r--lib/xvmc/xvmc_unichrome.c77
-rw-r--r--src/via_video.c49
2 files changed, 119 insertions, 7 deletions
diff --git a/lib/xvmc/xvmc_unichrome.c b/lib/xvmc/xvmc_unichrome.c
index 46bd7b0..a8fe4ad 100644
--- a/lib/xvmc/xvmc_unichrome.c
+++ b/lib/xvmc/xvmc_unichrome.c
@@ -37,6 +37,8 @@
#include "xvmce.h"
#include "xvmce_proto.h"
+#define FOURCC_MPEG (('G' << 24) | ('E' << 16) | ('P' << 8) | 'M')
+
/* Oh you must be kidding me. What a bunch of clueless idiots. */
extern Status _xvmc_create_context(Display *dpy, XvMCContext *context,
int *priv_count, CARD32 **priv_data);
@@ -67,6 +69,10 @@ static int current_surface_size = 0;
/* because of the rather abhorrent nature of the XvMC interface. */
static XvPortID XvMCPortID = 0;
+static XvImage *XvMCImage = NULL;
+static XID *XvMCImageID = 0;
+static Drawable *XvMCDrawable = NULL;
+static GC XvMCDrawableGC = NULL;
/*
*
@@ -79,6 +85,8 @@ XvMCCreateContext(Display *display, XvPortID port, int surface_type_id,
int major, minor;
int priv_count;
CARD32 *priv_data = NULL;
+ XvImageFormatValues *ImageFormats;
+ int count, i;
printf("%s\n", __func__);
@@ -107,6 +115,27 @@ XvMCCreateContext(Display *display, XvPortID port, int surface_type_id,
}
printf("Found Unichrome XvMCE Extension version %d.%d.\n", major, minor);
+ /* Find our *special* FOURCC */
+ ImageFormats = XvListImageFormats(display, port, &count);
+ for (i = 0; i < count; i++)
+ if (ImageFormats[i].id == FOURCC_MPEG)
+ break;
+
+ XFree(ImageFormats); /* don't need it anymore. */
+
+ if (i == count) {
+ fprintf(stderr, "%s: Unable to find FOURCC_MPEG.\n", __func__);
+ return BadImplementation;
+ }
+
+ /* Create the image for Xv to use. */
+ XvMCImage = XvCreateImage(display, port, FOURCC_MPEG,
+ (char *) &XvMCImageID, width, height);
+ if (!XvMCImage) {
+ fprintf(stderr, "%s: XvCreateImage Failed.\n", __func__);
+ return BadImplementation;
+ }
+
/* Only now, we can go and try to create a context, with a twist. */
context->surface_type_id = surface_type_id;
context->width = width; /* this better be correct, or we die */
@@ -132,14 +161,28 @@ XvMCCreateContext(Display *display, XvPortID port, int surface_type_id,
_X_EXPORT Status
XvMCDestroyContext(Display *display, XvMCContext *context)
{
+ Status status;
printf("%s\n", __func__);
if (!display || !context)
return BadValue;
+ if (XvMCDrawable)
+ status = XvStopVideo(display, XvMCPortID, XvMCDrawable);
+ if (status != Success)
+ fprintf(stderr, "%s: XvStopVideo failed: %d\n", __func__, status);
+ XvMCDrawable = NULL;
+
+ if (XvMCImage)
+ XFree(XvMCImage);
+ XvMCImage = NULL;
+
XvMCPortID = 0;
- return _xvmc_destroy_context(display, context);
+ status = _xvmc_destroy_context(display, context);
+ if (status != Success)
+ fprintf(stderr, "%s: _xvmc_destroy_context failed: %d\n", __func__, status);
+ XvMCDrawable = NULL;
}
@@ -197,11 +240,27 @@ 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)
{
+ Status status;
+
printf("%s: 0x%08X\n", __func__, surface->surface_id);
- /* XvPutImage here. */
+ /* We have to fake our own GC, how cool an interface is this? */
+ if (XvMCDrawable != draw) {
+ if (XvMCDrawableGC)
+ XFreeGC(display, XvMCDrawableGC);
+ XvMCDrawableGC = XCreateGC(display, draw, 0, NULL);
+ }
+
+ XvMCDrawable = draw;
+ XvMCImageID = surface->surface_id;
- return Success;
+ status = XvPutImage(display, XvMCPortID, XvMCDrawable, XvMCDrawableGC,
+ XvMCImage, src_x, src_y, src_w, src_h,
+ dst_x, dst_y, dst_w, dst_h);
+ if (status != Success)
+ fprintf(stderr, "%s: XvPutImage failed: %d\n", __func__, status);
+
+ return status;
}
@@ -211,11 +270,19 @@ XvMCPutSurface(Display *display, XvMCSurface *surface, Drawable draw,
_X_EXPORT Status
XvMCHideSurface(Display *display, XvMCSurface *surface)
{
+ Status status = Success;
+
printf("%s\n", __func__);
- /* XvStopVideo */
+ if (XvMCDrawable)
+ status = XvStopVideo(display, XvMCPortID, XvMCDrawable);
- return BadImplementation;
+ if (status != Success)
+ fprintf(stderr, "%s: XvStopVideo failed: %d\n", __func__, status);
+
+ XvMCDrawable = NULL;
+
+ return status;
}
diff --git a/src/via_video.c b/src/via_video.c
index c9e25c7..d61d46f 100644
--- a/src/via_video.c
+++ b/src/via_video.c
@@ -208,7 +208,32 @@ static XF86AttributeRec AttributesG[NUM_ATTRIBUTES_G] =
XvTopToBottom \
}
-#define NUM_IMAGES_G 6
+/*
+ * MPEG: Just holds a buffer id.
+ */
+#ifndef FOURCC_MPEG
+#define FOURCC_MPEG (('G' << 24) | ('E' << 16) | ('P' << 8) | 'M')
+#endif
+#define XVIMAGE_MPEG \
+ { \
+ FOURCC_MPEG, \
+ XvYUV, \
+ LSBFirst, \
+ { 'M', 'P', 'E', 'G' }, \
+ 12, \
+ XvPlanar, \
+ 1, \
+ 0, \
+ 0, 0, 0, \
+ 8, 8, 8, \
+ 1, 2, 2, \
+ 1, 2, 2, \
+ { 'Y', 'U', 'V' }, \
+ XvTopToBottom \
+ }
+
+
+#define NUM_IMAGES_G 7
static XF86ImageRec ImagesG[NUM_IMAGES_G] =
{
XVIMAGE_YUY2,
@@ -216,7 +241,8 @@ static XF86ImageRec ImagesG[NUM_IMAGES_G] =
XVIMAGE_I420,
XVIMAGE_RV15,
XVIMAGE_RV16,
- XVIMAGE_RV32
+ XVIMAGE_RV32,
+ XVIMAGE_MPEG
};
/*
@@ -1944,6 +1970,12 @@ viaPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, short drw_x,
struct ViaXvPort *Port = (struct ViaXvPort *) data;
Bool ReAlloc = FALSE, Video3Touched = FALSE, ClippingTouched = FALSE;
+ if (id == FOURCC_MPEG) {
+ ViaDebug(pScrn->scrnIndex, "%s: MPEG: 0x%08X\n", __func__,
+ *((XID *) buf));
+ return Success;
+ }
+
if (!Swov->Active) { /* initial pass */
ReAlloc = TRUE;
Video3Touched = TRUE;
@@ -2217,6 +2249,19 @@ viaQueryImageAttributes(ScrnInfoPtr pScrn, int FourCC, CARD16 *Width,
}
break;
+ case FOURCC_MPEG: /* actual buffer will only contain an Mpeg Buffer ID */
+ *Width = ALIGN_TO(*Width, 32);
+ *Height = ALIGN_TO(*Height, 16);
+
+ Size = 4;
+
+ if (pitches)
+ pitches[0] = 4;
+
+ if (offsets)
+ offsets[0] = 0;
+
+ break;
case FOURCC_YUY2: /* YUV422 */
case FOURCC_RV15: /* RGB555 */
case FOURCC_RV16: /* RGB565 */