diff options
Diffstat (limited to 'src/video_out/vidix/vidixlib.c')
| -rw-r--r-- | src/video_out/vidix/vidixlib.c | 167 |
1 files changed, 109 insertions, 58 deletions
diff --git a/src/video_out/vidix/vidixlib.c b/src/video_out/vidix/vidixlib.c index 66154fff8..2c57eb4f5 100644 --- a/src/video_out/vidix/vidixlib.c +++ b/src/video_out/vidix/vidixlib.c @@ -25,14 +25,10 @@ #include <dlfcn.h> /* GLIBC specific. Exists under cygwin too! */ #include <dirent.h> -#if defined(__OpenBSD__) && !defined(__ELF__) -#define dlsym(h,s) dlsym(h, "_" s) -#endif - #include "vidixlib.h" #include "bswap.h" -static char drv_name[FILENAME_MAX]; +#define t_vdl(p) (((vdl_stream_t *)p)) typedef struct vdl_stream_s { @@ -43,7 +39,7 @@ typedef struct vdl_stream_s int (*playback_on)( void ); int (*playback_off)( void ); /* Functions below can be missed in driver ;) */ - int (*init)(void); + int (*init)(const char *); void (*destroy)(void); int (*frame_sel)( unsigned frame_idx ); int (*get_eq)( vidix_video_eq_t * ); @@ -59,34 +55,65 @@ typedef struct vdl_stream_s int (*set_fx)( const vidix_oem_fx_t * ); }vdl_stream_t; -#define t_vdl(p) (((vdl_stream_t *)p)) +static char drv_name[FILENAME_MAX]; +static int dl_idx = -1; +/* currently available driver for static linking */ +static const char* const drv_snames[] = { +#ifdef VIDIX_BUILD_STATIC + "genfb_", + "mach64_", + "mga_crtc2_", + "mga_", + "nvidia_", + "pm2_", + "pm3_", + "radeo_", + "rage128_", +#endif + NULL +}; extern unsigned vdlGetVersion( void ) { return VIDIX_VERSION; } +static void* dlsymm(void* handle, const char* fce) +{ + char b[100]; +#if defined(__OpenBSD__) && !defined(__ELF__) + b[0] = '_'; + b[1] = 0; +#else + b[0] = 0; +#endif + if (dl_idx >= 0) strcat(b, drv_snames[dl_idx]); + strcat(b, fce); + //printf("Handle %p %s\n", handle, b); + return dlsym(handle, b); +} + static int vdl_fill_driver(VDL_HANDLE stream) { - t_vdl(stream)->init = dlsym(t_vdl(stream)->handle,"vixInit"); - t_vdl(stream)->destroy = dlsym(t_vdl(stream)->handle,"vixDestroy"); - t_vdl(stream)->get_caps = dlsym(t_vdl(stream)->handle,"vixGetCapability"); - t_vdl(stream)->query_fourcc = dlsym(t_vdl(stream)->handle,"vixQueryFourcc"); - t_vdl(stream)->config_playback= dlsym(t_vdl(stream)->handle,"vixConfigPlayback"); - t_vdl(stream)->playback_on = dlsym(t_vdl(stream)->handle,"vixPlaybackOn"); - t_vdl(stream)->playback_off = dlsym(t_vdl(stream)->handle,"vixPlaybackOff"); - t_vdl(stream)->frame_sel = dlsym(t_vdl(stream)->handle,"vixPlaybackFrameSelect"); - t_vdl(stream)->get_eq = dlsym(t_vdl(stream)->handle,"vixPlaybackGetEq"); - t_vdl(stream)->set_eq = dlsym(t_vdl(stream)->handle,"vixPlaybackSetEq"); - t_vdl(stream)->get_gkey = dlsym(t_vdl(stream)->handle,"vixGetGrKeys"); - t_vdl(stream)->set_gkey = dlsym(t_vdl(stream)->handle,"vixSetGrKeys"); - t_vdl(stream)->get_deint = dlsym(t_vdl(stream)->handle,"vixPlaybackGetDeint"); - t_vdl(stream)->set_deint = dlsym(t_vdl(stream)->handle,"vixPlaybackSetDeint"); - t_vdl(stream)->copy_frame = dlsym(t_vdl(stream)->handle,"vixPlaybackCopyFrame"); - t_vdl(stream)->query_dma = dlsym(t_vdl(stream)->handle,"vixQueryDMAStatus"); - t_vdl(stream)->get_num_fx = dlsym(t_vdl(stream)->handle,"vixQueryNumOemEffects"); - t_vdl(stream)->get_fx = dlsym(t_vdl(stream)->handle,"vixGetOemEffect"); - t_vdl(stream)->set_fx = dlsym(t_vdl(stream)->handle,"vixSetOemEffect"); + t_vdl(stream)->init = dlsymm(t_vdl(stream)->handle,"vixInit"); + t_vdl(stream)->destroy = dlsymm(t_vdl(stream)->handle,"vixDestroy"); + t_vdl(stream)->get_caps = dlsymm(t_vdl(stream)->handle,"vixGetCapability"); + t_vdl(stream)->query_fourcc = dlsymm(t_vdl(stream)->handle,"vixQueryFourcc"); + t_vdl(stream)->config_playback= dlsymm(t_vdl(stream)->handle,"vixConfigPlayback"); + t_vdl(stream)->playback_on = dlsymm(t_vdl(stream)->handle,"vixPlaybackOn"); + t_vdl(stream)->playback_off = dlsymm(t_vdl(stream)->handle,"vixPlaybackOff"); + t_vdl(stream)->frame_sel = dlsymm(t_vdl(stream)->handle,"vixPlaybackFrameSelect"); + t_vdl(stream)->get_eq = dlsymm(t_vdl(stream)->handle,"vixPlaybackGetEq"); + t_vdl(stream)->set_eq = dlsymm(t_vdl(stream)->handle,"vixPlaybackSetEq"); + t_vdl(stream)->get_gkey = dlsymm(t_vdl(stream)->handle,"vixGetGrKeys"); + t_vdl(stream)->set_gkey = dlsymm(t_vdl(stream)->handle,"vixSetGrKeys"); + t_vdl(stream)->get_deint = dlsymm(t_vdl(stream)->handle,"vixPlaybackGetDeint"); + t_vdl(stream)->set_deint = dlsymm(t_vdl(stream)->handle,"vixPlaybackSetDeint"); + t_vdl(stream)->copy_frame = dlsymm(t_vdl(stream)->handle,"vixPlaybackCopyFrame"); + t_vdl(stream)->query_dma = dlsymm(t_vdl(stream)->handle,"vixQueryDMAStatus"); + t_vdl(stream)->get_num_fx = dlsymm(t_vdl(stream)->handle,"vixQueryNumOemEffects"); + t_vdl(stream)->get_fx = dlsymm(t_vdl(stream)->handle,"vixGetOemEffect"); + t_vdl(stream)->set_fx = dlsymm(t_vdl(stream)->handle,"vixSetOemEffect"); /* check driver viability */ if(!( t_vdl(stream)->get_caps && t_vdl(stream)->query_fourcc && t_vdl(stream)->config_playback && t_vdl(stream)->playback_on && @@ -114,22 +141,34 @@ static int vdl_probe_driver(VDL_HANDLE stream,const char *path,const char *name, strcpy(drv_name,path); strcat(drv_name,name); if(verbose) printf("vidixlib: PROBING: %s\n",drv_name); - if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_LAZY|RTLD_GLOBAL))) + { - if(verbose) printf("vidixlib: %s not driver: %s\n",drv_name,dlerror()); - return 0; + const char* slash = strrchr(drv_name, '/'); + if (slash) { + for (dl_idx = 0; drv_snames[dl_idx]; dl_idx++) { + if (!strncmp(slash + 1, drv_snames[dl_idx], strlen(drv_snames[dl_idx]))) + break; // locate the name + } + if (!drv_snames[dl_idx]) dl_idx = -1; + } } - _ver = dlsym(t_vdl(stream)->handle,"vixGetVersion"); - _probe = dlsym(t_vdl(stream)->handle,"vixProbe"); - _cap = dlsym(t_vdl(stream)->handle,"vixGetCapability"); - if(_ver) + if (dl_idx < 0) + if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_LAZY|RTLD_GLOBAL))) { + if(verbose) printf("vidixlib: %s not driver: %s\n",drv_name,dlerror()); + return 0; + } + _ver = dlsymm(t_vdl(stream)->handle,"vixGetVersion"); + _probe = dlsymm(t_vdl(stream)->handle,"vixProbe"); + _cap = dlsymm(t_vdl(stream)->handle,"vixGetCapability"); + if(_ver) { - if((*_ver)() != VIDIX_VERSION) - { + if((*_ver)() != VIDIX_VERSION) + { if(verbose) printf("vidixlib: %s has wrong version\n",drv_name); err: dlclose(t_vdl(stream)->handle); t_vdl(stream)->handle = 0; + dl_idx = -1; return 0; } } @@ -161,10 +200,10 @@ static int vdl_find_driver(VDL_HANDLE stream,const char *path,unsigned cap,int v while(!done) { name = readdir(dstream); - if(name) - { + if(name) + { if(name->d_name[0] != '.') - if(vdl_probe_driver(stream,path,name->d_name,cap,verbose)) break; + if(vdl_probe_driver(stream,path,name->d_name,cap,verbose)) break; } else done = 1; } @@ -175,6 +214,7 @@ static int vdl_find_driver(VDL_HANDLE stream,const char *path,unsigned cap,int v VDL_HANDLE vdlOpen(const char *path,const char *name,unsigned cap,int verbose) { vdl_stream_t *stream; + const char *drv_args=NULL; int errcode; if(!(stream = malloc(sizeof(vdl_stream_t)))) return NULL; memset(stream,0,sizeof(vdl_stream_t)); @@ -183,29 +223,39 @@ VDL_HANDLE vdlOpen(const char *path,const char *name,unsigned cap,int verbose) unsigned (*ver)(void); int (*probe)(int,int); unsigned version = 0; + unsigned char *arg_sep; + arg_sep = strchr(name,':'); + if(arg_sep) { *arg_sep='\0'; drv_args = &arg_sep[1]; } strcpy(drv_name,path); strcat(drv_name,name); - if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_NOW|RTLD_GLOBAL))) { - if (verbose) - printf("vidixlib: dlopen error: %s\n", dlerror()); - err: - free(stream); - return NULL; + const char* slash = strrchr(drv_name, '/'); + if (slash) { + for (dl_idx = 0; drv_snames[dl_idx]; dl_idx++) { + if (!strncmp(slash + 1, drv_snames[dl_idx], strlen(drv_snames[dl_idx]))) + break; // locate the name + } + if (!drv_snames[dl_idx]) dl_idx = -1; + } } - ver = dlsym(t_vdl(stream)->handle,"vixGetVersion"); + if (dl_idx < 0) + if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_NOW|RTLD_GLOBAL))) + { + if (verbose) + printf("vidixlib: dlopen error: %s\n", dlerror()); + err: + vdlClose(stream); + return NULL; + } + ver = dlsymm(t_vdl(stream)->handle,"vixGetVersion"); if(ver) version = (*ver)(); if(version != VIDIX_VERSION) - { - drv_err: - if(t_vdl(stream)->handle) dlclose(t_vdl(stream)->handle); goto err; - } - probe = dlsym(t_vdl(stream)->handle,"vixProbe"); - if(probe) { if((*probe)(verbose,PROBE_FORCE)!=0) goto drv_err; } - else goto drv_err; + probe = dlsymm(t_vdl(stream)->handle,"vixProbe"); + if(probe) { if((*probe)(verbose,PROBE_FORCE)!=0) goto err; } + else goto err; fill: - if(!vdl_fill_driver(stream)) goto drv_err; + if(!vdl_fill_driver(stream)) goto err; goto ok; } else @@ -213,18 +263,18 @@ VDL_HANDLE vdlOpen(const char *path,const char *name,unsigned cap,int verbose) { if(verbose) printf("vidixlib: will use %s driver\n",drv_name); goto fill; - } + } else goto err; ok: if(t_vdl(stream)->init) { if(verbose) printf("vidixlib: Attempt to initialize driver at: %p\n",t_vdl(stream)->init); - if((errcode=t_vdl(stream)->init())!=0) + if((errcode=t_vdl(stream)->init(drv_args))!=0) { if(verbose) printf("vidixlib: Can't init driver: %s\n",strerror(errcode)); - goto drv_err; + goto err; } - } + } if(verbose) printf("vidixlib: '%s'successfully loaded\n",drv_name); return stream; } @@ -232,9 +282,10 @@ VDL_HANDLE vdlOpen(const char *path,const char *name,unsigned cap,int verbose) void vdlClose(VDL_HANDLE stream) { if(t_vdl(stream)->destroy) t_vdl(stream)->destroy(); - dlclose(t_vdl(stream)->handle); + if(t_vdl(stream)->handle) dlclose(t_vdl(stream)->handle); memset(stream,0,sizeof(vdl_stream_t)); /* <- it's not stupid */ free(stream); + dl_idx = -1; } int vdlGetCapability(VDL_HANDLE handle, vidix_capability_t *cap) |
