void QueryXv() { int num_adaptors; int num_formats; XvImageFormatValues *formats = NULL; int i, j; char xv_name[5]; XvQueryAdaptors(display, DefaultRootWindow(display), (unsigned int*) &num_adaptors, &info); for (i = 0; i < num_adaptors; i++) { formats = XvListImageFormats(display, info[i].base_id, &num_formats); for (j = 0; j < num_formats; j++) { xv_name[4] = 0; memcpy(xv_name, &formats[j].id, 4); if (formats[j].id == format) { if (verbose) fprintf(stderr, "using Xv format 0x%x %s %s\n", formats[j].id, xv_name, (formats[j].format == XvPacked) ? "packed" : "planar"); if (adaptor < 0) adaptor = i; } } } XFree(formats); if (adaptor < 0) fprintf(stderr, "No suitable Xv adaptor found"); }
int main(int argc, char** argv) { unsigned int count = 0; XvAdaptorInfo *adaptors = 0; XvQueryAdaptors(0, 0, &count, &adaptors); return 0; }
void QueryXv() { uint32_t num_adaptors; int num_formats; XvImageFormatValues *formats=NULL; int i,j; char xv_name[5]; XvQueryAdaptors(display,DefaultRootWindow(display),&num_adaptors,&info); for(i=0;i<num_adaptors;i++) { formats=XvListImageFormats(display,info[i].base_id,&num_formats); for(j=0;j<num_formats;j++) { xv_name[4]=0; memcpy(xv_name,&formats[j].id,4); if(formats[j].id==format) { dc1394_log_error("using Xv format 0x%x %s %s",formats[j].id,xv_name,(formats[j].format==XvPacked)?"packed":"planar"); if(adaptor<0)adaptor=i; } } } XFree(formats); if(adaptor<0) dc1394_log_error("No suitable Xv adaptor found"); }
int XvGrabber::getgrabber() { Tk_Window tk = Tcl::instance().tkmain(); Display* dpy = Tk_Display(tk); int majop, eventbase, errbase; if (XQueryExtension(dpy, "XVideo", &majop, &eventbase, &errbase) == False) return (-1); Window root = DefaultRootWindow(dpy); u_int ngrabbers=0; XvAdaptorInfo* grabbers; if (XvQueryAdaptors(dpy, root, &ngrabbers, &grabbers) != Success) return (-1); if (ngrabbers > 1) fprintf(stderr, "XVgrabber: warning: more than one frame grabber\n"); for (int i=2; i<ngrabbers; i++) { //if ((grabbers[i].type)&XvOutputMask) { if ((grabbers[i].type)&XvInputMask) { fprintf(stderr, "Xv %d grabber: %s\n",i,grabbers[i].name); strncpy(grabber_name, grabbers[i].name, sizeof(grabber_name)); grabID_ = grabbers[i].base_id; } } if (!grabID_) return (-1); XvFreeAdaptorInfo(grabbers); XvQueryEncodings(dpy, grabID_, &nencodings, &encoding); #if 1 printf("Encodings(%d): ", nencodings); for (int i=0; i<nencodings; i++) printf("%s %d %d\n", encoding[i].name, encoding[i].width, encoding[i].height); printf("\n"); #endif XAbrightness = XInternAtom(dpy, "XV_BRIGHTNESS", False); XAcontrast = XInternAtom(dpy, "XV_CONTRAST", False); XAhue = XInternAtom(dpy, "XV_HUE", False); XAsaturation = XInternAtom(dpy, "XV_SATURATION", False); XAencoding = XInternAtom(dpy, "XV_ENCODING", False); XvGetPortAttribute(dpy, grabID_, XAencoding, (int *)&encodingid_); if (!XMatchVisualInfo(dpy, Tk_ScreenNumber(tk), 24, TrueColor, &vinfo_)) return (-1); return (0); }
int main (void) { char *display_name = getenv("DISPLAY"); if (! display_name) { display_name = ":0"; } Display *display = XOpenDisplay (display_name); if (! display) { printf ("no DISPLAY\n"); abort (); } Window window = DefaultRootWindow(display); unsigned nadap; XvAdaptorInfo *padap; { int status = XvQueryAdaptors (display, window, &nadap, &padap); if (status) { printf ("XvQueryAdaptors fail\n"); abort (); } } printf ("nadap %u padap %p\n", nadap, padap); unsigned a; for (a = 0; a < nadap; a++) { padap++; unsigned i; for (i = 0; i < padap[0].num_ports; i++) { XvPortID port = padap[0].base_id + i; printf ("port %u\n", port); unsigned nenc; XvEncodingInfo *penc; { int status = XvQueryEncodings (display, port, &nenc, &penc); if (status) { printf ("XvQueryEncodings fail\n"); abort (); } } printf ("nenc %u penc %p\n", nenc, penc); } } return 0; }
bool X11Renderer::InitVideoXv() { XvAdaptorInfo *ai; uint32_t adaptors; XvPortID xvP; int ret; ret = XvQueryAdaptors(m_pDisplay, DefaultRootWindow(m_pDisplay), &adaptors, &ai); if (ret != Success) { ERROR("XvQueryAdaptors failed"); return false; } REND_DBG("adaptors: %d", adaptors); m_Port = 0; for (unsigned int i = 0; i < adaptors; i++) { REND_DBG("adaptor %d", adaptors); if ((ai[i].type & ( XvInputMask | XvImageMask)) == (XvInputMask | XvImageMask)) { for (xvP = ai[i].base_id; xvP<ai[i].base_id+ai[i].num_ports; xvP++ ) { REND_DBG("Port %d", xvP); if (XvGrabPort( m_pDisplay, xvP, CurrentTime ) == Success) { m_Port = xvP; REND_DBG("Got port %d\n", m_Port); break; } } if ( m_Port != 0 ) break; } } XvFreeAdaptorInfo(ai); if (!m_Port) { ERROR("Failed to grab port"); return false; } m_pXvImage = XvCreateImage(m_pDisplay, m_Port, GUID_I420_PLANAR, NULL, m_VPar.width, m_VPar.height); if (!m_pXvImage) { ERROR("XvCreateImage failed"); return false; } REND_DBG("Image data: 0x%x, size: %d", m_pXvImage->data, m_pXvImage->data_size); return true; }
XvPortID Yuv_window::get_xv_port() { XvPortID port = 0; unsigned int count = 0; XvAdaptorInfo* info = 0; int status = XvQueryAdaptors(QX11Info::display(), QX11Info::appRootWindow(), &count, &info); for (int i = 0; i < (int)count; i++) { printf( "\nAdapter Name : %s, Port base id: 0x%x, Num of Ports: %ld\n", info[i].name, (unsigned int)info[i].base_id, info[i].num_ports); for (int j = 0; j < (int)info[j].num_ports; j++) { port = j+info[i].base_id; status = XvGrabPort(QX11Info::display(), port, QX11Info::appUserTime()); if (status == Success) { goto exit; } } } exit: XvFreeAdaptorInfo(info); return port; }
XvPortID X11_app::get_xv_port() { XvPortID port = 0; unsigned int count = 0; XvAdaptorInfo* info = 0; int status = XvQueryAdaptors(_display, XRootWindow(_display, _screen), &count, &info); for (int i = 0; i < (int)count; i++) { printf( "\n\tAdapter Name : %s, Port base id: 0x%x, Num of Ports: %ld\n", info[i].name, (unsigned int)info[i].base_id, info[i].num_ports); for (int j = 0; j < (int)info[j].num_ports; j++) { port = j+info[i].base_id; status = XvGrabPort(_display, port, CurrentTime); if (status == Success) { goto exit; } } } exit: XvFreeAdaptorInfo(info); return port; }
//------------------------------------ // //------------------------------------ uint8_t GUI_XvInit(GUI_WindowInfo * window, uint32_t w, uint32_t h) { unsigned int ver, rel, req, ev, err; unsigned int port, adaptors; static XvAdaptorInfo *ai; static XvAdaptorInfo *curai; #if 0 win = gtk_widget_get_parent_window(window); xv_display = GDK_WINDOW_XDISPLAY(win); // xv_win= RootWindow(xv_display,0); xv_win = GDK_WINDOW_XWINDOW(GTK_WIDGET(window)->window); #endif xv_display=(Display *)window->display; xv_win=window->window; #define WDN xv_display xv_port = 0; if (Success != XvQueryExtension(WDN, &ver, &rel, &req, &ev, &err)) { printf("\n Query Extension failed\n"); goto failed; } /* check for Xvideo support */ if (Success != XvQueryAdaptors(WDN, DefaultRootWindow(WDN), &adaptors, &ai)) { printf("\n Query Adaptor failed\n"); goto failed; } curai = ai; XvFormat *formats; // Dump infos port = 0; for (uint16_t i = 0; (!port) && (i < adaptors); i++) { /* XvPortID base_id; unsigned long num_ports; char type; char *name; unsigned long num_formats; XvFormat *formats; unsigned long num_adaptors; */ #ifdef VERBOSE_XV printf("\n_______________________________\n"); printf("\n Adaptor : %d", i); printf("\n Base ID : %ld", curai->base_id); printf("\n Nb Port : %lu", curai->num_ports); printf("\n Type : %d,", curai->type); #define CHECK(x) if(curai->type & x) printf("|"#x); CHECK(XvInputMask); CHECK(XvOutputMask); CHECK(XvVideoMask); CHECK(XvStillMask); CHECK(XvImageMask); printf("\n Name : %s", curai->name); printf("\n Num Adap : %lu", curai->num_adaptors); printf("\n Num fmt : %lu", curai->num_formats); #endif formats = curai->formats; // uint16_t k; for (k = 0; (k < curai->num_ports) && !port; k++) { if (GUI_XvList(WDN, k + curai->base_id, &xv_format)) port = k + curai->base_id; } curai++; } // if (!port) { printf("\n no port found"); goto failed; } #ifdef COLORSPACE_YV12 printf("\n Xv YV12 found at port :%d, format : %ld", port, xv_format); #else printf("\n Xv YUY2 found at port :%d, format : %ld", port, xv_format); #endif if (Success != XvGrabPort(WDN, port, 0)) goto failed; { xv_port = port; /* Display *display, XvPortID port, int id, char* data, int width, int height, XShmSegmentInfo *shminfo */ XSetWindowAttributes xswa; XWindowAttributes attribs; static Atom xv_atom; unsigned long xswamask; int erCode; /* check if colorkeying is needed */ xv_atom = getAtom( "XV_AUTOPAINT_COLORKEY" ); if(xv_atom!=None) { XvSetPortAttribute( xv_display, xv_port, xv_atom, 1 ); } else printf("No autopaint \n"); /* if we have to deal with colorkeying ... */ xvimage = XvShmCreateImage(WDN, xv_port, xv_format, 0, w, h, &Shminfo); Shminfo.shmid = shmget(IPC_PRIVATE, xvimage->data_size, IPC_CREAT | 0777); if(Shminfo.shmid<=0) { printf("shmget failed\n"); } Shminfo.shmaddr = (char *) shmat(Shminfo.shmid, 0, 0); Shminfo.readOnly = False; if(Shminfo.shmaddr==(char *)-1) { printf("Shmat failed\n"); } xvimage->data = Shminfo.shmaddr; XShmAttach(WDN, &Shminfo); XSync(WDN, False); erCode=shmctl(Shminfo.shmid, IPC_RMID, 0); if(erCode) { printf("Shmctl failed :%d\n",erCode); } memset(xvimage->data, 0, xvimage->data_size); xv_xgc.graphics_exposures = False; xv_gc = XCreateGC(xv_display, xv_win, 0L, &xv_xgc); //ADM_assert(BadWindow!=XSelectInput(xv_display, xv_win, ExposureMask | VisibilityChangeMask)); } printf("\n Xv init succeedeed\n"); return 1; failed: printf("\n Xv init failed..\n"); return 0; }
bool QX11VideoSurface::findPort() { unsigned int count = 0; XvAdaptorInfo *adaptors = 0; bool portFound = false; if (XvQueryAdaptors(QX11Info::display(), m_winId, &count, &adaptors) == Success) { #ifdef Q_WS_MAEMO_5 //the overlay xvideo adapter fails to switch winId, //prefer the "SGX Textured Video" adapter instead for (int i = count-1; i >= 0 && !portFound; --i) { #else for (unsigned int i = 0; i < count && !portFound; ++i) { #endif if (adaptors[i].type & XvImageMask) { m_portId = adaptors[i].base_id; for (unsigned int j = 0; j < adaptors[i].num_ports && !portFound; ++j, ++m_portId) portFound = XvGrabPort(QX11Info::display(), m_portId, 0) == Success; } } XvFreeAdaptorInfo(adaptors); } return portFound; } void QX11VideoSurface::querySupportedFormats() { int count = 0; if (XvImageFormatValues *imageFormats = XvListImageFormats( QX11Info::display(), m_portId, &count)) { const int rgbCount = sizeof(qt_xvRgbLookup) / sizeof(XvFormatRgb); const int yuvCount = sizeof(qt_xvYuvLookup) / sizeof(XvFormatYuv); for (int i = 0; i < count; ++i) { switch (imageFormats[i].type) { case XvRGB: for (int j = 0; j < rgbCount; ++j) { if (imageFormats[i] == qt_xvRgbLookup[j]) { m_supportedPixelFormats.append(qt_xvRgbLookup[j].pixelFormat); m_formatIds.append(imageFormats[i].id); break; } } break; case XvYUV: for (int j = 0; j < yuvCount; ++j) { if (imageFormats[i] == qt_xvYuvLookup[j]) { m_supportedPixelFormats.append(qt_xvYuvLookup[j].pixelFormat); m_formatIds.append(imageFormats[i].id); break; } } break; } } XFree(imageFormats); } m_brightnessRange = qMakePair(0, 0); m_contrastRange = qMakePair(0, 0); m_hueRange = qMakePair(0, 0); m_saturationRange = qMakePair(0, 0); if (XvAttribute *attributes = XvQueryPortAttributes(QX11Info::display(), m_portId, &count)) { for (int i = 0; i < count; ++i) { if (qstrcmp(attributes[i].name, "XV_BRIGHTNESS") == 0) m_brightnessRange = qMakePair(attributes[i].min_value, attributes[i].max_value); else if (qstrcmp(attributes[i].name, "XV_CONTRAST") == 0) m_contrastRange = qMakePair(attributes[i].min_value, attributes[i].max_value); else if (qstrcmp(attributes[i].name, "XV_HUE") == 0) m_hueRange = qMakePair(attributes[i].min_value, attributes[i].max_value); else if (qstrcmp(attributes[i].name, "XV_SATURATION") == 0) m_saturationRange = qMakePair(attributes[i].min_value, attributes[i].max_value); } XFree(attributes); } }
static int X11_GetXVideoPort(GF_VideoOutput *vout, u32 pixel_format, Bool check_color) { XWindow *xwin = (XWindow *)vout->opaque; Bool has_color_key = 0; XvAdaptorInfo *adaptors; unsigned int i; unsigned int nb_adaptors; int selected_port; if (XvQueryExtension(xwin->display, &i, &i, &i, &i, &i ) != Success) return -1; if (XvQueryAdaptors(xwin->display, DefaultRootWindow(xwin->display), &nb_adaptors, &adaptors) != Success) return -1; selected_port = -1; for (i=0; i < nb_adaptors; i++) { XvImageFormatValues *formats; int j, num_formats, port; if( !( adaptors[i].type & XvInputMask ) || !(adaptors[i].type & XvImageMask ) ) continue; /* Check for our format... */ formats = XvListImageFormats(xwin->display, adaptors[i].base_id, &num_formats); for (j=0; j<num_formats && (selected_port == -1 ); j++) { XvAttribute *attr; int k, nb_attributes; u32 pformat = X11_GetPixelFormat(formats[j].id); if( !is_same_yuv(pformat, pixel_format) ) continue; /* Grab first port supporting this format */ for (port=adaptors[i].base_id; (port < (int)(adaptors[i].base_id + adaptors[i].num_ports) ) && (selected_port == -1); port++) { if (port==xwin->xvport) continue; attr = XvQueryPortAttributes(xwin->display, port, &nb_attributes); for (k=0; k<nb_attributes; k++ ) { if (!strcmp(attr[k].name, "XV_COLORKEY")) { const Atom ckey = XInternAtom(xwin->display, "XV_COLORKEY", False); XvGetPortAttribute(xwin->display, port, ckey, &vout->overlay_color_key); has_color_key = 1; vout->overlay_color_key |= 0xFF000000; } /* else if (!strcmp(attr[k].name, "XV_AUTOPAINT_COLORKEY")) { const Atom paint = XInternAtom(xwin->display, "XV_AUTOPAINT_COLORKEY", False); XvSetPortAttribute(xwin->display, port, paint, 1); } */ } if (check_color && !has_color_key) continue; if (XvGrabPort(xwin->display, port, CurrentTime) == Success) { selected_port = port; xwin->xv_pf_format = formats[j].id; } } if (selected_port == -1 ) continue; } if (formats != NULL) XFree(formats); } if (nb_adaptors > 0) XvFreeAdaptorInfo(adaptors); return selected_port; }
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; }
static Status Validate(Display *dpy, XvPortID port, int surface_type_id, unsigned int width, unsigned int height, int flags, bool *found_port, int *screen, int *chroma_format, int *mc_type, int *surface_flags, unsigned short *subpic_max_w, unsigned short *subpic_max_h) { bool found_surface = false; XvAdaptorInfo *adaptor_info; unsigned int num_adaptors; int num_types; unsigned int max_width = 0, max_height = 0; Status ret; assert(dpy); assert(found_port); assert(screen); assert(chroma_format); assert(mc_type); assert(surface_flags); assert(subpic_max_w); assert(subpic_max_h); *found_port = false; for (int i = 0; i < XScreenCount(dpy); ++i) { ret = XvQueryAdaptors(dpy, XRootWindow(dpy, i), &num_adaptors, &adaptor_info); if (ret != Success) return ret; for (unsigned int j = 0; j < num_adaptors && !*found_port; ++j) { for (unsigned int k = 0; k < adaptor_info[j].num_ports && !*found_port; ++k) { XvMCSurfaceInfo *surface_info; if (adaptor_info[j].base_id + k != port) continue; *found_port = true; surface_info = XvMCListSurfaceTypes(dpy, adaptor_info[j].base_id, &num_types); if (!surface_info) { XvFreeAdaptorInfo(adaptor_info); return BadAlloc; } for (int l = 0; l < num_types && !found_surface; ++l) { if (surface_info[l].surface_type_id != surface_type_id) continue; found_surface = true; max_width = surface_info[l].max_width; max_height = surface_info[l].max_height; *chroma_format = surface_info[l].chroma_format; *mc_type = surface_info[l].mc_type; *surface_flags = surface_info[l].flags; *subpic_max_w = surface_info[l].subpicture_max_width; *subpic_max_h = surface_info[l].subpicture_max_height; *screen = i; XVMC_MSG(XVMC_TRACE, "[XvMC] Found requested context surface format.\n" \ "[XvMC] screen=%u, port=%u\n" \ "[XvMC] id=0x%08X\n" \ "[XvMC] max width=%u, max height=%u\n" \ "[XvMC] chroma format=0x%08X\n" \ "[XvMC] acceleration level=0x%08X\n" \ "[XvMC] flags=0x%08X\n" \ "[XvMC] subpicture max width=%u, max height=%u\n", i, port, surface_type_id, max_width, max_height, *chroma_format, *mc_type, *surface_flags, *subpic_max_w, *subpic_max_h); } free(surface_info); } } XvFreeAdaptorInfo(adaptor_info); } if (!*found_port) { XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable port.\n"); return XvBadPort; } if (!found_surface) { XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable surface.\n"); return BadMatch; } if (width > max_width || height > max_height) { XVMC_MSG(XVMC_ERR, "[XvMC] Requested context dimensions (w=%u,h=%u) too large (max w=%u,h=%u).\n", width, height, max_width, max_height); return BadValue; } if (flags != XVMC_DIRECT && flags != 0) { XVMC_MSG(XVMC_ERR, "[XvMC] Invalid context flags 0x%08X.\n", flags); return BadValue; } return Success; }
static Bool GetPortId(Display *dpy, XvPortID *portID, int *surface_type) { int i, j, k, numAdapt, numTypes, eventBase, errorBase; XvMCSurfaceInfo *surfaceInfo; XvAdaptorInfo *info; Bool result = 0; if(!XvMCQueryExtension(dpy, &eventBase, &errorBase)) return 0; if(Success != XvQueryAdaptors(dpy,DefaultRootWindow(dpy),&numAdapt,&info)) return 0; for(i = 0; i < numAdapt; i++) { if(info[i].type & XvImageMask) { surfaceInfo = XvMCListSurfaceTypes(display, info[i].base_id, &numTypes); if(surfaceInfo) { for(j = 0; j < numTypes; j++) { if((surfaceInfo[j].chroma_format == XVMC_CHROMA_FORMAT_420) && (surfaceInfo[j].max_width >= coded_picture_width) && (surfaceInfo[j].max_height >= coded_picture_height) && ((surfaceInfo[j].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)) || (surfaceInfo[j].mc_type == (XVMC_IDCT | XVMC_MPEG_2)))) { if(use_idct != -1) { if(use_idct == 1) { if(surfaceInfo[j].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)) continue; } else { if(surfaceInfo[j].mc_type == (XVMC_IDCT | XVMC_MPEG_2)) continue; } } for(k = 0; k < info[i].num_ports; k++) { /* try to grab a port */ if(Success == XvGrabPort(dpy, info[i].base_id + k, CurrentTime)) { *portID = info[i].base_id + k; *surface_type = surfaceInfo[j].surface_type_id; result = 1; break; } } if(result) { if(surfaceInfo[j].flags & XVMC_INTRA_UNSIGNED) unsignedIntra = 1; if(surfaceInfo[j].mc_type == (XVMC_IDCT | XVMC_MPEG_2)) useIDCT = 1; break; } } } XFree(surfaceInfo); } } } XvFreeAdaptorInfo(info); return result; }
int XVWindow::init(Display* dp, Window rootWindow, int x, int y, int windowWidth, int windowHeight, int imageWidth, int imageHeight) { // local variables needed for creation of window and initialization of XV extension unsigned int i; unsigned int ver, rel, req, ev, err, adapt; XSetWindowAttributes xswattributes; XWindowAttributes xwattributes; XVisualInfo xvinfo; XvAdaptorInfo *xvainfo; unsigned int candidateXVPort=0; unsigned int busyPorts=0; _display=dp; _rootWindow=rootWindow; _state.origLayer=0; // initialize atoms WM_DELETE_WINDOW = XInternAtom(_display, "WM_DELETE_WINDOW", False); XA_WIN_PROTOCOLS = XInternAtom(_display, "_WIN_PROTOCOLS", False); XA_NET_SUPPORTED = XInternAtom(_display, "_NET_SUPPORTED", False); XA_NET_WM_STATE = XInternAtom(_display, "_NET_WM_STATE", False); XA_NET_WM_STATE_FULLSCREEN = XInternAtom(_display, "_NET_WM_STATE_FULLSCREEN", False); XA_NET_WM_STATE_ABOVE = XInternAtom(_display, "_NET_WM_STATE_ABOVE", False); XA_NET_WM_STATE_STAYS_ON_TOP = XInternAtom(_display, "_NET_WM_STATE_STAYS_ON_TOP", False); XA_NET_WM_STATE_BELOW = XInternAtom(_display, "_NET_WM_STATE_BELOW", False); XGetWindowAttributes(_display, _rootWindow, &xwattributes); XMatchVisualInfo(_display, DefaultScreen(_display), xwattributes.depth, TrueColor, &xvinfo); // define window properties and create the window xswattributes.colormap = XCreateColormap(_display, _rootWindow, xvinfo.visual, AllocNone); xswattributes.event_mask = StructureNotifyMask | ExposureMask; xswattributes.background_pixel = 0; xswattributes.border_pixel = 0; _XVWindow = XCreateWindow(_display, _rootWindow, x, y, windowWidth, windowHeight, 0, xvinfo.depth, InputOutput, xvinfo.visual, CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &xswattributes); // define inputs events XSelectInput(_display, _XVWindow, StructureNotifyMask | KeyPressMask | ButtonPressMask); setSizeHints(DEFAULT_X,DEFAULT_Y, imageWidth, imageHeight, windowWidth, windowHeight); // map the window XMapWindow(_display, _XVWindow); XSetWMProtocols(_display, _XVWindow, &WM_DELETE_WINDOW,1); // check if SHM XV window is possible if (Success != XvQueryExtension(_display, &ver, &rel, &req, &ev, &err)) { LOG_DEBUG("[x11] XQueryExtension failed"); return 0; } if (!XShmQueryExtension(_display)) { LOG_DEBUG("[x11] XQueryShmExtension failed"); return 0; } if (Success != XvQueryAdaptors(_display, _rootWindow, &adapt, &xvainfo)) { LOG_DEBUG("[x11] XQueryAdaptor failed"); XFree(xvainfo); return 0; } // look for a usable XV port for (i = 0; i < adapt && _XVPort == 0; i++) { if ((xvainfo[i].type & XvInputMask) && (xvainfo[i].type & XvImageMask)) { for (candidateXVPort = xvainfo[i].base_id; candidateXVPort < xvainfo[i].base_id + xvainfo[i].num_ports; ++candidateXVPort) if (!XvGrabPort(_display, candidateXVPort, CurrentTime)) { _XVPort = candidateXVPort; break; } else { LOG_DEBUG("[x11] Could not grab port: " + String::fromNumber(candidateXVPort)); ++busyPorts; } } } XvFreeAdaptorInfo(xvainfo); if (!_XVPort) { if (busyPorts) { LOG_WARN("[x11] Could not find free Xvideo port - maybe another process is already using it."); } else { LOG_WARN("[x11] It seems there is no Xvideo support for your video card available."); } return 0; } else { LOG_WARN("[x11] Use XVideo port: " + String::fromNumber(_XVPort)); } _gc = XCreateGC(_display, _XVWindow, 0, 0); // create the shared memory portion _XVImage = XvShmCreateImage(_display, _XVPort, GUID_I420_PLANAR, 0, imageWidth, imageHeight, &_XShmInfo); _XShmInfo.shmid = shmget(IPC_PRIVATE, _XVImage->data_size, IPC_CREAT | 0777); _XShmInfo.shmaddr = (char *) shmat(_XShmInfo.shmid, 0, 0); _XVImage->data = _XShmInfo.shmaddr; _XShmInfo.readOnly = False; if (!XShmAttach(_display, &_XShmInfo)) { LOG_WARN("[x11] XShmAttach failed"); return 0; } else { _isInitialized = true; } // detect the window manager type _wmType=getWMType(); return 1; }
static void x11video_prepare(MSFilter *f){ X11Video *s=(X11Video*)f->data; unsigned int n; unsigned int nadaptors; int i; XvAdaptorInfo *xai=NULL; XvPortID port=-1; int imgfmt_id=0; XShmSegmentInfo *shminfo=&s->shminfo; XWindowAttributes wa = {0}; if (s->display==NULL) return; if (s->window_id==0){ if(s->auto_window) { s->window_id=createX11Window(s); } if (s->window_id==0) return; s->own_window=TRUE; } /* Make sure X11 window is ready to use*/ XSync(s->display, False); if (s->own_window==FALSE){ /*we need to register for resize events*/ XSelectInput(s->display,s->window_id,StructureNotifyMask); } XGetWindowAttributes(s->display,s->window_id,&wa); XClearWindow(s->display,s->window_id); ms_message("x11video_prepare(): Window has size %ix%i, received video is %ix%i",wa.width,wa.height,s->vsize.width,s->vsize.height); if (wa.width<MS_LAYOUT_MIN_SIZE || wa.height<MS_LAYOUT_MIN_SIZE){ return; } s->wsize.width=wa.width; s->wsize.height=wa.height; s->fbuf.w=s->vsize.width; s->fbuf.h=s->vsize.height; s->port=-1; if (XvQueryExtension(s->display, &n, &n, &n, &n, &n)!=0){ ms_error("Fail to query xv extension"); return; } if (XShmQueryExtension(s->display)==0){ ms_error("Fail to query xshm extension"); return; } if (XvQueryAdaptors(s->display,DefaultRootWindow(s->display), &nadaptors, &xai)!=0){ ms_error("XvQueryAdaptors failed."); return; } for (n=0;n<nadaptors && port==-1;++n){ XvAdaptorInfo *ai=&xai[n]; XvImageFormatValues *imgfmt; int nimgfmt=0; ms_message("Found output adaptor; name=%s num_ports=%i, with %i formats:", ai->name,(int)ai->num_ports,(int)ai->num_formats); imgfmt=XvListImageFormats(s->display,ai->base_id,&nimgfmt); for(i=0;i<nimgfmt;++i){ char fcc[5]={0}; memcpy(fcc,&imgfmt[i].id,4); ms_message("type=%s/%s id=%s", imgfmt[i].type == XvYUV ? "YUV" : "RGB", imgfmt[i].format==XvPlanar ? "Planar" : "Packed",fcc); if (port==-1 && imgfmt[i].format==XvPlanar && strcasecmp(fcc,"YV12")==0){ int k; /*we found a format interesting to us*/ for(k=0;k<ai->num_ports;++k){ if (XvGrabPort(s->display,ai->base_id+k,CurrentTime)==0){ ms_message("Grabbed port %i",(int)ai->base_id+k); port=ai->base_id+k; imgfmt_id=imgfmt[i].id; break; } } } } if (imgfmt) XFree(imgfmt); } XvFreeAdaptorInfo(xai); if (port==-1){ ms_error("Could not find suitable format or Xv port to work with."); return; } s->port=port; /*create the shared memory XvImage*/ memset(shminfo,0,sizeof(*shminfo)); s->xv_image=XvShmCreateImage(s->display,s->port,imgfmt_id,NULL,s->fbuf.w,s->fbuf.h,shminfo); if (s->xv_image==NULL){ ms_error("XvShmCreateImage failed."); x11video_unprepare(f); return; } /*allocate some shared memory to receive the pixel data */ shminfo->shmid=shmget(IPC_PRIVATE, s->xv_image->data_size,IPC_CREAT | 0777); if (shminfo->shmid==-1){ ms_error("Could not allocate %i bytes of shared memory: %s", s->xv_image->data_size, strerror(errno)); x11video_unprepare(f); return; } shminfo->shmaddr=shmat(shminfo->shmid,NULL,0); if (shminfo->shmaddr==(void*)-1){ ms_error("shmat() failed: %s",strerror(errno)); shminfo->shmaddr=NULL; x11video_unprepare(f); return; } /*ask the x-server to attach this shared memory segment*/ x11_error=FALSE; if (!XShmAttach(s->display,shminfo)){ ms_error("XShmAttach failed !"); x11video_unprepare(f); return ; } s->xv_image->data=s->shminfo.shmaddr; s->fbuf.planes[0]=(void*)s->xv_image->data; s->fbuf.planes[2]=s->fbuf.planes[0]+(s->xv_image->height*s->xv_image->pitches[0]); s->fbuf.planes[1]=s->fbuf.planes[2]+((s->xv_image->height/2)*s->xv_image->pitches[1]); s->fbuf.strides[0]=s->xv_image->pitches[0]; s->fbuf.strides[2]=s->xv_image->pitches[1]; s->fbuf.strides[1]=s->xv_image->pitches[2]; /* set picture black */ x11video_fill_background(f); /*Create a GC*/ s->gc=XCreateGC(s->display,s->window_id,0,NULL); if (s->gc==NULL){ ms_error("XCreateGC() failed."); x11video_unprepare(f); return ; } s->ready=TRUE; }
int find_yuv_port(Display* display, XvPortID* port, fourcc_t* format, int *overlay) { int i, j, k, found_one = 0, is_overlay; /* XvQueryExtension */ unsigned int version, release, request_base, event_base, error_base; /* XvQueryAdaptors */ unsigned int num_adaptors; XvAdaptorInfo* adaptor_info = NULL; XvPortID port_id; /* XvListImageFormats */ int num_formats; XvImageFormatValues* format_list = NULL; switch (XvQueryExtension(display, &version, &release, &request_base, &event_base, &error_base)) { case Success: break; case XvBadExtension: printf("XvQueryExtension returned XvBadExtension.\n"); return 0; case XvBadAlloc: printf("XvQueryExtension returned XvBadAlloc.\n"); return 0; default: printf("XvQueryExtension returned unknown error.\n"); return 0; } switch (XvQueryAdaptors(display, DefaultRootWindow(display), &num_adaptors, &adaptor_info)) { case Success: break; case XvBadExtension: printf("XvQueryAdaptors returned XvBadExtension.\n"); return 0; case XvBadAlloc: printf("XvQueryAdaptors returned XvBadAlloc.\n"); return 0; default: printf("XvQueryAdaptors returned unknown error.\n"); return 0; } /* Find YUV capable adaptor. */ for (i = 0; i < (int)num_adaptors; i++) { if (!(adaptor_info[i].type & XvInputMask && adaptor_info[i].type & XvImageMask)) { continue; } /* Textured video is not an overlay */ is_overlay = !strstr(adaptor_info[i].name, "Textured"); format_list = XvListImageFormats(display, adaptor_info[i].base_id, &num_formats); for (j = 0; j < (int)(sizeof(fourcc_list) / sizeof(*fourcc_list)); j++) { if (format->id && fourcc_list[j].id != format->id) { continue; } for (k = 0; k < num_formats; k++) { if (format_list[k].id != fourcc_list[j].id) { continue; } for (port_id = adaptor_info[i].base_id; port_id < adaptor_info[i].base_id + adaptor_info[i].num_ports; port_id++) { if (XvGrabPort(display, port_id, CurrentTime) != Success) { continue; } if (found_one) { if (!*overlay && is_overlay) { XvUngrabPort(display, port_id, CurrentTime); continue; /* Prefer non-overlay as that one can handle more than one windows */ } XvUngrabPort(display, *port, CurrentTime); } *port = port_id; *format = fourcc_list[j]; *overlay = is_overlay; found_one = 1; } } } XFree(format_list); } XvFreeAdaptorInfo(adaptor_info); if (!found_one) { printf("No suitable Xv YUV adaptor/port available.\n"); } return found_one; }
int S9xXVDisplayDriver::init (void) { int padding; int depth = 0, num_formats, num_attrs, highest_formats = 0; XvImageFormatValues *formats = NULL; XvAdaptorInfo *adaptors; XvAttribute *port_attr; VisualID visualid = None; unsigned int num_adaptors; GdkScreen *screen; GdkWindow *root; buffer[0] = malloc (image_padded_size); buffer[1] = malloc (scaled_padded_size); padding = (image_padded_size - image_size) / 2; padded_buffer[0] = (void *) (((uint8 *) buffer[0]) + padding); padding = (scaled_padded_size - scaled_size) / 2; padded_buffer[1] = (void *) (((uint8 *) buffer[1]) + padding); memset (buffer[0], 0, image_padded_size); memset (buffer[1], 0, scaled_padded_size); /* Setup XV */ gtk_widget_realize (drawing_area); display = gdk_x11_drawable_get_xdisplay (GDK_DRAWABLE (gtk_widget_get_window (drawing_area))); screen = gtk_widget_get_screen (drawing_area); root = gdk_screen_get_root_window (screen); xv_portid = -1; XvQueryAdaptors (display, GDK_WINDOW_XWINDOW (root), &num_adaptors, &adaptors); for (int i = 0; i < (int) num_adaptors; i++) { if (adaptors[i].type & XvInputMask && adaptors[i].type & XvImageMask) { formats = XvListImageFormats (display, adaptors[i].base_id, &num_formats); if (num_formats > highest_formats) { xv_portid = adaptors[i].base_id; highest_formats = num_formats; visualid = adaptors[i].formats->visual_id; } free (formats); } } XvFreeAdaptorInfo (adaptors); if (xv_portid < 0) { fprintf (stderr, "Could not open Xv output port.\n"); return -1; } /* Set XV_AUTOPAINT_COLORKEY _only_ if available */ port_attr = XvQueryPortAttributes (display, xv_portid, &num_attrs); for (int i = 0; i < num_attrs; i++) { if (!strcmp (port_attr[i].name, "XV_AUTOPAINT_COLORKEY")) { Atom colorkey = None; colorkey = XInternAtom (display, "XV_AUTOPAINT_COLORKEY", True); if (colorkey != None) XvSetPortAttribute (display, xv_portid, colorkey, 1); } } /* Try to find an RGB format */ format = FOURCC_YUY2; bpp = 100; formats = XvListImageFormats (display, xv_portid, &num_formats); for (int i = 0; i < num_formats; i++) { if (formats[i].id == 0x3 || formats[i].type == XvRGB) { if (formats[i].bits_per_pixel < bpp) { format = formats[i].id; bpp = formats[i].bits_per_pixel; bytes_per_pixel = (bpp == 15) ? 2 : bpp >> 3; depth = formats[i].depth; this->rshift = get_inv_shift (formats[i].red_mask, bpp); this->gshift = get_inv_shift (formats[i].green_mask, bpp); this->bshift = get_inv_shift (formats[i].blue_mask, bpp); /* Check for red-blue inversion on SiliconMotion drivers */ if (formats[i].red_mask == 0x001f && formats[i].blue_mask == 0x7c00) { int copy = this->rshift; this->rshift = this->bshift; this->bshift = copy; } /* on big-endian Xv still seems to like LSB order */ if (config->force_inverted_byte_order) S9xSetEndianess (ENDIAN_MSB); else S9xSetEndianess (ENDIAN_LSB); } } }
int find_yuv_port(Display* display, XvPortID* port, fourcc_t* format) { int i, j, k; /* XvQueryExtension */ unsigned int version, release, request_base, event_base, error_base; /* XvQueryAdaptors */ unsigned int num_adaptors; XvAdaptorInfo* adaptor_info = NULL; XvPortID port_id; /* XvListImageFormats */ int num_formats; XvImageFormatValues* format_list = NULL; switch (XvQueryExtension(display, &version, &release, &request_base, &event_base, &error_base)) { case Success: break; case XvBadExtension: printf("XvQueryExtension returned XvBadExtension.\n"); return 0; case XvBadAlloc: printf("XvQueryExtension returned XvBadAlloc.\n"); return 0; default: printf("XvQueryExtension returned unknown error.\n"); return 0; } switch (XvQueryAdaptors(display, DefaultRootWindow(display), &num_adaptors, &adaptor_info)) { case Success: break; case XvBadExtension: printf("XvQueryAdaptors returned XvBadExtension.\n"); return 0; case XvBadAlloc: printf("XvQueryAdaptors returned XvBadAlloc.\n"); return 0; default: printf("XvQueryAdaptors returned unknown error.\n"); return 0; } /* Find YUV capable adaptor. */ for (i = 0; i < (int)num_adaptors; i++) { if (!(adaptor_info[i].type & XvInputMask && adaptor_info[i].type & XvImageMask)) { continue; } format_list = XvListImageFormats(display, adaptor_info[i].base_id, &num_formats); for (j = 0; j < (int)(sizeof(fourcc_list) / sizeof(*fourcc_list)); j++) { if (format->id && fourcc_list[j].id != format->id) { continue; } for (k = 0; k < num_formats; k++) { if (format_list[k].id != fourcc_list[j].id) { continue; } for (port_id = adaptor_info[i].base_id; port_id < adaptor_info[i].base_id + adaptor_info[i].num_ports; port_id++) { if (XvGrabPort(display, port_id, CurrentTime) != Success) { continue; } *port = port_id; *format = fourcc_list[j]; XFree(format_list); XvFreeAdaptorInfo(adaptor_info); return 1; } } } XFree(format_list); } XvFreeAdaptorInfo(adaptor_info); printf("No suitable Xv YUV adaptor/port available.\n"); return 0; }
static void gst_v4l2_xoverlay_open (GstV4l2Object * v4l2object) { struct stat s; GstV4l2Xv *v4l2xv; const gchar *name = g_getenv ("DISPLAY"); unsigned int ver, rel, req, ev, err, anum; int i, id = 0, first_id = 0, min; XvAdaptorInfo *ai; Display *dpy; /* we need a display, obviously */ if (!name || !(dpy = XOpenDisplay (name))) { GST_WARNING_OBJECT (v4l2object->element, "No $DISPLAY set or failed to open - no overlay"); return; } /* First let's check that XVideo extension is available */ if (!XQueryExtension (dpy, "XVideo", &i, &i, &i)) { GST_WARNING_OBJECT (v4l2object->element, "Xv extension not available - no overlay"); XCloseDisplay (dpy); return; } /* find port that belongs to this device */ if (XvQueryExtension (dpy, &ver, &rel, &req, &ev, &err) != Success) { GST_WARNING_OBJECT (v4l2object->element, "Xv extension not supported - no overlay"); XCloseDisplay (dpy); return; } if (XvQueryAdaptors (dpy, DefaultRootWindow (dpy), &anum, &ai) != Success) { GST_WARNING_OBJECT (v4l2object->element, "Failed to query Xv adaptors"); XCloseDisplay (dpy); return; } if (fstat (v4l2object->video_fd, &s) < 0) { GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Cannot identify device '%s'."), v4l2object->videodev), GST_ERROR_SYSTEM); XCloseDisplay (dpy); return; } min = s.st_rdev & 0xff; for (i = 0; i < anum; i++) { if (!strcmp (ai[i].name, "video4linux2")) { if (first_id == 0) first_id = ai[i].base_id; /* hmm... */ if (first_id != 0 && ai[i].base_id == first_id + min) id = ai[i].base_id; } } XvFreeAdaptorInfo (ai); if (id == 0) { GST_WARNING_OBJECT (v4l2object->element, "Did not find XvPortID for device - no overlay"); XCloseDisplay (dpy); return; } v4l2xv = g_new0 (GstV4l2Xv, 1); v4l2xv->dpy = dpy; v4l2xv->port = id; v4l2xv->mutex = g_mutex_new (); v4l2xv->idle_id = 0; v4l2object->xv = v4l2xv; if (v4l2object->xwindow_id) { gst_v4l2_xoverlay_set_xwindow_id (v4l2object, v4l2object->xwindow_id); } }
/** The initialization function * This function opens the frame buffer device and allocates memory for display * also it finds the frame buffer supported display formats */ OMX_ERRORTYPE omx_xvideo_sink_component_Init(OMX_COMPONENTTYPE *openmaxStandComp) { omx_xvideo_sink_component_PrivateType* omx_xvideo_sink_component_Private = openmaxStandComp->pComponentPrivate; omx_xvideo_sink_component_PortType* pPort = (omx_xvideo_sink_component_PortType *) omx_xvideo_sink_component_Private->ports[OMX_BASE_SINK_INPUTPORT_INDEX]; int yuv_width = pPort->sPortParam.format.video.nFrameWidth; int yuv_height = pPort->sPortParam.format.video.nFrameHeight; unsigned int err,i; omx_xvideo_sink_component_Private->dpy = XOpenDisplay(NULL); omx_xvideo_sink_component_Private->screen = DefaultScreen(omx_xvideo_sink_component_Private->dpy); XGetWindowAttributes(omx_xvideo_sink_component_Private->dpy, DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), &omx_xvideo_sink_component_Private->attribs); XMatchVisualInfo(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->screen, omx_xvideo_sink_component_Private->attribs.depth, TrueColor, & omx_xvideo_sink_component_Private->vinfo); omx_xvideo_sink_component_Private->wmDeleteWindow = XInternAtom(omx_xvideo_sink_component_Private->dpy, "WM_DELETE_WINDOW", False); omx_xvideo_sink_component_Private->hint.x = 1; omx_xvideo_sink_component_Private->hint.y = 1; omx_xvideo_sink_component_Private->hint.width = yuv_width; omx_xvideo_sink_component_Private->hint.height = yuv_height; omx_xvideo_sink_component_Private->hint.flags = PPosition | PSize; omx_xvideo_sink_component_Private->xswa.colormap = XCreateColormap(omx_xvideo_sink_component_Private->dpy, DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), omx_xvideo_sink_component_Private->vinfo.visual, AllocNone); omx_xvideo_sink_component_Private->xswa.event_mask = StructureNotifyMask | ExposureMask; omx_xvideo_sink_component_Private->xswa.background_pixel = 0; omx_xvideo_sink_component_Private->xswa.border_pixel = 0; omx_xvideo_sink_component_Private->window = XCreateWindow(omx_xvideo_sink_component_Private->dpy, DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), 0, 0, yuv_width, yuv_height, 0, omx_xvideo_sink_component_Private->vinfo.depth, InputOutput, omx_xvideo_sink_component_Private->vinfo.visual, CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &omx_xvideo_sink_component_Private->xswa); XSelectInput(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, StructureNotifyMask); XSetStandardProperties(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, "xvcam", "xvcam", None, NULL, 0, &omx_xvideo_sink_component_Private->hint); XSetWMProtocols(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, &omx_xvideo_sink_component_Private->wmDeleteWindow, 1); XMapWindow(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window); if (XShmQueryExtension(omx_xvideo_sink_component_Private->dpy)) omx_xvideo_sink_component_Private->CompletionType = XShmGetEventBase(omx_xvideo_sink_component_Private->dpy) + ShmCompletion; else return OMX_ErrorUndefined; if (Success != XvQueryExtension(omx_xvideo_sink_component_Private->dpy, &omx_xvideo_sink_component_Private->ver, &omx_xvideo_sink_component_Private->rel, &omx_xvideo_sink_component_Private->req, &omx_xvideo_sink_component_Private->ev, &err)) fprintf(stderr, "Couldn't do Xv stuff\n"); if (Success != XvQueryAdaptors(omx_xvideo_sink_component_Private->dpy, DefaultRootWindow(omx_xvideo_sink_component_Private->dpy), &omx_xvideo_sink_component_Private->adapt, &omx_xvideo_sink_component_Private->ai)) fprintf(stderr, "Couldn't do Xv stuff\n"); for (i = 0; i < (int) omx_xvideo_sink_component_Private->adapt; i++) { omx_xvideo_sink_component_Private->xv_port = omx_xvideo_sink_component_Private->ai[i].base_id; } if (omx_xvideo_sink_component_Private->adapt > 0) XvFreeAdaptorInfo(omx_xvideo_sink_component_Private->ai); omx_xvideo_sink_component_Private->gc = XCreateGC(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->window, 0, 0); omx_xvideo_sink_component_Private->yuv_image = XvShmCreateImage(omx_xvideo_sink_component_Private->dpy, omx_xvideo_sink_component_Private->xv_port, GUID_I420_PLANAR, 0, yuv_width, yuv_height, &omx_xvideo_sink_component_Private->yuv_shminfo); omx_xvideo_sink_component_Private->yuv_shminfo.shmid = shmget(IPC_PRIVATE, omx_xvideo_sink_component_Private->yuv_image->data_size, IPC_CREAT | 0777); omx_xvideo_sink_component_Private->yuv_shminfo.shmaddr = (char *) shmat(omx_xvideo_sink_component_Private->yuv_shminfo.shmid, 0, 0); omx_xvideo_sink_component_Private->yuv_image->data = omx_xvideo_sink_component_Private->yuv_shminfo.shmaddr; omx_xvideo_sink_component_Private->yuv_shminfo.readOnly = False; if (!XShmAttach(omx_xvideo_sink_component_Private->dpy, &omx_xvideo_sink_component_Private->yuv_shminfo)) { printf("XShmAttach go boom boom!\n"); return OMX_ErrorUndefined; } omx_xvideo_sink_component_Private->old_time = 0; omx_xvideo_sink_component_Private->new_time = 0; omx_xvideo_sink_component_Private->bIsXVideoInit = OMX_TRUE; /*Signal XVideo Initialized*/ tsem_up(omx_xvideo_sink_component_Private->xvideoSyncSem); return OMX_ErrorNone; }
int xf_video_init(xfInfo * xfi) { unsigned int version; unsigned int release; unsigned int request_base; unsigned int event_base; unsigned int error_base; unsigned int num_adaptors; unsigned int i; int ret; XvAdaptorInfo * ai; XvAttribute * attr; XvImageFormatValues * fo; xfi->xv_colorkey_atom = None; xfi->xv_image_size = 0; if (!XShmQueryExtension(xfi->display)) { printf("xf_video_init: no shmem available.\n"); return 1; } ret = XvQueryExtension(xfi->display, &version, &release, &request_base, &event_base, &error_base); if (ret != Success) { printf("xf_video_init: XvQueryExtension failed %d.\n", ret); return 1; } printf("xf_video_init:"); printf(" version %u", version); printf(" release %u", release); printf("\n"); ret = XvQueryAdaptors(xfi->display, DefaultRootWindow(xfi->display), &num_adaptors, &ai); if (ret != Success) { printf("xf_video_init: XvQueryAdaptors failed %d.\n", ret); return 1; } for (i = 0; i < num_adaptors; i++) { printf("xf_video_init: adapter port %ld-%ld (%s)\n", ai[i].base_id, ai[i].base_id + ai[i].num_ports - 1, ai[i].name); if (xfi->xv_port == -1 && i == num_adaptors - 1) xfi->xv_port = ai[i].base_id; } if (num_adaptors > 0) XvFreeAdaptorInfo(ai); if (xfi->xv_port == -1) { printf("xf_video_init: no adapter selected, video frames will not be processed.\n"); return 1; } printf("xf_video_init: selected %ld\n", xfi->xv_port); attr = XvQueryPortAttributes(xfi->display, xfi->xv_port, &ret); for (i = 0; i < (unsigned int)ret; i++) { if (strcmp(attr[i].name, "XV_COLORKEY") == 0) { xfi->xv_colorkey_atom = XInternAtom(xfi->display, "XV_COLORKEY", False); XvSetPortAttribute(xfi->display, xfi->xv_port, xfi->xv_colorkey_atom, attr[i].min_value + 1); break; } } XFree(attr); printf("xf_video_init: pixel format "); fo = XvListImageFormats(xfi->display, xfi->xv_port, &ret); if (ret > 0) { xfi->xv_pixfmts = (uint32 *) malloc((ret + 1) * sizeof(uint32)); for (i = 0; i < ret; i++) { xfi->xv_pixfmts[i] = fo[i].id; printf("%c%c%c%c ", ((char*)(xfi->xv_pixfmts + i))[0], ((char*)(xfi->xv_pixfmts + i))[1], ((char*)(xfi->xv_pixfmts + i))[2], ((char*)(xfi->xv_pixfmts + i))[3]); } xfi->xv_pixfmts[i] = 0; } printf("\n"); return 0; }
static void player_av_load (Player *self, Entry *entry) { gint i; PlayerAVPrivate *priv = PLAYER_AV (self)->priv; player_av_close (self); if (av_open_input_file (&priv->fctx, entry_get_location (entry), NULL, 0, NULL) != 0) return; if (av_find_stream_info (priv->fctx) < 0) return; priv->fctx->flags = AVFMT_FLAG_GENPTS; dump_format(priv->fctx, 0, entry_get_location (entry), 0); priv->astream = priv->vstream = -1; for (i = 0; i < priv->fctx->nb_streams; i++) { if (priv->fctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) { priv->vstream = i; } if (priv->fctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) { priv->astream = i; } if (priv->vstream != -1 && priv->astream != -1) break; } // Setup Audio Stream if (priv->astream != -1) { priv->actx = priv->fctx->streams[priv->astream]->codec; AVCodec *acodec = avcodec_find_decoder (priv->actx->codec_id); if (acodec && avcodec_open (priv->actx, acodec) < 0) { g_print ("Error opening audio stream\n"); return; } } else { priv->actx = NULL; } // Setup Video Stream if (priv->vstream != -1) { priv->vctx = priv->fctx->streams[priv->vstream]->codec; AVCodec *vcodec = avcodec_find_decoder (priv->vctx->codec_id); if(vcodec && avcodec_open (priv->vctx, vcodec) < 0) { g_print ("Error opening video stream\n"); return; } } else { priv->vctx = NULL; } if (priv->vctx) { priv->vctx->get_buffer = player_av_av_get_buffer; priv->vctx->release_buffer = player_av_av_release_buffer; priv->display = gdk_x11_display_get_xdisplay (gdk_display_get_default ()); priv->root = DefaultRootWindow (priv->display); priv->win = GDK_WINDOW_XID (priv->em_da->window); XSetWindowBackgroundPixmap (priv->display, priv->win, None); int nb_adaptors; XvAdaptorInfo *adaptors; XvQueryAdaptors (priv->display, priv->root, &nb_adaptors, &adaptors); int adaptor_no = 0, j, res; priv->xv_port_id = 0; for (i = 0; i < nb_adaptors && !priv->xv_port_id; i++) { adaptor_no = i; for (j = 0; j < adaptors[adaptor_no].num_ports && !priv->xv_port_id; j++) { res = XvGrabPort (priv->display, adaptors[adaptor_no].base_id + j, 0); if (Success == res) { priv->xv_port_id = adaptors[adaptor_no].base_id + j; } } } XvFreeAdaptorInfo (adaptors); int nb_formats; XvImageFormatValues *formats = XvListImageFormats (priv->display, priv->xv_port_id, &nb_formats); unsigned int vfmt = avcodec_pix_fmt_to_codec_tag (priv->vctx->pix_fmt); for (i = 0; i < nb_formats; i++) { if (vfmt == formats[i].id) { break; } } enum PixelFormat ofmt = PIX_FMT_NONE; priv->vframe = avcodec_alloc_frame (); priv->vframe_xv = avcodec_alloc_frame(); if (i < nb_formats) { ofmt = priv->vctx->pix_fmt; } else { for (i = 0; i < nb_formats; i++) { ofmt = avcodec_codec_tag_to_pix_fmt (formats[i].id); if (ofmt != PIX_FMT_NONE) { break; } } } int num_bytes = avpicture_get_size (ofmt, priv->vctx->width + priv->vctx->width % 4, priv->vctx->height); priv->vbuffer_xv = (uint8_t*) av_malloc (num_bytes * sizeof (uint8_t)); avpicture_fill ((AVPicture*) priv->vframe_xv, priv->vbuffer_xv, ofmt, priv->vctx->width + priv->vctx->width % 4, priv->vctx->height); priv->sws_ctx = sws_getContext ( priv->vctx->width, priv->vctx->height, priv->vctx->pix_fmt, priv->vctx->width, priv->vctx->height, ofmt, SWS_POINT, NULL, NULL, NULL); priv->xvimage = XvCreateImage ( priv->display, priv->xv_port_id, formats[i].id, priv->vbuffer_xv, priv->vctx->width, priv->vctx->height); XFree (formats); priv->xv_gc = XCreateGC (priv->display, priv->win, 0, &priv->values); } priv->entry = entry; g_object_ref (entry); priv->vpos = 0; priv->start_time = -1; priv->stop_time = -1; }
// setup x or xvideo void ffmpegWidget::xvSetup() { XvAdaptorInfo * ainfo; XvEncodingInfo *encodings; unsigned int adaptors, nencode; unsigned int ver, rel, extmaj, extev, exterr; // get display number this->dpy = x11Info().display(); // Grab the window id and setup a graphics context this->w = this->winId(); this->gc = XCreateGC(this->dpy, this->w, 0, 0); // Now try and setup xv // return version and release of extension if (XvQueryExtension(this->dpy, &ver, &rel, &extmaj, &extev, &exterr) != Success) { printf("XvQueryExtension failed, using QImage fallback mode\n"); return; } //printf("Ver: %d, Rel: %d, ExtMajor: %d, ExtEvent: %d, ExtError: %d\n", ver, rel, extmaj, extev, exterr); //Ver: 2, Rel: 2, ExtMajor: 140, ExtEvent: 75, ExtError: 150 // return adaptor information for the screen if (XvQueryAdaptors(this->dpy, QX11Info::appRootWindow(), &adaptors, &ainfo) != Success) { printf("XvQueryAdaptors failed, using QImage fallback mode\n"); return; } // see if we have any adapters if (adaptors <= 0) { printf("No xv adaptors found, using QImage fallback mode\n"); return; } // grab the port from the first adaptor int gotPort = 0; for(int p = 0; p < (int) ainfo[0].num_ports; p++) { if(XvGrabPort(this->dpy, ainfo[0].base_id + p, CurrentTime) == Success) { this->xv_port = ainfo[0].base_id + p; gotPort = 1; break; } } // if we didn't find a port if (!gotPort) { printf("No xv ports free, using QImage fallback mode\n"); return; } // get max XV Image size int gotEncodings = 0; XvQueryEncodings(this->dpy, ainfo[0].base_id, &nencode, &encodings); if (encodings && nencode && (ainfo[0].type & XvImageMask)) { for(unsigned int n = 0; n < nencode; n++) { if(!strcmp(encodings[n].name, "XV_IMAGE")) { this->maxW = encodings[n].width; this->maxH = encodings[n].height; gotEncodings = 1; break; } } } // if we didn't find a list of encodings if (!gotEncodings) { printf("No encodings information, using QImage fallback mode\n"); return; } // only support I420 mode for now int num_formats = 0; XvImageFormatValues * vals = XvListImageFormats(this->dpy, this->xv_port, &num_formats); for (int i=0; i<num_formats; i++) { if (strcmp(vals->guid, "I420") == 0) { this->xv_format = vals->id; this->ff_fmt = PIX_FMT_YUVJ420P; // Widget is responsible for painting all its pixels with an opaque color setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_PaintOnScreen); return; } vals++; } printf("Display doesn't support I420 mode, using QImage fallback mode\n"); return; }
static int preinit(struct vo *vo) { XvPortID xv_p; int busy_ports = 0; unsigned int i; struct xvctx *ctx = vo->priv; int xv_adaptor = ctx->cfg_xv_adaptor; if (!vo_x11_init(vo)) return -1; if (!vo_x11_create_vo_window(vo, NULL, "xv")) goto error; struct vo_x11_state *x11 = vo->x11; /* check for Xvideo extension */ unsigned int ver, rel, req, ev, err; if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) { MP_ERR(vo, "Xv not supported by this X11 version/driver\n"); goto error; } /* check for Xvideo support */ if (Success != XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display), &ctx->adaptors, &ctx->ai)) { MP_ERR(vo, "XvQueryAdaptors failed.\n"); goto error; } /* check adaptors */ if (ctx->xv_port) { int port_found; for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) { if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) { for (xv_p = ctx->ai[i].base_id; xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p) { if (xv_p == ctx->xv_port) { port_found = 1; break; } } } } if (port_found) { if (XvGrabPort(x11->display, ctx->xv_port, CurrentTime)) ctx->xv_port = 0; } else { MP_WARN(vo, "Invalid port parameter, overriding with port 0.\n"); ctx->xv_port = 0; } } for (i = 0; i < ctx->adaptors && ctx->xv_port == 0; i++) { /* check if adaptor number has been specified */ if (xv_adaptor != -1 && xv_adaptor != i) continue; if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) { for (xv_p = ctx->ai[i].base_id; xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p) if (!XvGrabPort(x11->display, xv_p, CurrentTime)) { ctx->xv_port = xv_p; MP_VERBOSE(vo, "Using Xv Adapter #%d (%s)\n", i, ctx->ai[i].name); break; } else { MP_WARN(vo, "Could not grab port %i.\n", (int) xv_p); ++busy_ports; } } } if (!ctx->xv_port) { if (busy_ports) MP_ERR(vo, "Xvideo ports busy.\n"); else MP_ERR(vo, "No Xvideo support found.\n"); goto error; } if (!xv_init_colorkey(vo)) { goto error; // bail out, colorkey setup failed } xv_enable_vsync(vo); xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height); ctx->fo = XvListImageFormats(x11->display, ctx->xv_port, (int *) &ctx->formats); MP_WARN(vo, "Warning: this legacy VO has bad quality and performance, " "and will in particular result in blurry OSD and subtitles. " "You should fix your graphic drivers, or not force the xv VO.\n"); return 0; error: uninit(vo); // free resources return -1; }
int svlWindowManagerX11::DoModal(bool show, bool fullscreen) { Destroy(); DestroyFlag = false; unsigned int i, atom_count; int x, y, prevright, prevbottom; unsigned int lastimage = 0; unsigned long black, white; XSizeHints wsh; #if CISST_SVL_HAS_XV Atom atoms[3]; unsigned int xvadaptorcount; XvAdaptorInfo *xvai; XVisualInfo xvvinfo; bool xvupdateimage = true; #else // CISST_SVL_HAS_XV Atom atoms[2]; #endif // CISST_SVL_HAS_XV // setting decoration hints for borderless mode struct { unsigned long flags; unsigned long functions; unsigned long decorations; signed long input_mode; unsigned long status; } mwm; mwm.flags = MWM_HINTS_DECORATIONS; mwm.decorations = 0; mwm.functions = 0; mwm.input_mode = 0; mwm.status = 0; // resetting DestroyedSignal event if (DestroyedSignal) delete(DestroyedSignal); DestroyedSignal = new osaThreadSignal(); if (DestroyedSignal == 0) goto labError; // initialize display and pick default screen xDisplay = XOpenDisplay(reinterpret_cast<char*>(0)); xScreen = DefaultScreen(xDisplay); #if CISST_SVL_HAS_XV // check if 24bpp is suppoted by the display if (XMatchVisualInfo(xDisplay, xScreen, 24, TrueColor, &xvvinfo) == 0) goto labError; #endif // CISST_SVL_HAS_XV // pick colors black = BlackPixel(xDisplay, xScreen); white = WhitePixel(xDisplay, xScreen); // create windows xWindows = new Window[NumOfWins]; memset(xWindows, 0, NumOfWins * sizeof(Window)); xGCs = new GC[NumOfWins]; memset(xGCs, 0, NumOfWins * sizeof(GC)); // create atoms for overriding default window behaviours atoms[0] = XInternAtom(xDisplay, "WM_DELETE_WINDOW", False); atoms[1] = XInternAtom(xDisplay, "_MOTIF_WM_HINTS", False); #if CISST_SVL_HAS_XV atoms[2] = XInternAtom(xDisplay, "XV_SYNC_TO_VBLANK", False); #endif // CISST_SVL_HAS_XV // create title strings Titles = new std::string[NumOfWins]; CustomTitles = new std::string[NumOfWins]; CustomTitleEnabled = new int[NumOfWins]; #if CISST_SVL_HAS_XV xvImg = new XvImage*[NumOfWins]; xvShmInfo = new XShmSegmentInfo[NumOfWins]; xvPort = new XvPortID[NumOfWins]; if (xvImg == 0 || xvShmInfo == 0 || xvPort == 0) goto labError; memset(xvImg, 0, NumOfWins * sizeof(XvImage*)); memset(xvShmInfo, 0, NumOfWins * sizeof(XShmSegmentInfo)); memset(xvPort, 0, NumOfWins * sizeof(XvPortID)); #else // CISST_SVL_HAS_XV // create images xImageBuffers = new unsigned char*[NumOfWins]; for (i = 0; i < NumOfWins; i ++) { xImageBuffers[i] = new unsigned char[Width[i] * Height[i] * 4]; } xImg = new XImage*[NumOfWins]; memset(xImg, 0, NumOfWins * sizeof(XImage*)); if (xImg == 0) goto labError; for (i = 0; i < NumOfWins; i ++) { xImg[i] = XCreateImage(xDisplay, DefaultVisual(xDisplay, xScreen), 24, ZPixmap, 0, reinterpret_cast<char*>(xImageBuffers[i]), Width[i], Height[i], 32, 0); } #endif // CISST_SVL_HAS_XV prevright = prevbottom = 0; for (i = 0; i < NumOfWins; i ++) { if (PosX == 0 || PosY == 0) { if (fullscreen) { x = prevright; y = 0; prevright += Width[i]; } else { x = prevright; y = prevbottom; prevright += 50; prevbottom += 50; } } else { x = PosX[i]; y = PosY[i]; } xWindows[i] = XCreateSimpleWindow(xDisplay, DefaultRootWindow(xDisplay), x, y, Width[i], Height[i], 0, black, white); if (xWindows[i] == 0) goto labError; // overriding default behaviours: // - borderless mode // - closing window if (fullscreen) { XChangeProperty(xDisplay, xWindows[i], atoms[1], atoms[1], 32, PropModeReplace, reinterpret_cast<unsigned char*>(&mwm), 5); atom_count = 2; } else { atom_count = 1; } XSetWMProtocols(xDisplay, xWindows[i], atoms, atom_count); wsh.flags = PPosition|PSize; wsh.x = x; wsh.y = y; wsh.width = Width[i]; wsh.height = Height[i]; XSetNormalHints(xDisplay, xWindows[i], &wsh); // set window title CustomTitleEnabled[i] = 0; std::ostringstream ostring; if (Title.length() > 0) { if (NumOfWins > 0) ostring << Title << " #" << i; else ostring << Title; } else { if (NumOfWins > 0) ostring << Title << "svlImageWindow #" << i; else ostring << "svlImageWindow"; } Titles[i] = ostring.str(); XSetStandardProperties(xDisplay, xWindows[i], Titles[i].c_str(), Titles[i].c_str(), None, NULL, 0, NULL); // set even mask XSelectInput(xDisplay, xWindows[i], ExposureMask|PointerMotionMask|ButtonPressMask|KeyPressMask); // set window colormap XSetWindowColormap(xDisplay, xWindows[i], DefaultColormapOfScreen(DefaultScreenOfDisplay(xDisplay))); #if CISST_SVL_HAS_XV // query shared memory extension if (!XShmQueryExtension(xDisplay)) goto labError; // query video adaptors if (XvQueryAdaptors(xDisplay, DefaultRootWindow(xDisplay), &xvadaptorcount, &xvai) != Success) goto labError; xvPort[i] = xvai->base_id + i; XvFreeAdaptorInfo(xvai); // overriding default Xvideo vertical sync behavior XvSetPortAttribute (xDisplay, xvPort[i], atoms[2], 1); #endif // CISST_SVL_HAS_XV // create graphics context xGCs[i] = XCreateGC(xDisplay, xWindows[i], 0, 0); // set default colors XSetBackground(xDisplay, xGCs[i], white); XSetForeground(xDisplay, xGCs[i], black); #if CISST_SVL_HAS_XV // create image in shared memory xvImg[i] = XvShmCreateImage(xDisplay, xvPort[i], 0x32595559/*YUV2*/, 0, Width[i], Height[i], &(xvShmInfo[i])); if (xvImg[i]->width < static_cast<int>(Width[i]) || xvImg[i]->height < static_cast<int>(Height[i])) { CMN_LOG_INIT_ERROR << "DoModal - image too large for XV to display (requested=" << Width[i] << "x" << Height[i] << "; allowed=" << xvImg[i]->width << "x" << xvImg[i]->height << ")" << std::endl; goto labError; } xvShmInfo[i].shmid = shmget(IPC_PRIVATE, xvImg[i]->data_size, IPC_CREAT | 0777); xvShmInfo[i].shmaddr = xvImg[i]->data = reinterpret_cast<char*>(shmat(xvShmInfo[i].shmid, 0, 0)); xvShmInfo[i].readOnly = False; if (!XShmAttach(xDisplay, &(xvShmInfo[i]))) goto labError; #endif // CISST_SVL_HAS_XV // clear window XClearWindow(xDisplay, xWindows[i]); // show window if requested if (show) XMapRaised(xDisplay, xWindows[i]); } // signal that initialization is done if (InitReadySignal) InitReadySignal->Raise(); // main message loop XEvent event; KeySym code; unsigned int winid; while (1) { osaSleep(0.001); #if CISST_SVL_HAS_XV if (!xvupdateimage) { for (int events = XPending(xDisplay); events > 0; events --) { #else // CISST_SVL_HAS_XV if (XPending(xDisplay)) { #endif // CISST_SVL_HAS_XV XNextEvent(xDisplay, &event); // find recipient for (winid = 0; winid < NumOfWins; winid ++) { if (event.xany.window == xWindows[winid]) break; } if (winid == NumOfWins) continue; // override default window behaviour if (event.type == ClientMessage) { if (static_cast<unsigned long>(event.xclient.data.l[0]) == atoms[0]) { // X11 server wants to close window // Do nothing.... we will destroy it ourselves later } continue; } // window should be closed if (event.type == UnmapNotify) { printf("destroy\n"); if (xGCs[winid]) { XFreeGC(xDisplay, xGCs[winid]); xGCs[winid] = 0; } xWindows[winid] = 0; continue; } // window should be updated if (event.type == Expose && event.xexpose.count == 0) { XClearWindow(xDisplay, xWindows[winid]); continue; } if (event.type == KeyPress) { code = XLookupKeysym(&event.xkey, 0); if (code >= 48 && code <= 57) { // ascii numbers OnUserEvent(winid, true, code); continue; } if (code >= 97 && code <= 122) { // ascii letters OnUserEvent(winid, true, code); continue; } if (code == 13 || code == 32) { // special characters with correct ascii code OnUserEvent(winid, true, code); continue; } if (code >= 0xffbe && code <= 0xffc9) { // F1-F12 OnUserEvent(winid, false, winInput_KEY_F1 + (code - 0xffbe)); continue; } switch (code) { case 0xFF55: OnUserEvent(winid, false, winInput_KEY_PAGEUP); break; case 0xFF56: OnUserEvent(winid, false, winInput_KEY_PAGEDOWN); break; case 0xFF50: OnUserEvent(winid, false, winInput_KEY_HOME); break; case 0xFF57: OnUserEvent(winid, false, winInput_KEY_END); break; case 0xFF63: OnUserEvent(winid, false, winInput_KEY_INSERT); break; case 0xFFFF: OnUserEvent(winid, false, winInput_KEY_DELETE); break; case 0xFF51: OnUserEvent(winid, false, winInput_KEY_LEFT); break; case 0xFF53: OnUserEvent(winid, false, winInput_KEY_RIGHT); break; case 0xFF52: OnUserEvent(winid, false, winInput_KEY_UP); break; case 0xFF54: OnUserEvent(winid, false, winInput_KEY_DOWN); break; } continue; } if (event.type == ButtonPress) { if (event.xbutton.button == Button1) { if (!LButtonDown && !RButtonDown) { LButtonDown = true; XGrabPointer(xDisplay, xWindows[winid], false, PointerMotionMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } OnUserEvent(winid, false, winInput_LBUTTONDOWN); } else if (event.xbutton.button == Button3) { if (!LButtonDown && !RButtonDown) { RButtonDown = true; XGrabPointer(xDisplay, xWindows[winid], false, PointerMotionMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); } OnUserEvent(winid, false, winInput_RBUTTONDOWN); } } if (event.type == ButtonRelease) { if (event.xbutton.button == Button1) { OnUserEvent(winid, false, winInput_LBUTTONUP); if (LButtonDown && !RButtonDown) { LButtonDown = false; XUngrabPointer(xDisplay, CurrentTime); } } else if (event.xbutton.button == Button3) { OnUserEvent(winid, false, winInput_RBUTTONUP); if (!LButtonDown && RButtonDown) { RButtonDown = false; XUngrabPointer(xDisplay, CurrentTime); } } } if (event.type == MotionNotify) { SetMousePos(static_cast<short>(event.xmotion.x), static_cast<short>(event.xmotion.y)); OnUserEvent(winid, false, winInput_MOUSEMOVE); } #if CISST_SVL_HAS_XV // image update complete if (event.type == XShmGetEventBase(xDisplay) + ShmCompletion) { xvupdateimage = true; continue; } } if (!xvupdateimage) signalImage.Wait(0.01); #endif // CISST_SVL_HAS_XV } else { if (DestroyFlag) break; if (ImageCounter > lastimage) { csImage.Enter(); lastimage = ImageCounter; #if CISST_SVL_HAS_XV for (i = 0; i < NumOfWins; i ++) { XvShmPutImage(xDisplay, xvPort[i], xWindows[i], xGCs[i], xvImg[i], 0, 0, Width[i], Height[i], 0, 0, Width[i], Height[i], True); } xvupdateimage = false; #else // CISST_SVL_HAS_XV for (i = 0; i < NumOfWins; i ++) { xImg[i]->data = reinterpret_cast<char*>(xImageBuffers[i]); XPutImage(xDisplay, xWindows[i], xGCs[i], xImg[i], 0, 0, 0, 0, Width[i], Height[i]); } #endif // CISST_SVL_HAS_XV /* for (i = 0; i < NumOfWins; i ++) { if (CustomTitleEnabled[i] < 0) { // Restore original timestamp XSetStandardProperties(xDisplay, xWindows[i], Titles[i].c_str(), Titles[i].c_str(), None, NULL, 0, NULL); } else if (CustomTitleEnabled[i] > 0) { // Set custom timestamp XSetStandardProperties(xDisplay, xWindows[i], CustomTitles[i].c_str(), CustomTitles[i].c_str(), None, NULL, 0, NULL); } } */ csImage.Leave(); } } } labError: #if CISST_SVL_HAS_XV if (xvShmInfo) { for (i = 0; i < NumOfWins; i ++) { XShmDetach(xDisplay, &(xvShmInfo[i])); shmdt(xvShmInfo[i].shmaddr); } delete [] xvShmInfo; xvShmInfo = 0; } #endif // CISST_SVL_HAS_XV XSync(xDisplay, 0); for (i = 0; i < NumOfWins; i ++) { if (xGCs[i]) XFreeGC(xDisplay, xGCs[i]); if (xWindows[i]) XDestroyWindow(xDisplay, xWindows[i]); } XCloseDisplay(xDisplay); #if CISST_SVL_HAS_XV if (xvImg) { for (i = 0; i < NumOfWins; i ++) { if (xvImg[i]) XFree(xvImg[i]); } delete [] xvImg; xvImg = 0; } if (xvPort) { delete [] xvPort; xvPort = 0; } #else // CISST_SVL_HAS_XV if (xImg) { for (i = 0; i < NumOfWins; i ++) { if (xImg[i]) XDestroyImage(xImg[i]); } delete [] xImg; xImg = 0; } if (xImageBuffers) { delete [] xImageBuffers; xImageBuffers = 0; } #endif // CISST_SVL_HAS_XV if (xGCs) { delete [] xGCs; xGCs = 0; } if (xWindows) { delete [] xWindows; xWindows = 0; } if (Titles) { delete [] Titles; Titles = 0; } if (CustomTitles) { delete [] CustomTitles; CustomTitles = 0; } if (CustomTitleEnabled) { delete [] CustomTitleEnabled; CustomTitleEnabled = 0; } xScreen = 0; xDisplay = 0; if (DestroyedSignal) DestroyedSignal->Raise(); return 0; }
static void draw_osd(struct vo *vo, struct osd_state *osd) { struct xvctx *ctx = vo->priv; struct mp_image img = get_xv_buffer(vo, ctx->current_buf); struct mp_osd_res res = { .w = ctx->image_width, .h = ctx->image_height, .display_par = 1.0 / vo->aspdat.par, }; osd_draw_on_image(osd, res, osd->vo_pts, 0, &img); } static void wait_for_completion(struct vo *vo, int max_outstanding) { #if HAVE_SHM struct xvctx *ctx = vo->priv; struct vo_x11_state *x11 = vo->x11; if (ctx->Shmem_Flag) { while (x11->ShmCompletionWaitCount > max_outstanding) { if (!ctx->Shm_Warned_Slow) { MP_WARN(vo, "X11 can't keep up! Waiting" " for XShm completion events...\n"); ctx->Shm_Warned_Slow = 1; } mp_sleep_us(1000); vo_x11_check_events(vo); } } #endif } static void flip_page(struct vo *vo) { struct xvctx *ctx = vo->priv; put_xvimage(vo, ctx->xvimage[ctx->current_buf]); /* remember the currently visible buffer */ ctx->current_buf = (ctx->current_buf + 1) % ctx->num_buffers; if (!ctx->Shmem_Flag) XSync(vo->x11->display, False); } static mp_image_t *get_screenshot(struct vo *vo) { struct xvctx *ctx = vo->priv; if (!ctx->original_image) return NULL; return mp_image_new_ref(ctx->original_image); } // Note: redraw_frame() can call this with NULL. static void draw_image(struct vo *vo, mp_image_t *mpi) { struct xvctx *ctx = vo->priv; wait_for_completion(vo, ctx->num_buffers - 1); struct mp_image xv_buffer = get_xv_buffer(vo, ctx->current_buf); if (mpi) { mp_image_copy(&xv_buffer, mpi); } else { mp_image_clear(&xv_buffer, 0, 0, xv_buffer.w, xv_buffer.h); } mp_image_setrefp(&ctx->original_image, mpi); } static int redraw_frame(struct vo *vo) { struct xvctx *ctx = vo->priv; draw_image(vo, ctx->original_image); return true; } static int query_format(struct vo *vo, uint32_t format) { struct xvctx *ctx = vo->priv; uint32_t i; int flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; int fourcc = find_xv_format(format); if (fourcc) { for (i = 0; i < ctx->formats; i++) { if (ctx->fo[i].id == fourcc) return flag; } } return 0; } static void uninit(struct vo *vo) { struct xvctx *ctx = vo->priv; int i; talloc_free(ctx->original_image); if (ctx->ai) XvFreeAdaptorInfo(ctx->ai); ctx->ai = NULL; if (ctx->fo) { XFree(ctx->fo); ctx->fo = NULL; } for (i = 0; i < ctx->num_buffers; i++) deallocate_xvimage(vo, i); // uninit() shouldn't get called unless initialization went past vo_init() vo_x11_uninit(vo); } static int preinit(struct vo *vo) { XvPortID xv_p; int busy_ports = 0; unsigned int i; struct xvctx *ctx = vo->priv; int xv_adaptor = ctx->cfg_xv_adaptor; if (!vo_x11_init(vo)) return -1; struct vo_x11_state *x11 = vo->x11; /* check for Xvideo extension */ unsigned int ver, rel, req, ev, err; if (Success != XvQueryExtension(x11->display, &ver, &rel, &req, &ev, &err)) { MP_ERR(vo, "Xv not supported by this X11 version/driver\n"); goto error; } /* check for Xvideo support */ if (Success != XvQueryAdaptors(x11->display, DefaultRootWindow(x11->display), &ctx->adaptors, &ctx->ai)) { MP_ERR(vo, "XvQueryAdaptors failed.\n"); goto error; } /* check adaptors */ if (ctx->xv_port) { int port_found; for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) { if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) { for (xv_p = ctx->ai[i].base_id; xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p) { if (xv_p == ctx->xv_port) { port_found = 1; break; } } } } if (port_found) { if (XvGrabPort(x11->display, ctx->xv_port, CurrentTime)) ctx->xv_port = 0; } else { MP_WARN(vo, "Invalid port parameter, overriding with port 0.\n"); ctx->xv_port = 0; } } for (i = 0; i < ctx->adaptors && ctx->xv_port == 0; i++) { /* check if adaptor number has been specified */ if (xv_adaptor != -1 && xv_adaptor != i) continue; if ((ctx->ai[i].type & XvInputMask) && (ctx->ai[i].type & XvImageMask)) { for (xv_p = ctx->ai[i].base_id; xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p) if (!XvGrabPort(x11->display, xv_p, CurrentTime)) { ctx->xv_port = xv_p; MP_VERBOSE(vo, "Using Xv Adapter #%d (%s)\n", i, ctx->ai[i].name); break; } else { MP_WARN(vo, "Could not grab port %i.\n", (int) xv_p); ++busy_ports; } } } if (!ctx->xv_port) { if (busy_ports) MP_ERR(vo, "Could not find free Xvideo port - maybe another process is already\n"\ "using it. Close all video applications, and try again. If that does\n"\ "not help, see 'mpv -vo help' for other (non-xv) video out drivers.\n"); else MP_ERR(vo, "It seems there is no Xvideo support for your video card available.\n"\ "Run 'xvinfo' to verify its Xv support and read\n"\ "DOCS/HTML/en/video.html#xv!\n"\ "See 'mpv -vo help' for other (non-xv) video out drivers.\n"\ "Try -vo x11.\n"); goto error; } if (!xv_init_colorkey(vo)) { goto error; // bail out, colorkey setup failed } xv_enable_vsync(vo); xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height); ctx->fo = XvListImageFormats(x11->display, ctx->xv_port, (int *) &ctx->formats); return 0; error: uninit(vo); // free resources return -1; }
void xf_tsmf_init(xfInfo* xfi, long xv_port) { int ret; unsigned int i; unsigned int version; unsigned int release; unsigned int event_base; unsigned int error_base; unsigned int request_base; unsigned int num_adaptors; xfXvContext* xv; XvAdaptorInfo* ai; XvAttribute* attr; XvImageFormatValues* fo; xv = (xfXvContext*) malloc(sizeof(xfXvContext)); ZeroMemory(xv, sizeof(xfXvContext)); xfi->xv_context = xv; xv->xv_colorkey_atom = None; xv->xv_image_size = 0; xv->xv_port = xv_port; if (!XShmQueryExtension(xfi->display)) { DEBUG_XV("no shmem available."); return; } ret = XvQueryExtension(xfi->display, &version, &release, &request_base, &event_base, &error_base); if (ret != Success) { DEBUG_XV("XvQueryExtension failed %d.", ret); return; } DEBUG_XV("version %u release %u", version, release); ret = XvQueryAdaptors(xfi->display, DefaultRootWindow(xfi->display), &num_adaptors, &ai); if (ret != Success) { DEBUG_XV("XvQueryAdaptors failed %d.", ret); return; } for (i = 0; i < num_adaptors; i++) { DEBUG_XV("adapter port %ld-%ld (%s)", ai[i].base_id, ai[i].base_id + ai[i].num_ports - 1, ai[i].name); if (xv->xv_port == 0 && i == num_adaptors - 1) xv->xv_port = ai[i].base_id; } if (num_adaptors > 0) XvFreeAdaptorInfo(ai); if (xv->xv_port == 0) { DEBUG_XV("no adapter selected, video frames will not be processed."); return; } DEBUG_XV("selected %ld", xv->xv_port); attr = XvQueryPortAttributes(xfi->display, xv->xv_port, &ret); for (i = 0; i < (unsigned int)ret; i++) { if (strcmp(attr[i].name, "XV_COLORKEY") == 0) { xv->xv_colorkey_atom = XInternAtom(xfi->display, "XV_COLORKEY", FALSE); XvSetPortAttribute(xfi->display, xv->xv_port, xv->xv_colorkey_atom, attr[i].min_value + 1); break; } } XFree(attr); #ifdef WITH_DEBUG_XV fprintf(stderr, "xf_tsmf_init: pixel format "); #endif fo = XvListImageFormats(xfi->display, xv->xv_port, &ret); if (ret > 0) { xv->xv_pixfmts = (UINT32*) malloc((ret + 1) * sizeof(UINT32)); ZeroMemory(xv->xv_pixfmts, (ret + 1) * sizeof(UINT32)); for (i = 0; i < ret; i++) { xv->xv_pixfmts[i] = fo[i].id; #ifdef WITH_DEBUG_XV fprintf(stderr, "%c%c%c%c ", ((char*)(xv->xv_pixfmts + i))[0], ((char*)(xv->xv_pixfmts + i))[1], ((char*)(xv->xv_pixfmts + i))[2], ((char*)(xv->xv_pixfmts + i))[3]); #endif } xv->xv_pixfmts[i] = 0; } XFree(fo); #ifdef WITH_DEBUG_XV fprintf(stderr, "\n"); #endif }
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); } }
static int find_best_xv_port(Display* dpy, Window win, XvPortID* xv_port, char* error_text, int text_len) { unsigned int num_adaptors; XvAdaptorInfo* adaptors; int ret; unsigned int i; DEBUG_PRINTF("Looking for port...\n"); ret = XvQueryAdaptors(dpy, win, &num_adaptors, &adaptors); switch (ret) { case Success: break; case XvBadExtension: snprintf(error_text, text_len, "Xv Extension not available for this display"); return 0; case XvBadAlloc: snprintf(error_text, text_len, "XvQueryAdaptors could not allocate memory"); return 0; default: snprintf(error_text, text_len, "XvQueryAdaptors: unknown error"); return 0; } if (num_adaptors == 0) { snprintf(error_text, text_len, "No adaptors found"); XvFreeAdaptorInfo(adaptors); return 0; } // grab first free port (TODO) for (i = 0; i < num_adaptors; ++i) { XvAdaptorInfo* ai = adaptors +i; DEBUG_PRINTF(" <><> Adaptor #%i (%s):\n", i, ai->name); if (ai->type & XvInputMask) DEBUG_PRINTF(" - input\n"); if (ai->type & XvOutputMask) DEBUG_PRINTF(" - output\n"); if (ai->type & XvImageMask) DEBUG_PRINTF(" - image\n"); if (ai->type & XvStillMask) DEBUG_PRINTF(" - still\n"); if (ai->type & XvVideoMask) DEBUG_PRINTF(" - video\n"); if ((ai->type & XvInputMask) && (ai->type & XvImageMask)) { XvPortID base_port = ai->base_id; XvPortID port; int num_ports = ai->num_ports; for (port = base_port; port < base_port + num_ports; ++port) { int ret = XvGrabPort(dpy, port, CurrentTime); if (ret == Success) { *xv_port = port; DEBUG_PRINTF("Xv: got port %i\n", (int)port); XvFreeAdaptorInfo(adaptors); return 1; } else { DEBUG_PRINTF("Xv: could not grab port %i\n", (int)port); } } } } snprintf(error_text, text_len, "Could not find free port"); XvFreeAdaptorInfo(adaptors); return 0; }