Mercurial > mplayer.hg
annotate vidix/vidixlib.c @ 12334:eeddcef4fb08
"hard" frame duplication for mencoder. this finally makes it possible
to generate valid mpeg output from avi's that have duplicate frames in
them, or when using inverse telecine filters. to use it, put the
"harddup" filter at the end of your filter chain.
author | rfelker |
---|---|
date | Wed, 28 Apr 2004 04:02:46 +0000 |
parents | 285e298968de |
children | 9a495bdc3a1e |
rev | line source |
---|---|
3991 | 1 /* |
2 * vidixlib.c | |
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 | |
10 * Licence: GPL | |
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). | |
18 */ | |
19 #include <stdlib.h> | |
20 #include <stdio.h> | |
21 #include <errno.h> | |
22 #include <string.h> | |
23 | |
10982 | 24 #ifndef WIN32 |
3991 | 25 #include <dlfcn.h> /* GLIBC specific. Exists under cygwin too! */ |
10982 | 26 #else |
27 #include <windows.h> | |
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(){ | |
32 char errormsg[10]; | |
33 sprintf(errormsg,"%i\n",GetLastError()); | |
34 return errormsg; | |
35 } | |
36 #endif | |
37 | |
38 | |
3991 | 39 #include <dirent.h> |
40 | |
6130
e9a309486f18
openbsd a.out needs underscore for dlsym - patch by Bj«Órn Sandell <biorn@dce.chalmers.se>
arpi
parents:
5872
diff
changeset
|
41 #if defined(__OpenBSD__) && !defined(__ELF__) |
e9a309486f18
openbsd a.out needs underscore for dlsym - patch by Bj«Órn Sandell <biorn@dce.chalmers.se>
arpi
parents:
5872
diff
changeset
|
42 #define dlsym(h,s) dlsym(h, "_" s) |
e9a309486f18
openbsd a.out needs underscore for dlsym - patch by Bj«Órn Sandell <biorn@dce.chalmers.se>
arpi
parents:
5872
diff
changeset
|
43 #endif |
e9a309486f18
openbsd a.out needs underscore for dlsym - patch by Bj«Órn Sandell <biorn@dce.chalmers.se>
arpi
parents:
5872
diff
changeset
|
44 |
3991 | 45 #include "vidixlib.h" |
4539 | 46 #include "../bswap.h" |
3991 | 47 |
4011 | 48 static char drv_name[FILENAME_MAX]; |
3991 | 49 |
50 typedef struct vdl_stream_s | |
51 { | |
52 void * handle; | |
53 int (*get_caps)(vidix_capability_t *); | |
54 int (*query_fourcc)(vidix_fourcc_t *); | |
3995 | 55 int (*config_playback)(vidix_playback_t *); |
3991 | 56 int (*playback_on)( void ); |
57 int (*playback_off)( void ); | |
58 /* Functions below can be missed in driver ;) */ | |
59 int (*init)(void); | |
60 void (*destroy)(void); | |
61 int (*frame_sel)( unsigned frame_idx ); | |
62 int (*get_eq)( vidix_video_eq_t * ); | |
63 int (*set_eq)( const vidix_video_eq_t * ); | |
4191 | 64 int (*get_deint)( vidix_deinterlace_t * ); |
65 int (*set_deint)( const vidix_deinterlace_t * ); | |
3991 | 66 int (*copy_frame)( const vidix_dma_t * ); |
4070
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
67 int (*get_gkey)( vidix_grkey_t * ); |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
68 int (*set_gkey)( const vidix_grkey_t * ); |
4191 | 69 int (*get_num_fx)( unsigned * ); |
70 int (*get_fx)( vidix_oem_fx_t * ); | |
71 int (*set_fx)( const vidix_oem_fx_t * ); | |
3991 | 72 }vdl_stream_t; |
73 | |
74 #define t_vdl(p) (((vdl_stream_t *)p)) | |
75 | |
76 extern unsigned vdlGetVersion( void ) | |
77 { | |
78 return VIDIX_VERSION; | |
79 } | |
80 | |
81 static int vdl_fill_driver(VDL_HANDLE stream) | |
82 { | |
83 t_vdl(stream)->init = dlsym(t_vdl(stream)->handle,"vixInit"); | |
84 t_vdl(stream)->destroy = dlsym(t_vdl(stream)->handle,"vixDestroy"); | |
85 t_vdl(stream)->get_caps = dlsym(t_vdl(stream)->handle,"vixGetCapability"); | |
86 t_vdl(stream)->query_fourcc = dlsym(t_vdl(stream)->handle,"vixQueryFourcc"); | |
87 t_vdl(stream)->config_playback= dlsym(t_vdl(stream)->handle,"vixConfigPlayback"); | |
88 t_vdl(stream)->playback_on = dlsym(t_vdl(stream)->handle,"vixPlaybackOn"); | |
89 t_vdl(stream)->playback_off = dlsym(t_vdl(stream)->handle,"vixPlaybackOff"); | |
90 t_vdl(stream)->frame_sel = dlsym(t_vdl(stream)->handle,"vixPlaybackFrameSelect"); | |
91 t_vdl(stream)->get_eq = dlsym(t_vdl(stream)->handle,"vixPlaybackGetEq"); | |
92 t_vdl(stream)->set_eq = dlsym(t_vdl(stream)->handle,"vixPlaybackSetEq"); | |
4070
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
93 t_vdl(stream)->get_gkey = dlsym(t_vdl(stream)->handle,"vixGetGrKeys"); |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
94 t_vdl(stream)->set_gkey = dlsym(t_vdl(stream)->handle,"vixSetGrKeys"); |
4191 | 95 t_vdl(stream)->get_deint = dlsym(t_vdl(stream)->handle,"vixPlaybackGetDeint"); |
96 t_vdl(stream)->set_deint = dlsym(t_vdl(stream)->handle,"vixPlaybackSetDeint"); | |
3991 | 97 t_vdl(stream)->copy_frame = dlsym(t_vdl(stream)->handle,"vixPlaybackCopyFrame"); |
4191 | 98 t_vdl(stream)->get_num_fx = dlsym(t_vdl(stream)->handle,"vixQueryNumOemEffects"); |
99 t_vdl(stream)->get_fx = dlsym(t_vdl(stream)->handle,"vixGetOemEffect"); | |
100 t_vdl(stream)->set_fx = dlsym(t_vdl(stream)->handle,"vixSetOemEffect"); | |
3991 | 101 /* check driver viability */ |
3995 | 102 if(!( t_vdl(stream)->get_caps && t_vdl(stream)->query_fourcc && |
103 t_vdl(stream)->config_playback && t_vdl(stream)->playback_on && | |
104 t_vdl(stream)->playback_off)) | |
4011 | 105 { |
4509
90386125ec1f
using dlerror() instead strerror(), displays unresolved symbol messages
alex
parents:
4191
diff
changeset
|
106 printf("vidixlib: Incomplete driver: some of essential features are missed in it.\n"); |
4011 | 107 return 0; |
108 } | |
3991 | 109 return 1; |
110 } | |
111 | |
5872 | 112 #ifndef RTLD_GLOBAL |
113 #define RTLD_GLOBAL RTLD_LAZY | |
114 #endif | |
115 #ifndef RTLD_NOW | |
116 #define RTLD_NOW RTLD_LAZY | |
117 #endif | |
118 | |
3995 | 119 static int vdl_probe_driver(VDL_HANDLE stream,const char *path,const char *name,unsigned cap,int verbose) |
3991 | 120 { |
121 vidix_capability_t vid_cap; | |
122 unsigned (*_ver)(void); | |
4191 | 123 int (*_probe)(int,int); |
3991 | 124 int (*_cap)(vidix_capability_t*); |
125 strcpy(drv_name,path); | |
126 strcat(drv_name,name); | |
4008 | 127 if(verbose) printf("vidixlib: PROBING: %s\n",drv_name); |
4011 | 128 if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_LAZY|RTLD_GLOBAL))) |
129 { | |
4509
90386125ec1f
using dlerror() instead strerror(), displays unresolved symbol messages
alex
parents:
4191
diff
changeset
|
130 if(verbose) printf("vidixlib: %s not driver: %s\n",drv_name,dlerror()); |
4011 | 131 return 0; |
132 } | |
3991 | 133 _ver = dlsym(t_vdl(stream)->handle,"vixGetVersion"); |
134 _probe = dlsym(t_vdl(stream)->handle,"vixProbe"); | |
135 _cap = dlsym(t_vdl(stream)->handle,"vixGetCapability"); | |
4008 | 136 if(_ver) |
137 { | |
138 if((*_ver)() != VIDIX_VERSION) | |
139 { | |
140 if(verbose) printf("vidixlib: %s has wrong version\n",drv_name); | |
141 err: | |
142 dlclose(t_vdl(stream)->handle); | |
143 t_vdl(stream)->handle = 0; | |
144 return 0; | |
145 } | |
146 } | |
147 else | |
148 { | |
149 fatal_err: | |
150 if(verbose) printf("vidixlib: %s has no function definition\n",drv_name); | |
151 goto err; | |
152 } | |
4191 | 153 if(_probe) { if((*_probe)(verbose,PROBE_NORMAL) != 0) goto err; } |
4008 | 154 else goto fatal_err; |
3991 | 155 if(_cap) { if((*_cap)(&vid_cap) != 0) goto err; } |
4008 | 156 else goto fatal_err; |
4011 | 157 if((vid_cap.type & cap) != cap) |
158 { | |
159 if(verbose) printf("vidixlib: Found %s but has no required capability\n",drv_name); | |
160 goto err; | |
161 } | |
4008 | 162 if(verbose) printf("vidixlib: %s probed o'k\n",drv_name); |
3991 | 163 return 1; |
164 } | |
165 | |
3995 | 166 static int vdl_find_driver(VDL_HANDLE stream,const char *path,unsigned cap,int verbose) |
3991 | 167 { |
168 DIR *dstream; | |
169 struct dirent *name; | |
170 int done = 0; | |
171 if(!(dstream = opendir(path))) return 0; | |
172 while(!done) | |
173 { | |
174 name = readdir(dstream); | |
4008 | 175 if(name) |
176 { | |
177 if(name->d_name[0] != '.') | |
178 if(vdl_probe_driver(stream,path,name->d_name,cap,verbose)) break; | |
179 } | |
3991 | 180 else done = 1; |
181 } | |
182 closedir(dstream); | |
183 return done?0:1; | |
184 } | |
185 | |
3995 | 186 VDL_HANDLE vdlOpen(const char *path,const char *name,unsigned cap,int verbose) |
3991 | 187 { |
188 vdl_stream_t *stream; | |
4011 | 189 int errcode; |
3991 | 190 if(!(stream = malloc(sizeof(vdl_stream_t)))) return NULL; |
191 memset(stream,0,sizeof(vdl_stream_t)); | |
192 if(name) | |
193 { | |
194 unsigned (*ver)(void); | |
4191 | 195 int (*probe)(int,int); |
3991 | 196 unsigned version = 0; |
197 strcpy(drv_name,path); | |
198 strcat(drv_name,name); | |
199 if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_NOW|RTLD_GLOBAL))) | |
200 { | |
4509
90386125ec1f
using dlerror() instead strerror(), displays unresolved symbol messages
alex
parents:
4191
diff
changeset
|
201 if (verbose) |
90386125ec1f
using dlerror() instead strerror(), displays unresolved symbol messages
alex
parents:
4191
diff
changeset
|
202 printf("vidixlib: dlopen error: %s\n", dlerror()); |
3991 | 203 err: |
204 free(stream); | |
205 return NULL; | |
206 } | |
207 ver = dlsym(t_vdl(stream)->handle,"vixGetVersion"); | |
208 if(ver) version = (*ver)(); | |
209 if(version != VIDIX_VERSION) | |
210 { | |
211 drv_err: | |
212 if(t_vdl(stream)->handle) dlclose(t_vdl(stream)->handle); | |
213 goto err; | |
214 } | |
3995 | 215 probe = dlsym(t_vdl(stream)->handle,"vixProbe"); |
4191 | 216 if(probe) { if((*probe)(verbose,PROBE_FORCE)!=0) goto drv_err; } |
3995 | 217 else goto drv_err; |
3991 | 218 fill: |
219 if(!vdl_fill_driver(stream)) goto drv_err; | |
4011 | 220 goto ok; |
3991 | 221 } |
222 else | |
4011 | 223 if(vdl_find_driver(stream,path,cap,verbose)) |
224 { | |
225 if(verbose) printf("vidixlib: will use %s driver\n",drv_name); | |
226 goto fill; | |
227 } | |
228 else goto err; | |
229 ok: | |
230 if(t_vdl(stream)->init) | |
231 { | |
232 if(verbose) printf("vidixlib: Attempt to initialize driver at: %p\n",t_vdl(stream)->init); | |
233 if((errcode=t_vdl(stream)->init())!=0) | |
234 { | |
235 if(verbose) printf("vidixlib: Can't init driver: %s\n",strerror(errcode)); | |
236 goto drv_err; | |
237 } | |
238 } | |
239 if(verbose) printf("vidixlib: '%s'successfully loaded\n",drv_name); | |
3991 | 240 return stream; |
241 } | |
242 | |
243 void vdlClose(VDL_HANDLE stream) | |
244 { | |
245 if(t_vdl(stream)->destroy) t_vdl(stream)->destroy(); | |
246 dlclose(t_vdl(stream)->handle); | |
247 memset(stream,0,sizeof(vdl_stream_t)); /* <- it's not stupid */ | |
248 free(stream); | |
249 } | |
250 | |
251 int vdlGetCapability(VDL_HANDLE handle, vidix_capability_t *cap) | |
252 { | |
253 return t_vdl(handle)->get_caps(cap); | |
254 } | |
255 | |
4539 | 256 #define MPLAYER_IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8)) |
257 #define MPLAYER_IMGFMT_BGR (('B'<<24)|('G'<<16)|('R'<<8)) | |
258 #define MPLAYER_IMGFMT_RGB_MASK 0xFFFFFF00 | |
259 | |
4547 | 260 static uint32_t normalize_fourcc(uint32_t fourcc) |
4539 | 261 { |
262 if((fourcc & MPLAYER_IMGFMT_RGB_MASK) == (MPLAYER_IMGFMT_RGB|0) || | |
263 (fourcc & MPLAYER_IMGFMT_RGB_MASK) == (MPLAYER_IMGFMT_BGR|0)) | |
264 return bswap_32(fourcc); | |
265 else return fourcc; | |
266 } | |
267 | |
3991 | 268 int vdlQueryFourcc(VDL_HANDLE handle,vidix_fourcc_t *f) |
269 { | |
4547 | 270 f->fourcc = normalize_fourcc(f->fourcc); |
3991 | 271 return t_vdl(handle)->query_fourcc(f); |
272 } | |
273 | |
3995 | 274 int vdlConfigPlayback(VDL_HANDLE handle,vidix_playback_t *p) |
3991 | 275 { |
4547 | 276 p->fourcc = normalize_fourcc(p->fourcc); |
3991 | 277 return t_vdl(handle)->config_playback(p); |
278 } | |
279 | |
280 int vdlPlaybackOn(VDL_HANDLE handle) | |
281 { | |
282 return t_vdl(handle)->playback_on(); | |
283 } | |
284 | |
285 int vdlPlaybackOff(VDL_HANDLE handle) | |
286 { | |
287 return t_vdl(handle)->playback_off(); | |
288 } | |
289 | |
290 int vdlPlaybackFrameSelect(VDL_HANDLE handle, unsigned frame_idx ) | |
291 { | |
292 return t_vdl(handle)->frame_sel ? t_vdl(handle)->frame_sel(frame_idx) : ENOSYS; | |
293 } | |
294 | |
295 int vdlPlaybackGetEq(VDL_HANDLE handle, vidix_video_eq_t * e) | |
296 { | |
297 return t_vdl(handle)->get_eq ? t_vdl(handle)->get_eq(e) : ENOSYS; | |
298 } | |
299 | |
300 int vdlPlaybackSetEq(VDL_HANDLE handle, const vidix_video_eq_t * e) | |
301 { | |
302 return t_vdl(handle)->set_eq ? t_vdl(handle)->set_eq(e) : ENOSYS; | |
303 } | |
304 | |
305 int vdlPlaybackCopyFrame(VDL_HANDLE handle, const vidix_dma_t * f) | |
306 { | |
307 return t_vdl(handle)->copy_frame ? t_vdl(handle)->copy_frame(f) : ENOSYS; | |
308 } | |
4070
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
309 |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
310 int vdlGetGrKeys(VDL_HANDLE handle, vidix_grkey_t * k) |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
311 { |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
312 return t_vdl(handle)->get_gkey ? t_vdl(handle)->get_gkey(k) : ENOSYS; |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
313 } |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
314 |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
315 int vdlSetGrKeys(VDL_HANDLE handle, const vidix_grkey_t * k) |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
316 { |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
317 return t_vdl(handle)->set_gkey ? t_vdl(handle)->set_gkey(k) : ENOSYS; |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
318 } |
4191 | 319 |
320 int vdlPlaybackGetDeint(VDL_HANDLE handle, vidix_deinterlace_t * d) | |
321 { | |
322 return t_vdl(handle)->get_deint ? t_vdl(handle)->get_deint(d) : ENOSYS; | |
323 } | |
324 | |
325 int vdlPlaybackSetDeint(VDL_HANDLE handle, const vidix_deinterlace_t * d) | |
326 { | |
327 return t_vdl(handle)->set_deint ? t_vdl(handle)->set_deint(d) : ENOSYS; | |
328 } | |
329 | |
330 int vdlQueryNumOemEffects(VDL_HANDLE handle, unsigned * number ) | |
331 { | |
332 return t_vdl(handle)->get_num_fx ? t_vdl(handle)->get_num_fx(number) : ENOSYS; | |
333 } | |
334 | |
335 int vdlGetOemEffect(VDL_HANDLE handle, vidix_oem_fx_t * f) | |
336 { | |
337 return t_vdl(handle)->get_fx ? t_vdl(handle)->get_fx(f) : ENOSYS; | |
338 } | |
339 | |
340 int vdlSetOemEffect(VDL_HANDLE handle, const vidix_oem_fx_t * f) | |
341 { | |
342 return t_vdl(handle)->set_fx ? t_vdl(handle)->set_fx(f) : ENOSYS; | |
343 } |