#include #include #include #include #include #include #include #define FOURCC_YV12 0x32315659 /* ie. {'Y','V','1','2'} */ void GetYUVFromRGB (int R, int G, int B, int *Y, int *U, int *V) { *Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16 - 128; *U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128 - 128; *V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128 - 128; } void GetRGBFromYUV (int Y, int U, int V, int *R, int *G, int *B) { int C, D, E; C = Y + 128 - 16; D = U + 128 - 128; E = V + 128 - 128; *R = (298 * C + 409 * E + 128) >> 8; *G = (298 * C - 100 * D - 208 * E + 128) >> 8; *B = (298 * C + 516 * D + 128) >> 8; } int main(int argc, char **argv) { int width = 720, height = 576; int mb_width, mb_height, coded_width, coded_height; Window root, window; Display *dpy; int surface_type_id; int i, j, k, numAdapt, numImages, numTypes, eventBase, errorBase; XvMCSurfaceInfo *surfaceInfo; XvAdaptorInfo *info; int portNum; XvMCContext context; int numsurfaces = 1; XvMCSurface surfaces[1]; XvMCBlockArray blocks; XvMCMacroBlockArray macro_blocks; XEvent ev; XImage *image; XvImageFormatValues *formats; XvAttribute *attrs; GC gc_context; mb_width = (width + 15) / 16; mb_height = (height + 15) / 16; coded_width = mb_width * 16; coded_height = mb_height * 16; dpy = XOpenDisplay(NULL); if (!dpy) { printf("XOpenDisplay failed\n"); return 0; } root = XDefaultRootWindow(dpy); if (!XvMCQueryExtension(dpy, &eventBase, &errorBase)) { printf("XvMCQueryExtension failed\n"); return 0; } int major = 0, minor = 0; if (Success != XvMCQueryVersion(dpy, &major, &minor)) { printf("XvMCQueryVersion failed\n"); return 0; } printf("major = %d, minor = %d\n", major, minor); if (Success != XvQueryAdaptors(dpy, DefaultRootWindow(dpy), &numAdapt, &info)) { printf("XvQueryAdaptors failed\n"); return 0; } for(i = 0; i < numAdapt; i++) { if(info[i].type & XvImageMask) { formats = XvListImageFormats (dpy, info[i].base_id, &numImages); for (j = 0; j < numImages; j++) { if (formats[j].id == FOURCC_YV12) { printf("support FOURCC_YV12\n"); break; } } XFree (formats); surfaceInfo = XvMCListSurfaceTypes(dpy, info[i].base_id, &numTypes); if(surfaceInfo) { for(j = 0; j < numTypes; j++) { printf("surfaceInfo[%d].subpicture_max_width = %d\n", j, surfaceInfo[j].subpicture_max_width); printf("surfaceInfo[%d].subpicture_max_height = %d\n", j, surfaceInfo[j].subpicture_max_height); printf("surfaceInfo[%d].max_width = %d\n", j, surfaceInfo[j].max_width); printf("surfaceInfo[%d].max_height = %d\n", j, surfaceInfo[j].max_height); printf("surfaceInfo[%d].flags = %d\n", j, surfaceInfo[j].flags); if (surfaceInfo[j].chroma_format == XVMC_CHROMA_FORMAT_420) printf("XVMC_CHROMA_FORMAT_420\n"); if (surfaceInfo[j].chroma_format == XVMC_CHROMA_FORMAT_422) printf("XVMC_CHROMA_FORMAT_422\n"); if (surfaceInfo[j].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)) printf("(XVMC_MOCOMP | XVMC_MPEG_2)\n"); if (surfaceInfo[j].mc_type == (XVMC_IDCT | XVMC_MPEG_2)) printf("(XVMC_IDCT | XVMC_MPEG_2)\n"); if((surfaceInfo[j].chroma_format == XVMC_CHROMA_FORMAT_420) && (surfaceInfo[j].max_width >= coded_width) && (surfaceInfo[j].max_height >= coded_height) && ((surfaceInfo[j].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)))) // (surfaceInfo[j].mc_type == (XVMC_IDCT | XVMC_MPEG_2)))) { printf("found\n"); for(k = 0; k < info[i].num_ports; k++) { if(Success == XvGrabPort(dpy, info[i].base_id + k, CurrentTime)) { printf("XvGrabPort(%d)\n", info[i].base_id + k); portNum = info[i].base_id + k; surface_type_id = surfaceInfo[j].surface_type_id; break; } } } } } XFree(surfaceInfo); } } XvFreeAdaptorInfo(info); if (Success != XvMCCreateContext(dpy, portNum, surface_type_id, coded_width, coded_height, XVMC_DIRECT, &context)) { printf("couldn't create XvMCContext\n"); return 0; } if (BadMatch != XvMCSetAttribute(dpy, &context, (Atom)-1, -1)) { printf("XvMCSetAttribute is expected to return 'BadMatch'\n"); } int value; if (BadMatch != XvMCGetAttribute(dpy, &context, (Atom)-1, &value)) { printf("XvMCGetAttribute is expected to return 'BadMatch'\n"); } XvMCDestroyContext(dpy, &context); XvUngrabPort(dpy, portNum, CurrentTime); XCloseDisplay(dpy); }