Mercurial > mplayer.hg
annotate vidix/vidixlib.c @ 15533:ddf15d233d58
Do not switch to audio tracks whose codec private data differs from the main audio track's as this will most likely result in messed up audio output. Patch by Michael Behrisch <list () behrisch ! de>
author | mosu |
---|---|
date | Sat, 21 May 2005 06:50:08 +0000 |
parents | 628dd5d2326c |
children | 2ffcd779b875 |
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" |
13185 | 47 #include "../config.h" |
3991 | 48 |
4011 | 49 static char drv_name[FILENAME_MAX]; |
3991 | 50 |
51 typedef struct vdl_stream_s | |
52 { | |
53 void * handle; | |
54 int (*get_caps)(vidix_capability_t *); | |
55 int (*query_fourcc)(vidix_fourcc_t *); | |
3995 | 56 int (*config_playback)(vidix_playback_t *); |
3991 | 57 int (*playback_on)( void ); |
58 int (*playback_off)( void ); | |
59 /* Functions below can be missed in driver ;) */ | |
60 int (*init)(void); | |
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 * ); | |
4191 | 65 int (*get_deint)( vidix_deinterlace_t * ); |
66 int (*set_deint)( const vidix_deinterlace_t * ); | |
3991 | 67 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
|
68 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
|
69 int (*set_gkey)( const vidix_grkey_t * ); |
4191 | 70 int (*get_num_fx)( unsigned * ); |
71 int (*get_fx)( vidix_oem_fx_t * ); | |
72 int (*set_fx)( const vidix_oem_fx_t * ); | |
3991 | 73 }vdl_stream_t; |
74 | |
75 #define t_vdl(p) (((vdl_stream_t *)p)) | |
76 | |
77 extern unsigned vdlGetVersion( void ) | |
78 { | |
79 return VIDIX_VERSION; | |
80 } | |
81 | |
82 static int vdl_fill_driver(VDL_HANDLE stream) | |
83 { | |
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"); | |
4070
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
94 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
|
95 t_vdl(stream)->set_gkey = dlsym(t_vdl(stream)->handle,"vixSetGrKeys"); |
4191 | 96 t_vdl(stream)->get_deint = dlsym(t_vdl(stream)->handle,"vixPlaybackGetDeint"); |
97 t_vdl(stream)->set_deint = dlsym(t_vdl(stream)->handle,"vixPlaybackSetDeint"); | |
3991 | 98 t_vdl(stream)->copy_frame = dlsym(t_vdl(stream)->handle,"vixPlaybackCopyFrame"); |
4191 | 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"); | |
3991 | 102 /* check driver viability */ |
3995 | 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)) | |
4011 | 106 { |
4509
90386125ec1f
using dlerror() instead strerror(), displays unresolved symbol messages
alex
parents:
4191
diff
changeset
|
107 printf("vidixlib: Incomplete driver: some of essential features are missed in it.\n"); |
4011 | 108 return 0; |
109 } | |
3991 | 110 return 1; |
111 } | |
112 | |
5872 | 113 #ifndef RTLD_GLOBAL |
114 #define RTLD_GLOBAL RTLD_LAZY | |
115 #endif | |
116 #ifndef RTLD_NOW | |
117 #define RTLD_NOW RTLD_LAZY | |
118 #endif | |
119 | |
3995 | 120 static int vdl_probe_driver(VDL_HANDLE stream,const char *path,const char *name,unsigned cap,int verbose) |
3991 | 121 { |
122 vidix_capability_t vid_cap; | |
123 unsigned (*_ver)(void); | |
4191 | 124 int (*_probe)(int,int); |
3991 | 125 int (*_cap)(vidix_capability_t*); |
12646 | 126 strlcpy(drv_name,path, sizeof( drv_name )); |
127 strlcat(drv_name,name, sizeof( drv_name )); | |
4008 | 128 if(verbose) printf("vidixlib: PROBING: %s\n",drv_name); |
4011 | 129 if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_LAZY|RTLD_GLOBAL))) |
130 { | |
4509
90386125ec1f
using dlerror() instead strerror(), displays unresolved symbol messages
alex
parents:
4191
diff
changeset
|
131 if(verbose) printf("vidixlib: %s not driver: %s\n",drv_name,dlerror()); |
4011 | 132 return 0; |
133 } | |
3991 | 134 _ver = dlsym(t_vdl(stream)->handle,"vixGetVersion"); |
135 _probe = dlsym(t_vdl(stream)->handle,"vixProbe"); | |
136 _cap = dlsym(t_vdl(stream)->handle,"vixGetCapability"); | |
4008 | 137 if(_ver) |
138 { | |
139 if((*_ver)() != VIDIX_VERSION) | |
140 { | |
141 if(verbose) printf("vidixlib: %s has wrong version\n",drv_name); | |
142 err: | |
143 dlclose(t_vdl(stream)->handle); | |
144 t_vdl(stream)->handle = 0; | |
145 return 0; | |
146 } | |
147 } | |
148 else | |
149 { | |
150 fatal_err: | |
151 if(verbose) printf("vidixlib: %s has no function definition\n",drv_name); | |
152 goto err; | |
153 } | |
4191 | 154 if(_probe) { if((*_probe)(verbose,PROBE_NORMAL) != 0) goto err; } |
4008 | 155 else goto fatal_err; |
3991 | 156 if(_cap) { if((*_cap)(&vid_cap) != 0) goto err; } |
4008 | 157 else goto fatal_err; |
4011 | 158 if((vid_cap.type & cap) != cap) |
159 { | |
160 if(verbose) printf("vidixlib: Found %s but has no required capability\n",drv_name); | |
161 goto err; | |
162 } | |
4008 | 163 if(verbose) printf("vidixlib: %s probed o'k\n",drv_name); |
3991 | 164 return 1; |
165 } | |
166 | |
3995 | 167 static int vdl_find_driver(VDL_HANDLE stream,const char *path,unsigned cap,int verbose) |
3991 | 168 { |
169 DIR *dstream; | |
170 struct dirent *name; | |
171 int done = 0; | |
172 if(!(dstream = opendir(path))) return 0; | |
173 while(!done) | |
174 { | |
175 name = readdir(dstream); | |
4008 | 176 if(name) |
177 { | |
178 if(name->d_name[0] != '.') | |
179 if(vdl_probe_driver(stream,path,name->d_name,cap,verbose)) break; | |
180 } | |
3991 | 181 else done = 1; |
182 } | |
183 closedir(dstream); | |
184 return done?0:1; | |
185 } | |
186 | |
3995 | 187 VDL_HANDLE vdlOpen(const char *path,const char *name,unsigned cap,int verbose) |
3991 | 188 { |
189 vdl_stream_t *stream; | |
4011 | 190 int errcode; |
3991 | 191 if(!(stream = malloc(sizeof(vdl_stream_t)))) return NULL; |
192 memset(stream,0,sizeof(vdl_stream_t)); | |
193 if(name) | |
194 { | |
195 unsigned (*ver)(void); | |
4191 | 196 int (*probe)(int,int); |
3991 | 197 unsigned version = 0; |
12646 | 198 strlcpy(drv_name,path, sizeof( drv_name )); |
199 strlcat(drv_name,name, sizeof( drv_name )); | |
3991 | 200 if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_NOW|RTLD_GLOBAL))) |
201 { | |
4509
90386125ec1f
using dlerror() instead strerror(), displays unresolved symbol messages
alex
parents:
4191
diff
changeset
|
202 if (verbose) |
90386125ec1f
using dlerror() instead strerror(), displays unresolved symbol messages
alex
parents:
4191
diff
changeset
|
203 printf("vidixlib: dlopen error: %s\n", dlerror()); |
3991 | 204 err: |
205 free(stream); | |
206 return NULL; | |
207 } | |
208 ver = dlsym(t_vdl(stream)->handle,"vixGetVersion"); | |
209 if(ver) version = (*ver)(); | |
210 if(version != VIDIX_VERSION) | |
211 { | |
212 drv_err: | |
213 if(t_vdl(stream)->handle) dlclose(t_vdl(stream)->handle); | |
214 goto err; | |
215 } | |
3995 | 216 probe = dlsym(t_vdl(stream)->handle,"vixProbe"); |
4191 | 217 if(probe) { if((*probe)(verbose,PROBE_FORCE)!=0) goto drv_err; } |
3995 | 218 else goto drv_err; |
3991 | 219 fill: |
220 if(!vdl_fill_driver(stream)) goto drv_err; | |
4011 | 221 goto ok; |
3991 | 222 } |
223 else | |
4011 | 224 if(vdl_find_driver(stream,path,cap,verbose)) |
225 { | |
226 if(verbose) printf("vidixlib: will use %s driver\n",drv_name); | |
227 goto fill; | |
228 } | |
229 else goto err; | |
230 ok: | |
231 if(t_vdl(stream)->init) | |
232 { | |
233 if(verbose) printf("vidixlib: Attempt to initialize driver at: %p\n",t_vdl(stream)->init); | |
234 if((errcode=t_vdl(stream)->init())!=0) | |
235 { | |
236 if(verbose) printf("vidixlib: Can't init driver: %s\n",strerror(errcode)); | |
237 goto drv_err; | |
238 } | |
239 } | |
240 if(verbose) printf("vidixlib: '%s'successfully loaded\n",drv_name); | |
3991 | 241 return stream; |
242 } | |
243 | |
244 void vdlClose(VDL_HANDLE stream) | |
245 { | |
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 */ | |
249 free(stream); | |
250 } | |
251 | |
252 int vdlGetCapability(VDL_HANDLE handle, vidix_capability_t *cap) | |
253 { | |
254 return t_vdl(handle)->get_caps(cap); | |
255 } | |
256 | |
4539 | 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 | |
260 | |
4547 | 261 static uint32_t normalize_fourcc(uint32_t fourcc) |
4539 | 262 { |
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); | |
266 else return fourcc; | |
267 } | |
268 | |
3991 | 269 int vdlQueryFourcc(VDL_HANDLE handle,vidix_fourcc_t *f) |
270 { | |
4547 | 271 f->fourcc = normalize_fourcc(f->fourcc); |
3991 | 272 return t_vdl(handle)->query_fourcc(f); |
273 } | |
274 | |
3995 | 275 int vdlConfigPlayback(VDL_HANDLE handle,vidix_playback_t *p) |
3991 | 276 { |
4547 | 277 p->fourcc = normalize_fourcc(p->fourcc); |
3991 | 278 return t_vdl(handle)->config_playback(p); |
279 } | |
280 | |
281 int vdlPlaybackOn(VDL_HANDLE handle) | |
282 { | |
283 return t_vdl(handle)->playback_on(); | |
284 } | |
285 | |
286 int vdlPlaybackOff(VDL_HANDLE handle) | |
287 { | |
288 return t_vdl(handle)->playback_off(); | |
289 } | |
290 | |
291 int vdlPlaybackFrameSelect(VDL_HANDLE handle, unsigned frame_idx ) | |
292 { | |
293 return t_vdl(handle)->frame_sel ? t_vdl(handle)->frame_sel(frame_idx) : ENOSYS; | |
294 } | |
295 | |
296 int vdlPlaybackGetEq(VDL_HANDLE handle, vidix_video_eq_t * e) | |
297 { | |
298 return t_vdl(handle)->get_eq ? t_vdl(handle)->get_eq(e) : ENOSYS; | |
299 } | |
300 | |
301 int vdlPlaybackSetEq(VDL_HANDLE handle, const vidix_video_eq_t * e) | |
302 { | |
303 return t_vdl(handle)->set_eq ? t_vdl(handle)->set_eq(e) : ENOSYS; | |
304 } | |
305 | |
306 int vdlPlaybackCopyFrame(VDL_HANDLE handle, const vidix_dma_t * f) | |
307 { | |
308 return t_vdl(handle)->copy_frame ? t_vdl(handle)->copy_frame(f) : ENOSYS; | |
309 } | |
4070
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
310 |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
311 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
|
312 { |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
313 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
|
314 } |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
315 |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
316 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
|
317 { |
b61ba6c256dd
Minor interface changes: color and video keys are moved out from playback configuring
nick
parents:
4011
diff
changeset
|
318 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
|
319 } |
4191 | 320 |
321 int vdlPlaybackGetDeint(VDL_HANDLE handle, vidix_deinterlace_t * d) | |
322 { | |
323 return t_vdl(handle)->get_deint ? t_vdl(handle)->get_deint(d) : ENOSYS; | |
324 } | |
325 | |
326 int vdlPlaybackSetDeint(VDL_HANDLE handle, const vidix_deinterlace_t * d) | |
327 { | |
328 return t_vdl(handle)->set_deint ? t_vdl(handle)->set_deint(d) : ENOSYS; | |
329 } | |
330 | |
331 int vdlQueryNumOemEffects(VDL_HANDLE handle, unsigned * number ) | |
332 { | |
333 return t_vdl(handle)->get_num_fx ? t_vdl(handle)->get_num_fx(number) : ENOSYS; | |
334 } | |
335 | |
336 int vdlGetOemEffect(VDL_HANDLE handle, vidix_oem_fx_t * f) | |
337 { | |
338 return t_vdl(handle)->get_fx ? t_vdl(handle)->get_fx(f) : ENOSYS; | |
339 } | |
340 | |
341 int vdlSetOemEffect(VDL_HANDLE handle, const vidix_oem_fx_t * f) | |
342 { | |
343 return t_vdl(handle)->set_fx ? t_vdl(handle)->set_fx(f) : ENOSYS; | |
344 } |