Changeset 901:8f08eda17546 in mediastreamer2


Ignore:
Timestamp:
Mar 1, 2010 12:47:23 PM (3 years ago)
Author:
Aymeric Moizard <jack@…>
Branch:
default
Message:

add experimental code for XV support

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • acinclude.m4

    r873 r901  
    152152                AC_CHECK_HEADERS(X11/Xlib.h) 
    153153                fi 
     154 
     155                AC_ARG_ENABLE(xv, 
     156                  [  --enable-xv     Enable xv support - experimental], 
     157                  [case "${enableval}" in 
     158                        yes) enable_xv=true ;; 
     159                        no)  enable_xv=false ;; 
     160                        *) AC_MSG_ERROR(bad value ${enableval} for --enable-xv) ;; 
     161                  esac],[enable_xv=false]) 
     162 
     163                if test "$enable_xv" = "true"; then 
     164                AC_CHECK_HEADERS(X11/extensions/Xv.h) 
     165                AC_CHECK_LIB(Xv,XvCreateImage,[LIBS="$LIBS -lXv"]) 
     166                fi 
    154167                 
    155168                VIDEO_CFLAGS=" $FFMPEG_CFLAGS -DVIDEO_ENABLED" 
  • src/videoout.c

    r898 r901  
    5757} 
    5858 
    59 #ifdef HAVE_SDL 
     59#undef HAVE_X11_EXTENSIONS_XV_H 
     60#if defined(HAVE_X11_EXTENSIONS_XV_H) && defined(HAVE_X11_XLIB_H) 
     61 
     62#include <X11/Xlib.h> 
     63#include <X11/Xutil.h> 
     64#include <X11/extensions/Xv.h> 
     65#include <X11/extensions/Xvlib.h> 
     66 
     67//#include <SDL/SDL.h> 
     68//#include <SDL/SDL_video.h> 
     69 
     70typedef struct XvDisplay { 
     71        MSFilter *filter; 
     72        ms_mutex_t xv_mutex; 
     73        //SDL_Surface *sdl_screen; 
     74        Display *display; 
     75        Window window;   
     76        GC gc; 
     77        XImage* ximage;   
     78        XvImage *xvImage; 
     79        int XvPort; 
     80        int XvFormat; 
     81        float sv_scalefactor; 
     82        MSVideoSize screen_size; 
     83 
     84        MSPicture fb; 
     85        mblk_t *fb_block; 
     86        MSPicture fb_selfview; 
     87        mblk_t *fb_selfview_block; 
     88} XvDisplay; 
     89 
     90#include <SDL/SDL_syswm.h> 
     91 
     92static long xv_get_native_window_id(XvDisplay *wd){ 
     93#if 0 
     94        SDL_SysWMinfo info; 
     95        SDL_VERSION(&info.version); 
     96        if ( SDL_GetWMInfo(&info) ) { 
     97                if ( info.subsystem == SDL_SYSWM_X11 ) { 
     98                        return (long) info.info.x11.wmwindow; 
     99                } 
     100        } 
     101#else 
     102        return (long) wd->window; 
     103#endif 
     104        return 0; 
     105} 
     106 
     107static void xv_show_window(XvDisplay *wd, bool_t show){ 
     108#if 0 
     109        SDL_SysWMinfo info; 
     110        SDL_VERSION(&info.version); 
     111        if ( SDL_GetWMInfo(&info) ) { 
     112                if ( info.subsystem == SDL_SYSWM_X11 ) { 
     113                 
     114                        info.info.x11.lock_func(); 
     115                        wd->display = info.info.x11.display; 
     116                        wd->window = info.info.x11.wmwindow; 
     117                        if (show) 
     118                                XMapWindow(wd->display,wd->window); 
     119                        else 
     120                                XUnmapWindow(wd->display,wd->window); 
     121                        info.info.x11.unlock_func(); 
     122                } 
     123        } 
     124#else 
     125        if (show) 
     126                XMapWindow(wd->display,wd->window); 
     127        else 
     128                XUnmapWindow(wd->display,wd->window); 
     129#endif 
     130} 
     131 
     132 
     133static void xv_display_uninit(MSDisplay *obj); 
     134 
     135static int xv_create_window(XvDisplay *wd, int w, int h){ 
     136        //static bool_t once=TRUE; 
     137        XvAdaptorInfo *xv_adaptor_info=NULL; 
     138        XvAdaptorInfo *ai; 
     139        unsigned int xv_adaptors; 
     140        unsigned int i; 
     141        XGCValues xv_xgc; 
     142 
     143        int screen; 
     144        XVisualInfo vinfo; 
     145        XWindowAttributes wattr; 
     146        unsigned long xswamask; 
     147        XSetWindowAttributes xswa; 
     148        XSizeHints hint; 
     149         
     150#if 0 
     151        uint32_t flags = SDL_ANYFORMAT | SDL_DOUBLEBUF | SDL_RESIZABLE; 
     152        const SDL_VideoInfo *info; 
     153        info =SDL_GetVideoInfo(); 
     154        if (info->wm_available) { 
     155                ms_message("Using window manager"); 
     156        } 
     157        if (info->hw_available) { 
     158                ms_message("hw surface available (%dk memory)", info->video_mem); 
     159                flags |= SDL_HWSURFACE; 
     160        } 
     161        else 
     162                flags |= SDL_SWSURFACE; 
     163         
     164        if (info->blit_hw) { 
     165                ms_message("hw surface available (%dk memory)", info->video_mem); 
     166                flags |= SDL_ASYNCBLIT; 
     167        } 
     168        if (info->blit_hw_CC) 
     169                ms_message("Colorkey blits between hw surfaces: accelerated"); 
     170        if (info->blit_hw_A) 
     171                ms_message("Alpha blits between hw surfaces:  accelerated"); 
     172        if (info->blit_sw) 
     173                ms_message("Copy blits from sw to hw surfaces:  accelerated"); 
     174        if (info->blit_hw_CC) 
     175                ms_message("Colorkey blits between sw to hw surfaces: accelerated"); 
     176        if (info->blit_hw_A) 
     177                ms_message("Alpha blits between sw to hw surfaces: accelerated"); 
     178 
     179        wd->sdl_screen = SDL_SetVideoMode(wd->screen_size.width,wd->screen_size.height, 0,flags); 
     180        if (wd->sdl_screen == NULL ) { 
     181                ms_warning("no hardware for video mode: %s\n", 
     182                                   SDL_GetError()); 
     183        } 
     184        if (wd->sdl_screen->flags & SDL_HWSURFACE) ms_message("SDL surface created in hardware"); 
     185        if (once) { 
     186                SDL_WM_SetCaption("Video window", NULL); 
     187                once=FALSE; 
     188        } 
     189#endif 
     190 
     191        hint.x=0; 
     192        hint.y=0; 
     193        hint.width=w; 
     194        hint.height=h; 
     195        hint.flags=PPosition | PSize; 
     196         
     197        wd->display = XOpenDisplay(":0.0"); 
     198        if (wd->display==NULL){ 
     199                ms_error("videout.c:xv XOpenDisplay failed"); 
     200                return -1; 
     201        } 
     202        ms_message("videout.c:xv XOpenDisplay done"); 
     203                 
     204        XGetWindowAttributes(wd->display, DefaultRootWindow(wd->display), &wattr); 
     205        screen = DefaultScreen(wd->display); 
     206        XMatchVisualInfo(wd->display, screen, wattr.depth, TrueColor, &vinfo); 
     207 
     208        ms_message("videout.c:xv depth=%i", wattr.depth); 
     209        xswa.background_pixel = 0; 
     210        xswa.border_pixel = 1; 
     211        xswamask = CWBackPixel | CWBorderPixel; 
     212        wd->window = XCreateWindow(wd->display, 
     213                                                           RootWindow(wd->display, screen), 
     214                                                           hint.x, hint.y, hint.width, hint.height, 4, 
     215                                                           wattr.depth, 
     216                                                           CopyFromParent, 
     217                                                           vinfo.visual, 
     218                                                           xswamask, 
     219                                                           &xswa); 
     220        if (wd->window==NULL){ 
     221                ms_error("videout.c:xv XCreateWindow failed"); 
     222                return -1; 
     223        } 
     224         
     225        xv_xgc.graphics_exposures = 0; 
     226        wd->gc = XCreateGC(wd->display, wd->window, 0L, &xv_xgc); 
     227        if (wd->gc==NULL){ 
     228                ms_error("videout.c:xv XCreateGC failed"); 
     229                return -1; 
     230        } 
     231 
     232        if (Success != XvQueryAdaptors(wd->display, 
     233                                   wd->window, 
     234                                   &xv_adaptors,  
     235                                   (XvAdaptorInfo **)&xv_adaptor_info)) { 
     236    } 
     237     
     238    ai = (XvAdaptorInfo *)xv_adaptor_info; 
     239 
     240        wd->XvPort=0; 
     241    for (i = 0; i < xv_adaptors; i++) { 
     242                ms_message("adaptors: name: %s baseport=%i", ai[i].name, ai[i].base_id); 
     243                if ((ai[i].type &XvInputMask) && (ai[i].type &XvImageMask)) 
     244                        { 
     245                                XvPortID xv_p; 
     246                                for (xv_p = ai[i].base_id; 
     247                     xv_p < ai[i].base_id + ai[i].num_ports; ++xv_p){ 
     248                                        if (XvGrabPort(wd->display, xv_p, CurrentTime)==0) 
     249                                                { 
     250                                                        wd->XvPort = xv_p; 
     251                                                        break; 
     252                                                } 
     253                                } 
     254                                if (wd->XvPort!=0) 
     255                                        break; 
     256                        } 
     257        } 
     258        XvFreeAdaptorInfo(ai); 
     259        ms_message("using Xvideo port %d for hw scaling", wd->XvPort); 
     260        if (wd->XvPort>0) 
     261                { 
     262                        uint32_t fmt = 0x32315659; //YV12 
     263                        int formats; 
     264                        XvImageFormatValues *fo; 
     265                        fo = XvListImageFormats(wd->display, wd->XvPort, (int *)&formats); 
     266                        for (i=0;i<formats;i++) 
     267                                { 
     268                                        ms_message("format=[%4.4s] %s", (char *) &fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar"); 
     269                                        if (fo[i].id==fmt){ 
     270                                                wd->XvFormat =fo[i].id; 
     271                                                ms_message("found YV12 format"); 
     272                                        } 
     273                                } 
     274                        XFree(fo); 
     275                } 
     276 
     277        wd->xvImage = (XvImage *)XvCreateImage( wd->display , wd->XvPort, wd->XvFormat, NULL, w, h); 
     278        wd->fb_block = yuv_buf_alloc(&wd->fb, w, h); 
     279        wd->xvImage->data = wd->fb_block->b_rptr; 
     280        //SDL_ShowCursor(0);//Hide the mouse cursor if was displayed 
     281        return 0; 
     282} 
     283 
     284static bool_t xv_display_init(MSDisplay *obj, MSFilter *f, MSPicture *fbuf, MSPicture *fbuf_selfview){ 
     285        XvDisplay *wd = (XvDisplay*)obj->data; 
     286        int i; 
     287 
     288        if (wd==NULL){ 
     289                //char driver[128]; 
     290                /* Initialize the SDL library */ 
     291                wd=(XvDisplay*)ms_new0(XvDisplay,1); 
     292                wd->filter = f; 
     293                obj->data=wd; 
     294 
     295                #if 0 
     296                if( SDL_Init(SDL_INIT_VIDEO) < 0 ) { 
     297                        ms_error("Couldn't initialize SDL: %s", SDL_GetError()); 
     298                        return FALSE; 
     299                } 
     300                if (SDL_VideoDriverName(driver, sizeof(driver))){ 
     301                        ms_message("Video driver: %s", driver); 
     302                } 
     303#endif 
     304                ms_mutex_init(&wd->xv_mutex,NULL); 
     305                ms_mutex_lock(&wd->xv_mutex); 
     306                wd->screen_size.width = fbuf->w; 
     307                wd->screen_size.height = fbuf->h; 
     308        }else { 
     309                ms_mutex_lock(&wd->xv_mutex); 
     310 
     311                if (wd->xvImage!=NULL) 
     312                        XFree(wd->xvImage); 
     313                if (wd->fb_block!=NULL) 
     314                        freemsg(wd->fb_block); 
     315                XvUngrabPort(wd->display, wd->XvPort, CurrentTime); 
     316                 
     317                //if (wd->sdl_screen!=NULL) 
     318                //      SDL_FreeSurface(wd->sdl_screen); 
     319                //wd->sdl_screen=NULL; 
     320        } 
     321        wd->filter = f; 
     322 
     323        wd->XvFormat=0x32315659; //IMGFMT_YV12; 
     324        //xv_show_window(wd, TRUE); 
     325        i=xv_create_window(wd, fbuf->w, fbuf->h); 
     326        if (i==0){ 
     327                fbuf->planes[0]=wd->fb.planes[0]; 
     328                fbuf->planes[1]=wd->fb.planes[2]; 
     329                fbuf->planes[2]=wd->fb.planes[1]; 
     330                fbuf->planes[3]=NULL; 
     331                fbuf->strides[0]=wd->fb.strides[0]; 
     332                fbuf->strides[1]=wd->fb.strides[2]; 
     333                fbuf->strides[2]=wd->fb.strides[1]; 
     334                fbuf->strides[3]=0; 
     335                fbuf->w=wd->fb.w; 
     336                fbuf->h=wd->fb.h; 
     337                xv_show_window(wd, TRUE); 
     338                obj->window_id=xv_get_native_window_id(wd); 
     339                ms_mutex_unlock(&wd->xv_mutex); 
     340                return TRUE; 
     341        } 
     342        ms_mutex_unlock(&wd->xv_mutex); 
     343        return FALSE; 
     344} 
     345 
     346static void xv_display_lock(MSDisplay *obj){ 
     347        XvDisplay *wd = (XvDisplay*)obj->data; 
     348        ms_mutex_lock(&wd->xv_mutex); 
     349        XLockDisplay(wd->display); 
     350        ms_mutex_unlock(&wd->xv_mutex); 
     351} 
     352 
     353static void xv_display_unlock(MSDisplay *obj){ 
     354        XvDisplay *wd = (XvDisplay*)obj->data; 
     355        ms_mutex_lock(&wd->xv_mutex); 
     356        XUnlockDisplay(wd->display); 
     357        ms_mutex_unlock(&wd->xv_mutex); 
     358} 
     359 
     360static void xv_display_update(MSDisplay *obj, int new_image, int new_selfview){ 
     361        XvDisplay *wd = (XvDisplay*)obj->data; 
     362        //SDL_Rect rect; 
     363        int ratiow; 
     364        int ratioh; 
     365        int w; 
     366        int h; 
     367         
     368        //rect.x=0; 
     369        //rect.y=0; 
     370        ms_mutex_lock(&wd->xv_mutex); 
     371 
     372        ratiow=wd->fb.w; 
     373        ratioh=wd->fb.h; 
     374        reduce(&ratiow, &ratioh); 
     375        w = wd->screen_size.width/ratiow*ratiow; 
     376        h = wd->screen_size.height/ratioh*ratioh; 
     377 
     378        if (h*ratiow>w*ratioh) 
     379        { 
     380                w = w; 
     381                h = w*ratioh/ratiow; 
     382        } 
     383        else 
     384        { 
     385                h = h; 
     386                w = h*ratiow/ratioh; 
     387        } 
     388 
     389        if (h*wd->fb.w!=w*wd->fb.h) 
     390                ms_error("wrong ratio"); 
     391 
     392        //x = (wd->screen_size.width-w)/2; 
     393        //y = (wd->screen_size.height-h)/2; 
     394        //rect.w = w; 
     395        //rect.h = h; 
     396        XLockDisplay(wd->display); 
     397        XvPutImage( wd->display, wd->XvPort, wd->window, wd->gc, 
     398                                wd->xvImage, 0, 0, wd->xvImage->width, wd->xvImage->height, 0, 0, w*2, h*2); 
     399        XFlush(wd->display); 
     400        XUnlockDisplay(wd->display); 
     401        ms_mutex_unlock(&wd->xv_mutex); 
     402} 
     403 
     404static bool_t xv_poll_event(MSDisplay *obj, MSDisplayEvent *ev){ 
     405        XvDisplay *wd = (XvDisplay*)obj->data; 
     406        bool_t ret=FALSE; 
     407#if 0 
     408        SDL_Event event; 
     409        if (wd->sdl_screen==NULL) return FALSE; 
     410        ms_mutex_lock(&wd->xv_mutex); 
     411        if (SDL_PollEvent(&event)){ 
     412                ms_mutex_unlock(&wd->xv_mutex); 
     413                switch(event.type){ 
     414                        case SDL_VIDEORESIZE: 
     415                                ev->evtype=MS_DISPLAY_RESIZE_EVENT; 
     416                                ev->w=event.resize.w; 
     417                                ev->h=event.resize.h; 
     418                                wd->screen_size.width = event.resize.w; 
     419                                wd->screen_size.height = event.resize.h; 
     420                                return TRUE; 
     421                        break; 
     422                        default: 
     423                        break; 
     424                } 
     425        }else ms_mutex_unlock(&wd->xv_mutex); 
     426#endif 
     427        return ret; 
     428} 
     429 
     430static void xv_display_uninit(MSDisplay *obj){ 
     431        XvDisplay *wd = (XvDisplay*)obj->data; 
     432#if 0 
     433        SDL_Event event; 
     434        int i; 
     435#endif 
     436        if (wd==NULL) 
     437                return; 
     438        xv_show_window(wd, FALSE); 
     439        if (wd->gc!=NULL) 
     440                XFreeGC(wd->display, wd->gc); 
     441        //if (wd->sdl_screen!=NULL){ 
     442        //      SDL_FreeSurface(wd->sdl_screen); 
     443        //      wd->sdl_screen=NULL; 
     444        //} 
     445        if (wd->xvImage!=NULL) 
     446                XFree(wd->xvImage); 
     447        if (wd->fb_block!=NULL) 
     448                freemsg(wd->fb_block); 
     449        XvUngrabPort(wd->display, wd->XvPort, CurrentTime); 
     450        ms_free(wd); 
     451#if 0 
     452#ifdef __linux 
     453        /*purge the event queue before leaving*/ 
     454        for(i=0;SDL_PollEvent(&event) && i<100;++i){ 
     455        } 
     456#endif 
     457        SDL_Quit(); 
     458#endif 
     459} 
     460 
     461MSDisplayDesc ms_xv_display_desc={ 
     462        .init=xv_display_init, 
     463        .lock=xv_display_lock, 
     464        .unlock=xv_display_unlock, 
     465        .update=xv_display_update, 
     466        .uninit=xv_display_uninit, 
     467        .pollevent=xv_poll_event, 
     468}; 
     469 
     470#elif HAVE_SDL 
    60471 
    61472#include <SDL/SDL.h> 
     
    9091320} 
    9101321 
    911 #ifdef HAVE_SDL 
     1322#if defined(HAVE_X11_EXTENSIONS_XV_H) && defined(HAVE_X11_XLIB_H) 
     1323static MSDisplayDesc *default_display_desc=&ms_xv_display_desc; 
     1324#elif HAVE_SDL 
    9121325static MSDisplayDesc *default_display_desc=&ms_sdl_display_desc; 
    9131326#elif defined(WIN32) 
     
    10701483static int video_out_handle_resizing(MSFilter *f, void *data){ 
    10711484        /* to be removed */ 
    1072         return 0; 
     1485        return -1; 
    10731486} 
    10741487 
Note: See TracChangeset for help on using the changeset viewer.