changeset 9395:2d651a218031

windows support and eleminating some 10ls. Win32 ATRC has audio artifacts, Win32 SIPR is just silent, but at least Win32 COOK works nice -- at least by me, on linux
author alex
date Tue, 11 Feb 2003 15:24:26 +0000
parents b58dcfbbca5a
children cbc01dc4b773
files libmpcodecs/ad_realaud.c
diffstat 1 files changed, 241 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/ad_realaud.c	Tue Feb 11 15:06:44 2003 +0000
+++ b/libmpcodecs/ad_realaud.c	Tue Feb 11 15:24:26 2003 +0000
@@ -7,15 +7,16 @@
 
 #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"
 };
@@ -39,11 +40,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,8 +72,128 @@
     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;
 
+/* 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 && raOpenCodec/*2*/ && 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/*2*/ && 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)
@@ -62,46 +201,54 @@
   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;
-  }
 
-    raCloseCodec = dlsym(handle, "RACloseCodec");
-    raDecode = dlsym(handle, "RADecode");
-    raFlush = dlsym(handle, "RAFlush");
-    raFreeDecoder = dlsym(handle, "RAFreeDecoder");
-    raGetFlavorProperty = dlsym(handle, "RAGetFlavorProperty");
-    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;
-  }
+    /* 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)
+//	result=wraOpenCodec2(&sh->context,NULL);
+	result=wraOpenCodec(&sh->context);
+    else
+#endif
+//    result=raOpenCodec2(&sh->context,NULL);
+    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,34 +256,76 @@
 
   { 
     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);
@@ -164,6 +353,24 @@
 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);
+    } else
+#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
+    if (rv_handle) dlclose(rv_handle);
+    rv_handle = NULL;
 }
 
 static unsigned char sipr_swaps[38][2]={
@@ -229,6 +436,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;