/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** gui_xv.cpp - description ------------------- This part is strongly derivated from xine/mplayer/mpeg2dec begin : Tue Jan 1 2002 copyright : (C) 2002 by mean email : fixounet@free.fr ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "xvaccelrenderer.h" #include #include #include #include // Use this define for verbose output #define VERBOSE_XV //________________Wrapper around Xv_______________ XvAccelRender::XvAccelRender(QWidget *window, uint32_t w, uint32_t h) { xvimage = NULL; #ifdef VERBOSE_XV printf("Xv start\n"); #endif width = w; height = h; GUI_XvInit(window, w, h); } XvAccelRender::~XvAccelRender() { GUI_XvEnd( ); #ifdef VERBOSE_XV printf("Xv end\n"); #endif } char *XvAccelRender::getDisplayData() { if(xvimage) return xvimage->data; else return NULL; } uint8_t XvAccelRender::display(uint32_t w, uint32_t h) { return GUI_XvDisplay(w, h); } //________________Wrapper around Xv_______________ // // Free all ressources allocated by xv // void XvAccelRender::GUI_XvEnd( void ) { ADM_assert(xv_port); ADM_assert(xv_display); #ifdef VERBOSE_XV printf("\n Releasing Xv Port\n"); #endif XLockDisplay (xv_display); if(XvUngrabPort(xv_display,xv_port,0)!=Success) printf("\n Trouble releasing port...\n"); XUnlockDisplay (xv_display); xvimage=NULL; xv_display=NULL; xv_port=0; } //------------------------------------ uint8_t XvAccelRender::GUI_XvDisplay(uint32_t w, uint32_t h) { if (xvimage) { // put image in shared segment // for YV12, 4 bits for Y 4 bits for u, 4 bits for v // total 1.5* // memcpy(xvimage->data, src, (w*h*3)>>1); //memcpy(xvimage->data, src, (w*h*4)>>1); // We decodee directly to the buffer, so we don't need to copy it. XLockDisplay (xv_display); // And display it ! #if 1 XvShmPutImage(xv_display, xv_port, xv_win, xv_gc, xvimage, 0, 0, w, h, // src // 0, 0, w / 4, h / 4, // dst 0, 0, width, height, // dst False); #else XvPutImage(xv_display, xv_port, xv_win, xv_gc, xvimage, 0, 0, w, h, // src 0, 0, w, h // dst ); #endif //XSetForeground (xv_display, xv_gc, 0); XSync(xv_display, False); XUnlockDisplay (xv_display); //GUI_XvExpose(); } return 1; } /* uint8_t XvAccelRender::GUI_XvSync(void) { if(xv_display) XSync(xv_display, False); return 1; } */ //------------------------------------ // //------------------------------------ uint8_t XvAccelRender::GUI_XvInit(QWidget * window, uint32_t w, uint32_t h) { unsigned int ver, rel, req, ev, err; unsigned int port, adaptors; static XvAdaptorInfo *ai; static XvAdaptorInfo *curai; // win = gtk_widget_get_parent_window(window); xv_display = window->x11Info().display();//GDK_WINDOW_XDISPLAY(win); // xv_win= RootWindow(xv_display,0); xv_win = window->winId();//GDK_WINDOW_XWINDOW(GTK_WIDGET(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 Adaptator : %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 + 1; // FIXME: TODO: HACK: It works when +1 is applied! But why!? } curai++; } // if (!port) { printf("\n no port found"); goto failed; } #ifdef COLORSPACE_YV12 #ifdef VERBOSE_XV printf("\n Xv YV12 found at port :%d, format : %d", port, xv_format); #endif #else #ifdef VERBOSE_XV printf("\n Xv YUY2 found at port :%d, format : %d", port, xv_format); #endif #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 */ xvimage = XvShmCreateImage(WDN, xv_port, xv_format, 0, w, h, &Shminfo); Shminfo.shmid = shmget(IPC_PRIVATE, xvimage->data_size, IPC_CREAT | 0777); Shminfo.shmaddr = (char *) shmat(Shminfo.shmid, 0, 0); Shminfo.readOnly = False; xvimage->data = Shminfo.shmaddr; XShmAttach(WDN, &Shminfo); XSync(WDN, False); shmctl(Shminfo.shmid, IPC_RMID, 0); 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)); } #ifdef VERBOSE_XV printf("\n Xv init succeedeed\n"); #endif return 1; failed: printf("\n Xv init failed..\n"); return 0; } // _________________________________________________ // // _________________________________________________ uint8_t XvAccelRender::GUI_XvList(Display * dis, uint32_t port, uint32_t * fmt) { XvImageFormatValues *formatValues; int imgfmt; int k, f = 0; formatValues = XvListImageFormats(dis, port, &imgfmt); if (formatValues) for (k = 0; !f || (k < imgfmt); k++) { #ifdef VERVOSE_XV printf("\n %lx %d --> %s", port, formatValues[k].id, formatValues[k].guid); #endif #ifdef COLORSPACE_YV12 if (!strcmp(formatValues[k].guid, "YV12")) #else if (!strcmp(formatValues[k].guid, "YUY2")) #endif { f = 1; *fmt = formatValues[k].id; } } else f = 0; XFree(formatValues); return f; }