3 * VIDIXLib - Library for VIDeo Interface for *niX
4 * This interface is introduced as universal one to MPEG decoder,
5 * BES == Back End Scaler and YUV2RGB hw accelerators.
6 * In the future it may be expanded up to capturing and audio things.
7 * Main goal of this this interface imlpementation is providing DGA
8 * everywhere where it's possible (unlike X11 and other).
9 * Copyright 2002 Nick Kurshev
11 * This interface is based on v4l2, fbvid.h, mga_vid.h projects
12 * and personally my ideas.
13 * NOTE: This interface is introduces as APP interface.
14 * Don't use it for driver.
15 * It provides multistreaming. This mean that APP can handle
16 * several streams simultaneously. (Example: Video capturing and video
17 * playback or capturing, video playback, audio encoding and so on).
25 #include <dlfcn.h> /* GLIBC specific. Exists under cygwin too! */
28 #define dlsym(h,s) GetProcAddress(h,s)
29 #define dlopen(h,s) LoadLibrary(h)
30 #define dlclose(h) FreeLibrary(h)
31 static char* dlerror(){
33 sprintf(errormsg
,"%i\n",GetLastError());
41 #if defined(__OpenBSD__) && !defined(__ELF__)
42 #define dlsym(h,s) dlsym(h, "_" s)
47 #include "../config.h"
49 static char drv_name
[FILENAME_MAX
];
51 typedef struct vdl_stream_s
54 int (*get_caps
)(vidix_capability_t
*);
55 int (*query_fourcc
)(vidix_fourcc_t
*);
56 int (*config_playback
)(vidix_playback_t
*);
57 int (*playback_on
)( void );
58 int (*playback_off
)( void );
59 /* Functions below can be missed in driver ;) */
61 void (*destroy
)(void);
62 int (*frame_sel
)( unsigned frame_idx
);
63 int (*get_eq
)( vidix_video_eq_t
* );
64 int (*set_eq
)( const vidix_video_eq_t
* );
65 int (*get_deint
)( vidix_deinterlace_t
* );
66 int (*set_deint
)( const vidix_deinterlace_t
* );
67 int (*copy_frame
)( const vidix_dma_t
* );
68 int (*get_gkey
)( vidix_grkey_t
* );
69 int (*set_gkey
)( const vidix_grkey_t
* );
70 int (*get_num_fx
)( unsigned * );
71 int (*get_fx
)( vidix_oem_fx_t
* );
72 int (*set_fx
)( const vidix_oem_fx_t
* );
75 #define t_vdl(p) (((vdl_stream_t *)p))
77 extern unsigned vdlGetVersion( void )
82 static int vdl_fill_driver(VDL_HANDLE stream
)
84 t_vdl(stream
)->init
= dlsym(t_vdl(stream
)->handle
,"vixInit");
85 t_vdl(stream
)->destroy
= dlsym(t_vdl(stream
)->handle
,"vixDestroy");
86 t_vdl(stream
)->get_caps
= dlsym(t_vdl(stream
)->handle
,"vixGetCapability");
87 t_vdl(stream
)->query_fourcc
= dlsym(t_vdl(stream
)->handle
,"vixQueryFourcc");
88 t_vdl(stream
)->config_playback
= dlsym(t_vdl(stream
)->handle
,"vixConfigPlayback");
89 t_vdl(stream
)->playback_on
= dlsym(t_vdl(stream
)->handle
,"vixPlaybackOn");
90 t_vdl(stream
)->playback_off
= dlsym(t_vdl(stream
)->handle
,"vixPlaybackOff");
91 t_vdl(stream
)->frame_sel
= dlsym(t_vdl(stream
)->handle
,"vixPlaybackFrameSelect");
92 t_vdl(stream
)->get_eq
= dlsym(t_vdl(stream
)->handle
,"vixPlaybackGetEq");
93 t_vdl(stream
)->set_eq
= dlsym(t_vdl(stream
)->handle
,"vixPlaybackSetEq");
94 t_vdl(stream
)->get_gkey
= dlsym(t_vdl(stream
)->handle
,"vixGetGrKeys");
95 t_vdl(stream
)->set_gkey
= dlsym(t_vdl(stream
)->handle
,"vixSetGrKeys");
96 t_vdl(stream
)->get_deint
= dlsym(t_vdl(stream
)->handle
,"vixPlaybackGetDeint");
97 t_vdl(stream
)->set_deint
= dlsym(t_vdl(stream
)->handle
,"vixPlaybackSetDeint");
98 t_vdl(stream
)->copy_frame
= dlsym(t_vdl(stream
)->handle
,"vixPlaybackCopyFrame");
99 t_vdl(stream
)->get_num_fx
= dlsym(t_vdl(stream
)->handle
,"vixQueryNumOemEffects");
100 t_vdl(stream
)->get_fx
= dlsym(t_vdl(stream
)->handle
,"vixGetOemEffect");
101 t_vdl(stream
)->set_fx
= dlsym(t_vdl(stream
)->handle
,"vixSetOemEffect");
102 /* check driver viability */
103 if(!( t_vdl(stream
)->get_caps
&& t_vdl(stream
)->query_fourcc
&&
104 t_vdl(stream
)->config_playback
&& t_vdl(stream
)->playback_on
&&
105 t_vdl(stream
)->playback_off
))
107 printf("vidixlib: Incomplete driver: some of essential features are missed in it.\n");
114 #define RTLD_GLOBAL RTLD_LAZY
117 #define RTLD_NOW RTLD_LAZY
120 static int vdl_probe_driver(VDL_HANDLE stream
,const char *path
,const char *name
,unsigned cap
,int verbose
)
122 vidix_capability_t vid_cap
;
123 unsigned (*_ver
)(void);
124 int (*_probe
)(int,int);
125 int (*_cap
)(vidix_capability_t
*);
126 strlcpy(drv_name
,path
, sizeof( drv_name
));
127 strlcat(drv_name
,name
, sizeof( drv_name
));
128 if(verbose
) printf("vidixlib: PROBING: %s\n",drv_name
);
129 if(!(t_vdl(stream
)->handle
= dlopen(drv_name
,RTLD_LAZY
|RTLD_GLOBAL
)))
131 if(verbose
) printf("vidixlib: %s not driver: %s\n",drv_name
,dlerror());
134 _ver
= dlsym(t_vdl(stream
)->handle
,"vixGetVersion");
135 _probe
= dlsym(t_vdl(stream
)->handle
,"vixProbe");
136 _cap
= dlsym(t_vdl(stream
)->handle
,"vixGetCapability");
139 if((*_ver
)() != VIDIX_VERSION
)
141 if(verbose
) printf("vidixlib: %s has wrong version\n",drv_name
);
143 dlclose(t_vdl(stream
)->handle
);
144 t_vdl(stream
)->handle
= 0;
151 if(verbose
) printf("vidixlib: %s has no function definition\n",drv_name
);
154 if(_probe
) { if((*_probe
)(verbose
,PROBE_NORMAL
) != 0) goto err
; }
156 if(_cap
) { if((*_cap
)(&vid_cap
) != 0) goto err
; }
158 if((vid_cap
.type
& cap
) != cap
)
160 if(verbose
) printf("vidixlib: Found %s but has no required capability\n",drv_name
);
163 if(verbose
) printf("vidixlib: %s probed o'k\n",drv_name
);
167 static int vdl_find_driver(VDL_HANDLE stream
,const char *path
,unsigned cap
,int verbose
)
172 if(!(dstream
= opendir(path
))) return 0;
175 name
= readdir(dstream
);
178 if(name
->d_name
[0] != '.')
179 if(vdl_probe_driver(stream
,path
,name
->d_name
,cap
,verbose
)) break;
187 VDL_HANDLE
vdlOpen(const char *path
,const char *name
,unsigned cap
,int verbose
)
189 vdl_stream_t
*stream
;
191 if(!(stream
= malloc(sizeof(vdl_stream_t
)))) return NULL
;
192 memset(stream
,0,sizeof(vdl_stream_t
));
195 unsigned (*ver
)(void);
196 int (*probe
)(int,int);
197 unsigned version
= 0;
198 strlcpy(drv_name
,path
, sizeof( drv_name
));
199 strlcat(drv_name
,name
, sizeof( drv_name
));
200 if(!(t_vdl(stream
)->handle
= dlopen(drv_name
,RTLD_NOW
|RTLD_GLOBAL
)))
203 printf("vidixlib: dlopen error: %s\n", dlerror());
208 ver
= dlsym(t_vdl(stream
)->handle
,"vixGetVersion");
209 if(ver
) version
= (*ver
)();
210 if(version
!= VIDIX_VERSION
)
213 if(t_vdl(stream
)->handle
) dlclose(t_vdl(stream
)->handle
);
216 probe
= dlsym(t_vdl(stream
)->handle
,"vixProbe");
217 if(probe
) { if((*probe
)(verbose
,PROBE_FORCE
)!=0) goto drv_err
; }
220 if(!vdl_fill_driver(stream
)) goto drv_err
;
224 if(vdl_find_driver(stream
,path
,cap
,verbose
))
226 if(verbose
) printf("vidixlib: will use %s driver\n",drv_name
);
231 if(t_vdl(stream
)->init
)
233 if(verbose
) printf("vidixlib: Attempt to initialize driver at: %p\n",t_vdl(stream
)->init
);
234 if((errcode
=t_vdl(stream
)->init())!=0)
236 if(verbose
) printf("vidixlib: Can't init driver: %s\n",strerror(errcode
));
240 if(verbose
) printf("vidixlib: '%s'successfully loaded\n",drv_name
);
244 void vdlClose(VDL_HANDLE stream
)
246 if(t_vdl(stream
)->destroy
) t_vdl(stream
)->destroy();
247 dlclose(t_vdl(stream
)->handle
);
248 memset(stream
,0,sizeof(vdl_stream_t
)); /* <- it's not stupid */
252 int vdlGetCapability(VDL_HANDLE handle
, vidix_capability_t
*cap
)
254 return t_vdl(handle
)->get_caps(cap
);
257 #define MPLAYER_IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8))
258 #define MPLAYER_IMGFMT_BGR (('B'<<24)|('G'<<16)|('R'<<8))
259 #define MPLAYER_IMGFMT_RGB_MASK 0xFFFFFF00
261 static uint32_t normalize_fourcc(uint32_t fourcc
)
263 if((fourcc
& MPLAYER_IMGFMT_RGB_MASK
) == (MPLAYER_IMGFMT_RGB
|0) ||
264 (fourcc
& MPLAYER_IMGFMT_RGB_MASK
) == (MPLAYER_IMGFMT_BGR
|0))
265 return bswap_32(fourcc
);
269 int vdlQueryFourcc(VDL_HANDLE handle
,vidix_fourcc_t
*f
)
271 f
->fourcc
= normalize_fourcc(f
->fourcc
);
272 return t_vdl(handle
)->query_fourcc(f
);
275 int vdlConfigPlayback(VDL_HANDLE handle
,vidix_playback_t
*p
)
277 p
->fourcc
= normalize_fourcc(p
->fourcc
);
278 return t_vdl(handle
)->config_playback(p
);
281 int vdlPlaybackOn(VDL_HANDLE handle
)
283 return t_vdl(handle
)->playback_on();
286 int vdlPlaybackOff(VDL_HANDLE handle
)
288 return t_vdl(handle
)->playback_off();
291 int vdlPlaybackFrameSelect(VDL_HANDLE handle
, unsigned frame_idx
)
293 return t_vdl(handle
)->frame_sel
? t_vdl(handle
)->frame_sel(frame_idx
) : ENOSYS
;
296 int vdlPlaybackGetEq(VDL_HANDLE handle
, vidix_video_eq_t
* e
)
298 return t_vdl(handle
)->get_eq
? t_vdl(handle
)->get_eq(e
) : ENOSYS
;
301 int vdlPlaybackSetEq(VDL_HANDLE handle
, const vidix_video_eq_t
* e
)
303 return t_vdl(handle
)->set_eq
? t_vdl(handle
)->set_eq(e
) : ENOSYS
;
306 int vdlPlaybackCopyFrame(VDL_HANDLE handle
, const vidix_dma_t
* f
)
308 return t_vdl(handle
)->copy_frame
? t_vdl(handle
)->copy_frame(f
) : ENOSYS
;
311 int vdlGetGrKeys(VDL_HANDLE handle
, vidix_grkey_t
* k
)
313 return t_vdl(handle
)->get_gkey
? t_vdl(handle
)->get_gkey(k
) : ENOSYS
;
316 int vdlSetGrKeys(VDL_HANDLE handle
, const vidix_grkey_t
* k
)
318 return t_vdl(handle
)->set_gkey
? t_vdl(handle
)->set_gkey(k
) : ENOSYS
;
321 int vdlPlaybackGetDeint(VDL_HANDLE handle
, vidix_deinterlace_t
* d
)
323 return t_vdl(handle
)->get_deint
? t_vdl(handle
)->get_deint(d
) : ENOSYS
;
326 int vdlPlaybackSetDeint(VDL_HANDLE handle
, const vidix_deinterlace_t
* d
)
328 return t_vdl(handle
)->set_deint
? t_vdl(handle
)->set_deint(d
) : ENOSYS
;
331 int vdlQueryNumOemEffects(VDL_HANDLE handle
, unsigned * number
)
333 return t_vdl(handle
)->get_num_fx
? t_vdl(handle
)->get_num_fx(number
) : ENOSYS
;
336 int vdlGetOemEffect(VDL_HANDLE handle
, vidix_oem_fx_t
* f
)
338 return t_vdl(handle
)->get_fx
? t_vdl(handle
)->get_fx(f
) : ENOSYS
;
341 int vdlSetOemEffect(VDL_HANDLE handle
, const vidix_oem_fx_t
* f
)
343 return t_vdl(handle
)->set_fx
? t_vdl(handle
)->set_fx(f
) : ENOSYS
;