📄 xvmc.c
字号:
"subpicture type.", i ); } } } XFree(formatValues); curInfo++; curCap++; } } XFree(surfaceInfo); /* * Try to create a direct rendering context. This will fail if we are not * on the displaying computer or an indirect context is not available. */ XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); curCap = p_vout->p_sys->xvmc_cap; if( Success == XvMCCreateContext( p_vout->p_sys->p_display, i_xvport, curCap->type_id, curCap->max_width, curCap->max_height, XVMC_DIRECT, &c ) ) { msg_Dbg( p_vout, "using direct XVMC rendering context" ); p_vout->p_sys->context_flags = XVMC_DIRECT; } else if( Success == XvMCCreateContext( p_vout->p_sys->p_display, i_xvport, curCap->type_id, curCap->max_width, curCap->max_height, 0, &c ) ) { msg_Dbg( p_vout, "using default XVMC rendering context" ); p_vout->p_sys->context_flags = 0; } else { if( p_vout->p_sys->xvmc_cap ) free( p_vout->p_sys->xvmc_cap ); p_vout->p_sys->xvmc_cap = NULL; msg_Err( p_vout, "use of direct XvMC context on a remote display failed" " falling back to XV." ); xvmc_context_writer_unlock( &p_vout->p_sys->xvmc_lock ); return VLC_SUCCESS; } XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); XvMCDestroyContext( p_vout->p_sys->p_display, &c ); xxmc_xvmc_surface_handler_construct( p_vout ); /* p_vout->p_sys->capabilities |= VO_CAP_XXMC; */ XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); init_xx44_palette( &p_vout->p_sys->palette , 0 ); p_vout->p_sys->last_accel_request = 0xFFFFFFFF; xvmc_context_writer_unlock( &p_vout->p_sys->xvmc_lock ); return VLC_SUCCESS;}static int xxmc_setup_subpictures( vout_thread_t *p_vout, unsigned int width, unsigned int height ){ xvmc_capabilities_t *curCap = NULL; XvMCSubpicture *sp = NULL; if( p_vout->p_sys->contextActive ) { curCap = p_vout->p_sys->xvmc_cap + p_vout->p_sys->xvmc_cur_cap; if( (width > curCap->sub_max_width) || (height > curCap->sub_max_height) ) return VLC_EGENERIC; if( (p_vout->p_sys->xvmc_backend_subpic = (curCap->flags & XVMC_BACKEND_SUBPICTURE)) ) msg_Dbg( p_vout, "using backend subpictures." ); if (!p_vout->p_sys->subImage) { XLockDisplay( p_vout->p_sys->p_display ); msg_Dbg(p_vout, "xxmc_setup_subpictures");#ifdef HAVE_SYS_SHM_H if( p_vout->p_sys->i_shm_opcode ) { /* Create image using XShm extension */ p_vout->p_sys->subImage = CreateShmImage( p_vout, p_vout->p_sys->p_display, p_vout->p_sys->i_xvport, curCap->subPicType.id, /* VLC2X11_FOURCC( p_vout->output. i_chroma ), */ &p_vout->p_sys->subShmInfo, p_vout->output.i_width, p_vout->output.i_height ); }#endif /* HAVE_SYS_SHM_H */ XUnlockDisplay( p_vout->p_sys->p_display ); if( !p_vout->p_sys->subImage ) { msg_Dbg(p_vout, "failed allocating XvImage for supbictures" ); return VLC_EGENERIC; } } sp = xxmc_xvmc_alloc_subpicture( p_vout, &p_vout->p_sys->context, width, height, curCap->subPicType.id ); if( sp ) { init_xx44_palette( &p_vout->p_sys->palette, sp->num_palette_entries ); p_vout->p_sys->xvmc_palette = (char *) malloc( sp->num_palette_entries * sp->entry_bytes ); xxmc_xvmc_free_subpicture( p_vout, sp); if( !p_vout->p_sys->xvmc_palette ) return VLC_EGENERIC; p_vout->p_sys->hwSubpictures = 1; } } return VLC_SUCCESS;}static void xvmc_check_colorkey_properties( vout_thread_t *p_vout ){ int num,i; XvAttribute *xvmc_attributes = NULL; Atom ap; /* * Determine if the context is of "Overlay" type. If so, * check whether we can autopaint. */ p_vout->p_sys->have_xvmc_autopaint = 0; if( p_vout->p_sys->context_flags & XVMC_OVERLAID_SURFACE ) { msg_Dbg( p_vout, "check colorkey properties" ); XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); xvmc_attributes = XvMCQueryAttributes( p_vout->p_sys->p_display, &p_vout->p_sys->context, &num ); if( xvmc_attributes ) { for( i = 0; i < num; ++i ) { if( strncmp( "XV_AUTOPAINT_COLORKEY", xvmc_attributes[i].name, 21) == 0) { ap = XInternAtom( p_vout->p_sys->p_display, "XV_AUTOPAINT_COLORKEY", False ); XvMCSetAttribute( p_vout->p_sys->p_display, &p_vout->p_sys->context, ap, 1 ); /* p_vout->p_sys->props[VO_PROP_AUTOPAINT_COLORKEY].value */ p_vout->p_sys->have_xvmc_autopaint = 1; msg_Dbg( p_vout, "has xvmc autopaint" ); } } } XFree( xvmc_attributes ); XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); /* p_vout->p_sys->xvmc_xoverlay_type = X11OSD_COLORKEY; */ }#if 0 else { p_vout->p_sys->xvmc_xoverlay_type = X11OSD_SHAPED; }#endif}static void xxmc_xvmc_destroy_surfaces( vout_thread_t *p_vout ){ int i; xvmc_surface_handler_t *handler = NULL; handler = &p_vout->p_sys->xvmc_surf_handler; pthread_mutex_lock( &handler->mutex ); for( i = 0; i < XVMC_MAX_SURFACES; ++i ) { XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); if( handler->surfValid[i] ) { XvMCFlushSurface( p_vout->p_sys->p_display , handler->surfaces+i); XvMCSyncSurface( p_vout->p_sys->p_display, handler->surfaces+i ); XvMCHideSurface( p_vout->p_sys->p_display, handler->surfaces+i ); XvMCDestroySurface( p_vout->p_sys->p_display, handler->surfaces+i ); } XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); handler->surfValid[i] = 0; } pthread_mutex_unlock( &handler->mutex );}static void xxmc_xvmc_destroy_subpictures( vout_thread_t *p_vout ){ int i; xvmc_surface_handler_t *handler = NULL; handler = &p_vout->p_sys->xvmc_surf_handler; pthread_mutex_lock( &handler->mutex ); for( i = 0; i < XVMC_MAX_SUBPICTURES; ++i ) { XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); if( handler->subValid[i] ) { XvMCFlushSubpicture( p_vout->p_sys->p_display , handler->subpictures+i); XvMCSyncSubpicture( p_vout->p_sys->p_display, handler->subpictures+i ); XvMCDestroySubpicture( p_vout->p_sys->p_display, handler->subpictures+i ); } XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); handler->subValid[i] = 0; } pthread_mutex_unlock( &handler->mutex );}static XvMCSurface *xxmc_xvmc_alloc_surface( vout_thread_t *p_vout, XvMCContext *context ){ xvmc_surface_handler_t *handler = NULL; int i; handler = &p_vout->p_sys->xvmc_surf_handler; pthread_mutex_lock( &handler->mutex ); xxmc_xvmc_dump_surfaces( p_vout ); for( i = 0; i < XVMC_MAX_SURFACES; ++i ) { if( handler->surfValid[i] && !handler->surfInUse[i] ) { handler->surfInUse[i] = 1; msg_Dbg( p_vout, "reusing surface %d", i ); xxmc_xvmc_dump_surfaces( p_vout ); pthread_mutex_unlock( &handler->mutex ); return (handler->surfaces + i); } } for( i = 0; i < XVMC_MAX_SURFACES; ++i ) { if( !handler->surfInUse[i] ) { XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); if( Success != XvMCCreateSurface( p_vout->p_sys->p_display, context, handler->surfaces + i) ) { XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); pthread_mutex_unlock( &handler->mutex ); return NULL; } XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); msg_Dbg( p_vout, "created surface %d", i ); handler->surfInUse[i] = 1; handler->surfValid[i] = 1; pthread_mutex_unlock( &handler->mutex ); return (handler->surfaces + i); } } pthread_mutex_unlock( &handler->mutex ); return NULL;}void xxmc_dispose_context( vout_thread_t *p_vout ){ if( p_vout->p_sys->contextActive ) { if( p_vout->p_sys->xvmc_accel & (VLC_XVMC_ACCEL_MOCOMP | VLC_XVMC_ACCEL_IDCT) ) { xvmc_macroblocks_t *macroblocks = NULL; macroblocks = &p_vout->p_sys->macroblocks; XvMCDestroyMacroBlocks( p_vout->p_sys->p_display, ¯oblocks->macro_blocks ); XvMCDestroyBlocks( p_vout->p_sys->p_display, ¯oblocks->blocks ); } msg_Dbg( p_vout, "freeing up XvMC surfaces and subpictures" ); if( p_vout->p_sys->xvmc_palette ) free( p_vout->p_sys->xvmc_palette ); dispose_xx44_palette( &p_vout->p_sys->palette ); xxmc_xvmc_destroy_subpictures( p_vout ); xxmc_xvmc_destroy_surfaces( p_vout ); msg_Dbg(p_vout, "freeing up XvMC Context."); XLockDisplay( p_vout->p_sys->p_display ); if( p_vout->p_sys->subImage ) { XFree( p_vout->p_sys->subImage ); p_vout->p_sys->subImage = NULL; } p_vout->p_sys->subImage = NULL; XUnlockDisplay( p_vout->p_sys->p_display ); XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); XvMCDestroyContext( p_vout->p_sys->p_display, &p_vout->p_sys->context ); XVMCUNLOCKDISPLAY( p_vout->p_sys->p_display ); p_vout->p_sys->contextActive = 0; p_vout->p_sys->hwSubpictures = 0; p_vout->p_sys->xvmc_accel = 0; }}static int xxmc_find_context( vout_thread_t *p_vout, vlc_xxmc_t *xxmc, unsigned int width, unsigned int height ){ unsigned int i, k; bool found = false; xvmc_capabilities_t *curCap = NULL; unsigned int request_mpeg_flags, request_accel_flags; request_mpeg_flags = xxmc->mpeg; for( k = 0; k < NUM_ACCEL_PRIORITY; ++k ) { request_accel_flags = xxmc->acceleration & accel_priority[k]; if( !request_accel_flags ) continue; curCap = p_vout->p_sys->xvmc_cap; for( i =0; i < p_vout->p_sys->xvmc_num_cap; ++i ) { msg_Dbg( p_vout, "surface type %d, capabilities 0x%8x 0x%8x", i, curCap->mpeg_flags, curCap->accel_flags ); msg_Dbg( p_vout, "fequests: 0x%8x 0x%8x", request_mpeg_flags, request_accel_flags ); if( ( (curCap->mpeg_flags & request_mpeg_flags) == request_mpeg_flags) && (curCap->accel_flags & request_accel_flags) && (width <= curCap->max_width) && (height <= curCap->max_height) ) { found = true; break; } curCap++; } if( found ) { p_vout->p_sys->xvmc_cur_cap = i; break; } } if( found ) { p_vout->p_sys->xvmc_accel = request_accel_flags; p_vout->p_sys->unsigned_intra = (curCap->flags & XVMC_INTRA_UNSIGNED); return 1; } p_vout->p_sys->xvmc_accel = 0; return 0;}static int xxmc_create_context( vout_thread_t *p_vout, unsigned int width, unsigned int height ){ xvmc_capabilities_t *curCap = NULL; curCap = p_vout->p_sys->xvmc_cap + p_vout->p_sys->xvmc_cur_cap; msg_Dbg( p_vout, "creating new XvMC context %d", curCap->type_id ); XVMCLOCKDISPLAY( p_vout->p_sys->p_display ); if( Success == XvMCCreateContext( p_vout->p_sys->p_display, p_vout->p_sys->i_xvport, curCap->type_id, width,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -