[Mplayer-cvslog] CVS: 0_90/libmpcodecs ad_realaud.c,1.19,1.20
Arpi of Ize
arpi at mplayerhq.hu
Mon Mar 10 15:06:45 CET 2003
Update of /cvsroot/mplayer/0_90/libmpcodecs
In directory mail:/var/tmp.root/cvs-serv27171
Modified Files:
ad_realaud.c
Log Message:
backport: win32 DLL support, cook flavor fixes
Index: ad_realaud.c
===================================================================
RCS file: /cvsroot/mplayer/0_90/libmpcodecs/ad_realaud.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- ad_realaud.c 4 Nov 2002 00:23:52 -0000 1.19
+++ ad_realaud.c 10 Mar 2003 14:06:43 -0000 1.20
@@ -7,27 +7,31 @@
#ifdef USE_REALCODECS
-#include <stddef.h>
+//#include <stddef.h>
#include <dlfcn.h>
+#include "help_mp.h"
#include "ad_internal.h"
static ad_info_t info = {
"RealAudio decoder",
"realaud",
- "A'rpi",
+ "A'rpi", // win32 dlls support by alex
"Florian Schneider",
"binary real audio codecs"
};
LIBAD_EXTERN(realaud)
-static void *handle=NULL;
-
void *__builtin_new(unsigned long size) {
return malloc(size);
}
+// required for cook's uninit:
+void __builtin_delete(void* ize) {
+ free(ize);
+}
+
#if defined(__FreeBSD__) || defined(__NetBSD__)
void *__ctype_b=NULL;
#endif
@@ -39,11 +43,29 @@
static void* (*raGetFlavorProperty)(void*,unsigned long,unsigned long,int*);
//static unsigned long (*raGetNumberOfFlavors2)(void);
static unsigned long (*raInitDecoder)(void*, void*);
-static unsigned long (*raOpenCodec2)(void*);
+static unsigned long (*raOpenCodec)(void*);
+static unsigned long (*raOpenCodec2)(void*, void*);
static unsigned long (*raSetFlavor)(void*,unsigned long);
static void (*raSetDLLAccessPath)(char*);
static void (*raSetPwd)(char*,char*);
+#ifdef USE_WIN32DLL
+static unsigned long WINAPI (*wraCloseCodec)(void*);
+static unsigned long WINAPI (*wraDecode)(void*, char*,unsigned long,char*,unsigned int*,long);
+static unsigned long WINAPI (*wraFlush)(unsigned long,unsigned long,unsigned long);
+static unsigned long WINAPI (*wraFreeDecoder)(void*);
+static void* WINAPI (*wraGetFlavorProperty)(void*,unsigned long,unsigned long,int*);
+static unsigned long WINAPI (*wraInitDecoder)(void*, void*);
+static unsigned long WINAPI (*wraOpenCodec)(void*);
+static unsigned long WINAPI (*wraOpenCodec2)(void*, void*);
+static unsigned long WINAPI (*wraSetFlavor)(void*,unsigned long);
+static void WINAPI (*wraSetDLLAccessPath)(char*);
+static void WINAPI (*wraSetPwd)(char*,char*);
+
+static int dll_type = 0; /* 0 = unix dlopen, 1 = win32 dll */
+#endif
+static void *rv_handle = NULL;
+#if 0
typedef struct {
int samplerate;
short bits;
@@ -53,55 +75,187 @@
int packetsize;
int unk3;
void* unk4;
+} ra_init_t ;
+#else
+
+/*
+ Probably the linux .so-s were compiled with old GCC without setting
+ packing, so it adds 2 bytes padding after the quality field.
+ In windows it seems that there's no padding in it.
+
+ -- alex
+*/
+
+/* linux dlls doesn't need packing */
+typedef struct /*__attribute__((__packed__))*/ {
+ int samplerate;
+ short bits;
+ short channels;
+ short quality;
+ /* 2bytes padding here, by gcc */
+ int bits_per_frame;
+ int packetsize;
+ int extradata_len;
+ void* extradata;
} ra_init_t;
-static int preinit(sh_audio_t *sh){
- // let's check if the driver is available, return 0 if not.
- // (you should do that if you use external lib(s) which is optional)
- unsigned int result;
- int len=0;
- void* prop;
- char path[4096];
- sprintf(path, REALCODEC_PATH "/%s", sh->codec->dll);
- handle = dlopen (path, RTLD_LAZY);
- if(!handle){
- mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Cannot open dll: %s\n",dlerror());
- return 0;
- }
+/* windows dlls need packed structs (no padding) */
+typedef struct __attribute__((__packed__)) {
+ int samplerate;
+ short bits;
+ short channels;
+ short quality;
+ int bits_per_frame;
+ int packetsize;
+ int extradata_len;
+ void* extradata;
+} wra_init_t;
+#endif
+
+static int load_syms_linux(char *path)
+{
+ void *handle;
+
+ mp_msg(MSGT_DECVIDEO, MSGL_INFO, "opening shared obj '%s'\n", path);
+ handle = dlopen(path, RTLD_LAZY);
+ if (!handle)
+ {
+ mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Error: %s\n", dlerror());
+ return 0;
+ }
raCloseCodec = dlsym(handle, "RACloseCodec");
raDecode = dlsym(handle, "RADecode");
raFlush = dlsym(handle, "RAFlush");
raFreeDecoder = dlsym(handle, "RAFreeDecoder");
raGetFlavorProperty = dlsym(handle, "RAGetFlavorProperty");
+ raOpenCodec = dlsym(handle, "RAOpenCodec");
raOpenCodec2 = dlsym(handle, "RAOpenCodec2");
raInitDecoder = dlsym(handle, "RAInitDecoder");
raSetFlavor = dlsym(handle, "RASetFlavor");
raSetDLLAccessPath = dlsym(handle, "SetDLLAccessPath");
raSetPwd = dlsym(handle, "RASetPwd"); // optional, used by SIPR
- if(!raCloseCodec || !raDecode || !raFlush || !raFreeDecoder ||
- !raGetFlavorProperty || !raOpenCodec2 || !raSetFlavor ||
- /*!raSetDLLAccessPath ||*/ !raInitDecoder){
- mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Cannot resolve symbols - incompatible dll: %s\n",path);
- return 0;
- }
+ if (raCloseCodec && raDecode && raFlush && raFreeDecoder &&
+ raGetFlavorProperty && (raOpenCodec||raOpenCodec2) && raSetFlavor &&
+ /*raSetDLLAccessPath &&*/ raInitDecoder)
+ {
+ rv_handle = handle;
+ return 1;
+ }
+
+ mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Cannot resolve symbols - incompatible dll: %s\n",path);
+ dlclose(handle);
+ return 0;
+}
+
+#ifdef USE_WIN32DLL
+
+#include "../loader/ldt_keeper.h"
+void* WINAPI LoadLibraryA(char* name);
+void* WINAPI GetProcAddress(void* handle,char *func);
+int WINAPI FreeLibrary(void *handle);
+
+static int load_sysm_windows(char *path)
+{
+ void *handle;
+
+ mp_msg(MSGT_DECVIDEO, MSGL_INFO, "opening win32 dll '%s'\n", path);
+ Setup_LDT_Keeper();
+ handle = LoadLibraryA(path);
+ if (!handle)
+ {
+ mp_msg(MSGT_DECVIDEO, MSGL_WARN, "Error loading dll\n");
+ return 0;
+ }
+ wraCloseCodec = GetProcAddress(handle, "RACloseCodec");
+ wraDecode = GetProcAddress(handle, "RADecode");
+ wraFlush = GetProcAddress(handle, "RAFlush");
+ wraFreeDecoder = GetProcAddress(handle, "RAFreeDecoder");
+ wraGetFlavorProperty = GetProcAddress(handle, "RAGetFlavorProperty");
+ wraOpenCodec = GetProcAddress(handle, "RAOpenCodec");
+ wraOpenCodec2 = GetProcAddress(handle, "RAOpenCodec2");
+ wraInitDecoder = GetProcAddress(handle, "RAInitDecoder");
+ wraSetFlavor = GetProcAddress(handle, "RASetFlavor");
+ wraSetDLLAccessPath = GetProcAddress(handle, "SetDLLAccessPath");
+ wraSetPwd = GetProcAddress(handle, "RASetPwd"); // optional, used by SIPR
+
+ if (wraCloseCodec && wraDecode && wraFlush && wraFreeDecoder &&
+ wraGetFlavorProperty && (wraOpenCodec || wraOpenCodec2) && wraSetFlavor &&
+ /*wraSetDLLAccessPath &&*/ wraInitDecoder)
+ {
+ rv_handle = handle;
+ dll_type = 1;
+ return 1;
+ }
+
+ mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Cannot resolve symbols - incompatible dll: %s\n",path);
+ FreeLibrary(handle);
+ return 0;
+
+}
+#endif
+
+static int preinit(sh_audio_t *sh){
+ // let's check if the driver is available, return 0 if not.
+ // (you should do that if you use external lib(s) which is optional)
+ unsigned int result;
+ int len=0;
+ void* prop;
+ char path[4096];
+
+ sprintf(path, REALCODEC_PATH "/%s", sh->codec->dll);
+
+ /* first try to load linux dlls, if failed and we're supporting win32 dlls,
+ then try to load the windows ones */
+ if (!load_syms_linux(path))
+#ifdef USE_WIN32DLL
+ if (!load_sysm_windows(path))
+#endif
+ {
+ mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_MissingDLLcodec, sh->codec->dll);
+ mp_msg(MSGT_DECVIDEO, MSGL_HINT, "Read the RealAudio section of the DOCS!\n");
+ return 0;
+ }
+
+#ifdef USE_WIN32DLL
+ if((raSetDLLAccessPath && dll_type == 0) || (wraSetDLLAccessPath && dll_type == 1)){
+#else
if(raSetDLLAccessPath){
+#endif
+ // used by 'SIPR'
sprintf(path, "DT_Codecs=" REALCODEC_PATH);
if(path[strlen(path)-1]!='/'){
path[strlen(path)+1]=0;
path[strlen(path)]='/';
}
path[strlen(path)+1]=0;
+#ifdef USE_WIN32DLL
+ if (dll_type == 1)
+ wraSetDLLAccessPath(path);
+ else
+#endif
raSetDLLAccessPath(path);
}
- result=raOpenCodec2(&sh->context);
+#ifdef USE_WIN32DLL
+ if (dll_type == 1){
+ if(wraOpenCodec2)
+ result=wraOpenCodec2(&sh->context,REALCODEC_PATH "\\");
+ else
+ result=wraOpenCodec(&sh->context);
+ } else
+#endif
+ if(raOpenCodec2)
+ result=raOpenCodec2(&sh->context,REALCODEC_PATH "/");
+ else
+ result=raOpenCodec(&sh->context);
if(result){
mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Decoder open failed, error code: 0x%X\n",result);
return 0;
}
+// printf("opencodec ok (result: %x)\n", result);
sh->samplerate=sh->wf->nSamplesPerSec;
sh->samplesize=sh->wf->wBitsPerSample/8;
@@ -109,38 +263,83 @@
{
ra_init_t init_data={
- sh->wf->nSamplesPerSec,sh->wf->wBitsPerSample,sh->wf->nChannels,
- 100, // ???
+ sh->wf->nSamplesPerSec,
+ sh->wf->wBitsPerSample,
+ sh->wf->nChannels,
+ 100, // quality
((short*)(sh->wf+1))[0], // subpacket size
((short*)(sh->wf+1))[3], // coded frame size
((short*)(sh->wf+1))[4], // codec data length
((char*)(sh->wf+1))+10 // extras
};
+#ifdef USE_WIN32DLL
+ wra_init_t winit_data={
+ sh->wf->nSamplesPerSec,
+ sh->wf->wBitsPerSample,
+ sh->wf->nChannels,
+ 100, // quality
+ ((short*)(sh->wf+1))[0], // subpacket size
+ ((short*)(sh->wf+1))[3], // coded frame size
+ ((short*)(sh->wf+1))[4], // codec data length
+ ((char*)(sh->wf+1))+10 // extras
+ };
+ if (dll_type == 1)
+ result=wraInitDecoder(sh->context,&winit_data);
+ else
+#endif
result=raInitDecoder(sh->context,&init_data);
if(result){
mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Decoder init failed, error code: 0x%X\n",result);
return 0;
}
+// printf("initdecoder ok (result: %x)\n", result);
}
+#ifdef USE_WIN32DLL
+ if((raSetPwd && dll_type == 0) || (wraSetPwd && dll_type == 1)){
+#else
if(raSetPwd){
+#endif
// used by 'SIPR'
+#ifdef USE_WIN32DLL
+ if (dll_type == 1)
+ wraSetPwd(sh->context,"Ardubancel Quazanga");
+ else
+#endif
raSetPwd(sh->context,"Ardubancel Quazanga"); // set password... lol.
}
+#ifdef USE_WIN32DLL
+ if (dll_type == 1)
+ result=wraSetFlavor(sh->context,((short*)(sh->wf+1))[2]);
+ else
+#endif
result=raSetFlavor(sh->context,((short*)(sh->wf+1))[2]);
if(result){
mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Decoder flavor setup failed, error code: 0x%X\n",result);
return 0;
}
+#ifdef USE_WIN32DLL
+ if (dll_type == 1)
+ prop=wraGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],0,&len);
+ else
+#endif
prop=raGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],0,&len);
mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Audio codec: [%d] %s\n",((short*)(sh->wf+1))[2],prop);
+#ifdef USE_WIN32DLL
+ if (dll_type == 1)
+ prop=wraGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],1,&len);
+ else
+#endif
prop=raGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],1,&len);
- sh->i_bps=((*((int*)prop))+4)/8;
- mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Audio bitrate: %5.3f kbit/s (%d bps) \n",(*((int*)prop))*0.001f,sh->i_bps);
-
+ if(prop){
+ sh->i_bps=((*((int*)prop))+4)/8;
+ mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Audio bitrate: %5.3f kbit/s (%d bps) \n",(*((int*)prop))*0.001f,sh->i_bps);
+ } else
+ sh->i_bps=12000; // dunno :((( [12000 seems to be OK for crash.rmvb too]
+
// prop=raGetFlavorProperty(sh->context,((short*)(sh->wf+1))[2],0x13,&len);
// mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Samples/block?: %d \n",(*((int*)prop)));
@@ -164,6 +363,26 @@
static void uninit(sh_audio_t *sh){
// uninit the decoder etc...
// again: you don't have to free() a_in_buffer here! it's done by the core.
+#ifdef USE_WIN32DLL
+ if (dll_type == 1)
+ {
+ if (wraFreeDecoder) wraFreeDecoder(sh->context);
+ if (wraCloseCodec) wraCloseCodec(sh->context);
+ }
+#endif
+
+ if (raFreeDecoder) raFreeDecoder(sh->context);
+ if (raCloseCodec) raCloseCodec(sh->context);
+
+#ifdef USE_WIN32DLL
+ if (dll_type == 1)
+ {
+ if (rv_handle) FreeLibrary(rv_handle);
+ } else
+#endif
+// this dlclose() causes some memory corruption, and crashes soon (in caller):
+// if (rv_handle) dlclose(rv_handle);
+ rv_handle = NULL;
}
static unsigned char sipr_swaps[38][2]={
@@ -229,6 +448,12 @@
}
#endif
+#ifdef USE_WIN32DLL
+ if (dll_type == 1)
+ result=wraDecode(sh->context, sh->a_in_buffer+sh->a_in_buffer_size-sh->a_in_buffer_len, sh->wf->nBlockAlign,
+ buf, &len, -1);
+ else
+#endif
result=raDecode(sh->context, sh->a_in_buffer+sh->a_in_buffer_size-sh->a_in_buffer_len, sh->wf->nBlockAlign,
buf, &len, -1);
sh->a_in_buffer_len-=sh->wf->nBlockAlign;
More information about the MPlayer-cvslog
mailing list