Changeset 901:8f08eda17546 in mediastreamer2 for src/videoout.c
- Timestamp:
- Mar 1, 2010 12:47:23 PM (3 years ago)
- Branch:
- default
- File:
-
- 1 edited
-
src/videoout.c (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/videoout.c
r898 r901 57 57 } 58 58 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 70 typedef 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 92 static 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 107 static 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 133 static void xv_display_uninit(MSDisplay *obj); 134 135 static 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 284 static 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 346 static 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 353 static 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 360 static 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 404 static 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 430 static 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 461 MSDisplayDesc 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 60 471 61 472 #include <SDL/SDL.h> … … 909 1320 } 910 1321 911 #ifdef HAVE_SDL 1322 #if defined(HAVE_X11_EXTENSIONS_XV_H) && defined(HAVE_X11_XLIB_H) 1323 static MSDisplayDesc *default_display_desc=&ms_xv_display_desc; 1324 #elif HAVE_SDL 912 1325 static MSDisplayDesc *default_display_desc=&ms_sdl_display_desc; 913 1326 #elif defined(WIN32) … … 1070 1483 static int video_out_handle_resizing(MSFilter *f, void *data){ 1071 1484 /* to be removed */ 1072 return 0;1485 return -1; 1073 1486 } 1074 1487
Note: See TracChangeset
for help on using the changeset viewer.
