bool XVWindow::checkMaxSize(unsigned int width, unsigned int height) { XvEncodingInfo * xveinfo; unsigned int numXveinfo = 0; unsigned int i; bool ret = false; if (XvQueryEncodings (_display, _XVPort, &numXveinfo, &xveinfo) != Success) { PTRACE(4, "XVideo\tXvQueryEncodings failed\n"); return false; } for (i = 0 ; i < numXveinfo ; i++) { if ( strcmp( xveinfo[i].name, "XV_IMAGE" ) == 0 ) { if ( (width <= xveinfo[i].width ) || (height <= xveinfo[i].height) ) ret = true; else { PTRACE(1, "XVideo\tRequested resolution " << width << "x" << height << " higher than maximum supported resolution " << xveinfo[i].width << "x" << xveinfo[i].height); ret = false; } break; } } XvFreeEncodingInfo(xveinfo); return ret; }
void XVWindow::DumpCapabilities (int port) { XvImageFormatValues *xviformats = 0; XvAttribute *xvattributes = NULL; XvEncodingInfo *xveinfo = NULL; unsigned int numXveinfo = 0; unsigned int i = 0; int numXvattributes = 0; int j = 0; int numXviformats = 0; char info[512]; if (XvQueryEncodings (_display, port, &numXveinfo, &xveinfo) != Success) { PTRACE(4, "XVideo\tXvQueryEncodings failed\n"); return; } for (i = 0 ; i < numXveinfo ; i++) { PTRACE(4, "XVideo\tEncoding List for Port " << port << ": " << " id=" << xveinfo [i].encoding_id << " name=" << xveinfo [i].name << " size=" << xveinfo [i].width << "x" << xveinfo[i].height << " numerator=" << xveinfo [i].rate.numerator << " denominator=" << xveinfo [i].rate.denominator); } XvFreeEncodingInfo(xveinfo); PTRACE(4, "XVideo\tAttribute List for Port " << port << ":"); xvattributes = XvQueryPortAttributes (_display, port, &numXvattributes); for (j = 0 ; j < numXvattributes ; j++) { PTRACE(4, " �name: � � � " << xvattributes [j].name); PTRACE(4, " �flags: � � " << ((xvattributes [j].flags & XvGettable) ? " get" : "") << ((xvattributes [j].flags & XvSettable) ? " set" : "")); PTRACE(4, " �min_color: �" << xvattributes [j].min_value); PTRACE(4, " �max_color: �" << xvattributes [j].max_value); } if (xvattributes) XFree (xvattributes); PTRACE (4, "XVideo\tImage format list for Port " << port << ":"); xviformats = XvListImageFormats (_display, port, &numXviformats); for (j = 0 ; j < numXviformats ; j++) { sprintf (info, " 0x%x (%4.4s) %s, order: %s", xviformats [j].id, (char *) &xviformats [j].id, (xviformats [j].format == XvPacked) ? "packed" : "planar", xviformats [j].component_order); PTRACE(4, info); } if (xviformats) XFree (xviformats); }
// Get maximum supported source image dimensions. // If querying the dimensions fails, don't change *width and *height. static void xv_get_max_img_dim(struct vo *vo, uint32_t *width, uint32_t *height) { struct xvctx *ctx = vo->priv; XvEncodingInfo *encodings; unsigned int num_encodings, idx; XvQueryEncodings(vo->x11->display, ctx->xv_port, &num_encodings, &encodings); if (encodings) { for (idx = 0; idx < num_encodings; ++idx) { if (strcmp(encodings[idx].name, "XV_IMAGE") == 0) { *width = encodings[idx].width; *height = encodings[idx].height; break; } } } MP_VERBOSE(vo, "Maximum source image dimensions: %ux%u\n", *width, *height); XvFreeEncodingInfo(encodings); }
int main (int argc, char* argv[]) { int yuv_width = 1024; int yuv_height = 768; int xv_port = -1; int adaptor, encodings, attributes, formats; int i, j, ret, p, _d, _w, _h; long secsb, secsa, frames; XvAdaptorInfo *ai; XvEncodingInfo *ei; XvAttribute *at; XvImageFormatValues *fo; XvImage *yuv_image; #define GUID_YUV12_PLANAR 0x32315659 unsigned int p_version, p_release, p_request_base, p_event_base, p_error_base; int p_num_adaptors; Display *dpy; Window window, _dw; XSizeHints hint; XSetWindowAttributes xswa; XVisualInfo vinfo; int screen; unsigned long mask; XEvent event; GC gc; /** for shm */ int shmem_flag = 0; XShmSegmentInfo yuv_shminfo; int CompletionType; printf("starting up video testapp...\n\n"); adaptor = -1; dpy = XOpenDisplay(NULL); if (dpy == NULL) { printf("Cannot open Display.\n"); exit (-1); } screen = DefaultScreen(dpy); /** find best display */ if (XMatchVisualInfo(dpy, screen, 24, TrueColor, &vinfo)) { printf(" found 24bit TrueColor\n"); } else if (XMatchVisualInfo(dpy, screen, 16, TrueColor, &vinfo)) { printf(" found 16bit TrueColor\n"); } else if (XMatchVisualInfo(dpy, screen, 15, TrueColor, &vinfo)) { printf(" found 15bit TrueColor\n"); } else if (XMatchVisualInfo(dpy, screen, 8, PseudoColor, &vinfo)) { printf(" found 8bit PseudoColor\n"); } else if (XMatchVisualInfo(dpy, screen, 8, GrayScale, &vinfo)) { printf(" found 8bit GrayScale\n"); } else if (XMatchVisualInfo(dpy, screen, 8, StaticGray, &vinfo)) { printf(" found 8bit StaticGray\n"); } else if (XMatchVisualInfo(dpy, screen, 1, StaticGray, &vinfo)) { printf(" found 1bit StaticGray\n"); } else { printf("requires 16 bit display\n"); exit (-1); } CompletionType = -1; hint.x = 1; hint.y = 1; hint.width = yuv_width; hint.height = yuv_height; hint.flags = PPosition | PSize; xswa.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), vinfo.visual, AllocNone); xswa.event_mask = StructureNotifyMask | ExposureMask; xswa.background_pixel = 0; xswa.border_pixel = 0; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; window = XCreateWindow(dpy, DefaultRootWindow(dpy), 0, 0, yuv_width, yuv_height, 0, vinfo.depth, InputOutput, vinfo.visual, mask, &xswa); XStoreName(dpy, window, "XV"); XSetIconName(dpy, window, "XV"); XSelectInput(dpy, window, StructureNotifyMask); /** Map window */ XMapWindow(dpy, window); /** Wait for map. */ do { XNextEvent(dpy, &event); } while (event.type != MapNotify || event.xmap.event != window); if (XShmQueryExtension(dpy)) shmem_flag = 1; if (!shmem_flag) { printf("no shmem available.\n"); exit (-1); } if (shmem_flag==1) CompletionType = XShmGetEventBase(dpy) + ShmCompletion; /**--------------------------------- XV ------------------------------------*/ printf("beginning to parse the Xvideo extension...\n\n"); /** query and print Xvideo properties */ ret = XvQueryExtension(dpy, &p_version, &p_release, &p_request_base, &p_event_base, &p_error_base); if (ret != Success) { if (ret == XvBadExtension) printf("XvBadExtension returned at XvQueryExtension.\n"); else if (ret == XvBadAlloc) printf("XvBadAlloc returned at XvQueryExtension.\n"); else printf("other error happened at XvQueryExtension.\n"); } printf("========================================\n"); printf("XvQueryExtension returned the following:\n"); printf("p_version : %u\n", p_version); printf("p_release : %u\n", p_release); printf("p_request_base : %u\n", p_request_base); printf("p_event_base : %u\n", p_event_base); printf("p_error_base : %u\n", p_error_base); printf("========================================\n"); ret = XvQueryAdaptors(dpy, DefaultRootWindow(dpy), &p_num_adaptors, &ai); if (ret != Success) { if (ret == XvBadExtension) printf("XvBadExtension returned at XvQueryExtension.\n"); else if (ret == XvBadAlloc) printf("XvBadAlloc returned at XvQueryExtension.\n"); else printf("other error happaned at XvQueryAdaptors.\n"); } printf("=======================================\n"); printf("XvQueryAdaptors returned the following:\n"); printf("%d adaptors available.\n", p_num_adaptors); for (i = 0; i < p_num_adaptors; i++) { printf(" name: %s\n" " type: %s%s%s%s%s\n" " ports: %ld\n" " first port: %ld\n", ai[i].name, (ai[i].type & XvInputMask) ? "input | " : "", (ai[i].type & XvOutputMask) ? "output | " : "", (ai[i].type & XvVideoMask) ? "video | " : "", (ai[i].type & XvStillMask) ? "still | " : "", (ai[i].type & XvImageMask) ? "image | " : "", ai[i].num_ports, ai[i].base_id); xv_port = ai[i].base_id; printf("adaptor %d ; format list:\n", i); for (j = 0; j < ai[i].num_formats; j++) { printf(" depth=%d, visual=%ld\n", ai[i].formats[j].depth, ai[i].formats[j].visual_id); } for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) { printf(" encoding list for port %d\n", p); if (XvQueryEncodings(dpy, p, &encodings, &ei) != Success) { printf("XvQueryEncodings failed.\n"); continue; } for (j = 0; j < encodings; j++) { printf(" id=%ld, name=%s, size=%ldx%ld, numerator=%d, denominator=%d\n", ei[j].encoding_id, ei[j].name, ei[j].width, ei[j].height, ei[j].rate.numerator, ei[j].rate.denominator); } XvFreeEncodingInfo(ei); printf(" attribute list for port %d\n", p); at = XvQueryPortAttributes(dpy, p, &attributes); for (j = 0; j < attributes; j++) { printf(" name: %s\n" " flags: %s%s\n" " min_color: %i\n" " max_color: %i\n", at[j].name, (at[j].flags & XvGettable) ? " get" : "", (at[j].flags & XvSettable) ? " set" : "", at[j].min_value, at[j].max_value); } if (at) XFree(at); printf(" image format list for port %d\n", p); fo = XvListImageFormats(dpy, p, &formats); for (j = 0; j < formats; j++) { printf(" 0x%x (%4.4s) %s\n", fo[j].id, (char *)&fo[j].id, (fo[j].format == XvPacked) ? "packed" : "planar"); } if (fo) XFree(fo); } printf("\n"); } if (p_num_adaptors > 0) XvFreeAdaptorInfo(ai); if (xv_port == -1) exit (0); gc = XCreateGC(dpy, window, 0, 0); yuv_image = XvShmCreateImage(dpy, xv_port, GUID_YUV12_PLANAR, 0, yuv_width, yuv_height, &yuv_shminfo); yuv_shminfo.shmid = shmget(IPC_PRIVATE, yuv_image->data_size, IPC_CREAT | 0777); yuv_shminfo.shmaddr = yuv_image->data = shmat(yuv_shminfo.shmid, 0, 0); yuv_shminfo.readOnly = False; if (!XShmAttach(dpy, &yuv_shminfo)) { printf("XShmAttach failed !\n"); exit (-1); } for (i = 0; i < yuv_image->height; i++) { for (j = 0; j < yuv_image->width; j++) { yuv_image->data[yuv_image->width*i + j] = i*j; } } printf("%d\n", yuv_image->data_size); int joe = 0; while (1) { frames = secsa = secsb = 0; time(&secsa); while (frames < 200) { XGetGeometry(dpy, window, &_dw, &_d, &_d, &_w, &_h, &_d, &_d); for (i = 0; i < yuv_image->height * 1.5; i++) { for (j = 0; j < yuv_image->width; j++) { yuv_image->data[yuv_image->width*i + j] = (i + j + joe / 5); } } XvShmPutImage(dpy, xv_port, window, gc, yuv_image, 0, 0, yuv_image->width, yuv_image->height, 0, 0, _w, _h, True); /* XFlush(dpy); */ joe++; frames++; } time(&secsb); printf("%ld frames in %ld seconds; %.4f fps\n", frames, secsb-secsa, (double) frames/(secsb-secsa)); } return 0; }
int main(int argc, char *argv[]) { Display *dpy; unsigned int ver, rev, eventB, reqB, errorB; int i, j, k, n; unsigned int nencode, nadaptors; int nscreens, nattr, numImages; XvAdaptorInfo *ainfo; XvAttribute *attributes; XvEncodingInfo *encodings; XvFormat *format; XvImageFormatValues *formats; char *disname = NULL; char shortmode = 0; if ((argc > 4)) PrintUsage(); if (argc != 1) { for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-display")) { disname = argv[i + 1]; i++; } else if (!strcmp(argv[i], "-short")) shortmode = 1; else if (!strcmp(argv[i], "-version")) { printf("%s\n", PACKAGE_STRING); exit(0); } else { PrintUsage(); } } } if (!(dpy = XOpenDisplay(disname))) { fprintf(stderr, "xvinfo: Unable to open display %s\n", (disname != NULL) ? disname : XDisplayName(NULL)); exit(-1); } if ((Success != XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB, &errorB))) { fprintf(stderr, "xvinfo: No X-Video Extension on %s\n", (disname != NULL) ? disname : XDisplayName(NULL)); exit(0); } else { fprintf(stdout, "X-Video Extension version %i.%i\n", ver, rev); } nscreens = ScreenCount(dpy); for (i = 0; i < nscreens; i++) { fprintf(stdout, "screen #%i\n", i); XvQueryAdaptors(dpy, RootWindow(dpy, i), &nadaptors, &ainfo); if (!nadaptors) { fprintf(stdout, " no adaptors present\n"); continue; } for (j = 0; j < nadaptors; j++) { fprintf(stdout, " Adaptor #%i: \"%s\"\n", j, ainfo[j].name); fprintf(stdout, " number of ports: %li\n", ainfo[j].num_ports); fprintf(stdout, " port base: %li\n", ainfo[j].base_id); fprintf(stdout, " operations supported: "); switch (ainfo[j].type & (XvInputMask | XvOutputMask)) { case XvInputMask: if (ainfo[j].type & XvVideoMask) fprintf(stdout, "PutVideo "); if (ainfo[j].type & XvStillMask) fprintf(stdout, "PutStill "); if (ainfo[j].type & XvImageMask) fprintf(stdout, "PutImage "); break; case XvOutputMask: if (ainfo[j].type & XvVideoMask) fprintf(stdout, "GetVideo "); if (ainfo[j].type & XvStillMask) fprintf(stdout, "GetStill "); break; default: fprintf(stdout, "none "); break; } fprintf(stdout, "\n"); format = ainfo[j].formats; if (!shortmode) { fprintf(stdout, " supported visuals:\n"); for (k = 0; k < ainfo[j].num_formats; k++, format++) { fprintf(stdout, " depth %i, visualID 0x%2lx\n", format->depth, format->visual_id); } } attributes = XvQueryPortAttributes(dpy, ainfo[j].base_id, &nattr); if (attributes && nattr) { fprintf(stdout, " number of attributes: %i\n", nattr); for (k = 0; k < nattr; k++) { fprintf(stdout, " \"%s\" (range %i to %i)\n", attributes[k].name, attributes[k].min_value, attributes[k].max_value); if (attributes[k].flags & XvSettable) { if (!shortmode) fprintf(stdout, " client settable attribute\n"); else fprintf(stdout, " settable"); } if (attributes[k].flags & XvGettable) { Atom the_atom; int value; if (!shortmode) fprintf(stdout, " client gettable attribute"); else fprintf(stdout, ", gettable"); the_atom = XInternAtom(dpy, attributes[k].name, True); if (the_atom != None) { if ((Success == XvGetPortAttribute(dpy, ainfo[j].base_id, the_atom, &value))) fprintf(stdout, " (current value is %i)", value); } fprintf(stdout, "\n"); } else if (shortmode) fprintf(stdout, "\n"); } XFree(attributes); } else { fprintf(stdout, " no port attributes defined\n"); } XvQueryEncodings(dpy, ainfo[j].base_id, &nencode, &encodings); if (encodings && nencode) { int ImageEncodings = 0; for (n = 0; n < nencode; n++) { if (!strcmp(encodings[n].name, "XV_IMAGE")) ImageEncodings++; } if (nencode - ImageEncodings) { fprintf(stdout, " number of encodings: %i\n", nencode - ImageEncodings); for (n = 0; n < nencode; n++) { if (strcmp(encodings[n].name, "XV_IMAGE")) { fprintf(stdout, " encoding ID #%li: \"%s\"\n", encodings[n].encoding_id, encodings[n].name); fprintf(stdout, " size: %li x %li\n", encodings[n].width, encodings[n].height); fprintf(stdout, " rate: %f\n", (float) encodings[n].rate.numerator / (float) encodings[n].rate.denominator); } } } if (ImageEncodings && (ainfo[j].type & XvImageMask)) { char imageName[5]; for (n = 0; n < nencode; n++) { if (!strcmp(encodings[n].name, "XV_IMAGE")) { fprintf(stdout, " maximum XvImage size: %li x %li\n", encodings[n].width, encodings[n].height); break; } } formats = XvListImageFormats(dpy, ainfo[j].base_id, &numImages); fprintf(stdout, " Number of image formats: %i\n", numImages); for (n = 0; n < numImages; n++) { sprintf(imageName, "%c%c%c%c", formats[n].id & 0xff, (formats[n].id >> 8) & 0xff, (formats[n].id >> 16) & 0xff, (formats[n].id >> 24) & 0xff); fprintf(stdout, " id: 0x%x", formats[n].id); if (isprint(imageName[0]) && isprint(imageName[1]) && isprint(imageName[2]) && isprint(imageName[3])) { fprintf(stdout, " (%s)\n", imageName); } else { fprintf(stdout, "\n"); } if (!shortmode) { fprintf(stdout, " guid: "); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[0]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[1]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[2]); fprintf(stdout, "%02x-", (unsigned char) formats[n].guid[3]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[4]); fprintf(stdout, "%02x-", (unsigned char) formats[n].guid[5]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[6]); fprintf(stdout, "%02x-", (unsigned char) formats[n].guid[7]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[8]); fprintf(stdout, "%02x-", (unsigned char) formats[n].guid[9]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[10]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[11]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[12]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[13]); fprintf(stdout, "%02x", (unsigned char) formats[n].guid[14]); fprintf(stdout, "%02x\n", (unsigned char) formats[n].guid[15]); fprintf(stdout, " bits per pixel: %i\n", formats[n].bits_per_pixel); fprintf(stdout, " number of planes: %i\n", formats[n].num_planes); fprintf(stdout, " type: %s (%s)\n", (formats[n].type == XvRGB) ? "RGB" : "YUV", (formats[n].format == XvPacked) ? "packed" : "planar"); if (formats[n].type == XvRGB) { fprintf(stdout, " depth: %i\n", formats[n].depth); fprintf(stdout, " red, green, blue masks: " "0x%x, 0x%x, 0x%x\n", formats[n].red_mask, formats[n].green_mask, formats[n].blue_mask); } else { } } } if (formats) XFree(formats); } XvFreeEncodingInfo(encodings); } }
int XvQueryEncodings( Display *dpy, XvPortID port, unsigned int *p_nEncodings, XvEncodingInfo **p_pEncodings ){ XExtDisplayInfo *info = xv_find_display(dpy); xvQueryEncodingsReq *req; xvQueryEncodingsReply rep; int size, jj; char *name; XvEncodingInfo *pes, *pe; char *buffer; union { char *buffer; char *string; xvEncodingInfo *pe; } u; XvCheckExtension(dpy, info, XvBadExtension); LockDisplay(dpy); XvGetReq(QueryEncodings, req); req->port = port; /* READ THE REPLY */ if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) { UnlockDisplay(dpy); SyncHandle(); return(XvBadReply); } size = rep.length << 2; if ( (buffer = (char *)Xmalloc ((unsigned) size)) == NULL) { UnlockDisplay(dpy); SyncHandle(); return(XvBadAlloc); } _XRead (dpy, buffer, size); u.buffer = buffer; /* GET ENCODINGS */ size = rep.num_encodings*sizeof(XvEncodingInfo); if ( (pes = (XvEncodingInfo *)Xmalloc(size)) == NULL) { Xfree(buffer); UnlockDisplay(dpy); SyncHandle(); return(XvBadAlloc); } /* INITIALIZE THE ENCODING POINTER */ pe = pes; for (jj=0; jj<rep.num_encodings; jj++) { pe->name = (char *)NULL; pe->num_encodings = 0; pe++; } pe = pes; for (jj=0; jj<rep.num_encodings; jj++) { pe->encoding_id = u.pe->encoding; pe->width = u.pe->width; pe->height = u.pe->height; pe->rate.numerator = u.pe->rate.numerator; pe->rate.denominator = u.pe->rate.denominator; pe->num_encodings = rep.num_encodings - jj; size = u.pe->name_size; u.buffer += (sz_xvEncodingInfo + 3) & ~3; if ( (name = (char *)Xmalloc(size+1)) == NULL) { XvFreeEncodingInfo(pes); Xfree(buffer); UnlockDisplay(dpy); SyncHandle(); return(XvBadAlloc); } strncpy(name, u.string, size); name[size] = '\0'; pe->name = name; pe++; u.buffer += (size + 3) & ~3; } *p_nEncodings = rep.num_encodings; *p_pEncodings = pes; Xfree(buffer); UnlockDisplay(dpy); SyncHandle(); return (Success); }