diff options
author | Luc Verhaegen <libv@skynet.be> | 2009-08-06 17:51:49 +0200 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2009-11-04 15:13:01 +0100 |
commit | 0f4f1c981e72c6f7e10b000248057e4415471a61 (patch) | |
tree | 262b9c537a5f81469ebf1c0941cdf8b937971515 | |
parent | d83fb0bb2b0c944f5da4b1270488d35ddb5815c7 (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.c | 77 | ||||
-rw-r--r-- | src/via_video.c | 49 |
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 */ |