changeset 12628:985e1813e298

support for realvideo codecs under macosx, original patch by Donnie Smith
author alex
date Thu, 24 Jun 2004 09:19:15 +0000
parents 5c61415caefd
children 4bbc58806c90
files etc/codecs.conf libmpcodecs/ad_realaud.c libmpcodecs/vd_realvid.c
diffstat 3 files changed, 278 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/etc/codecs.conf	Thu Jun 24 09:03:31 2004 +0000
+++ b/etc/codecs.conf	Thu Jun 24 09:19:15 2004 +0000
@@ -1072,6 +1072,14 @@
   dll "drv43260.dll"
   out I420
 
+videocodec rv40mac
+  info "Mac OS X RealPlayer 9 RV40 decoder"
+  status working
+  fourcc RV40,rv40
+  driver realvid
+  dll "drv4.shlb"
+  out I420
+
 videocodec rv30
   info "Linux RealPlayer 8 RV30 decoder"
   status working
@@ -1088,6 +1096,14 @@
   dll "drv33260.dll"
   out I420
 
+videocodec rv30mac
+  info "Mac OS X RealPlayer 9 RV30 decoder"
+  status working
+  fourcc RV30,rv30
+  driver realvid
+  dll "drv3.shlb"
+  out I420
+
 videocodec rv20
   info "Linux RealPlayer 8 RV20 decoder"
   status working
@@ -1104,6 +1120,14 @@
   dll "drv23260.dll"
   out I420
 
+videocodec rv20mac
+  info "Mac OS X RealPlayer 9 RV20 decoder"
+  status working
+  fourcc RV20,rv20
+  driver realvid
+  dll "drv2.shlb"
+  out I420
+
 ; others:
 
 videocodec alpary
@@ -1842,6 +1866,13 @@
   driver realaud
   dll "14_43260.dll"
 
+audiocodec ra144mac
+  info "Mac OS X RealAudio 1.0"
+  status working
+  format 0x345F3431 ; "14_4"
+  driver realaud
+  dll "14_4.shlb"
+
 audiocodec ra288
   info "RealAudio 2.0"
   status working
@@ -1856,6 +1887,13 @@
   driver realaud
   dll "28_83260.dll"
 
+audiocodec ra288mac
+  info "Mac OS X RealAudio 2.0"
+  status working
+  format 0x385F3832 ; "28_8"
+  driver realaud
+  dll "28_8.shlb"
+
 audiocodec mpra1428
   info "RealAudio 1.0 and 2.0 native decoder"
   status working
@@ -1877,6 +1915,13 @@
   driver realaud
   dll "cook3260.dll"
 
+audiocodec racookmac
+  info "Mac OS X RealAudio COOK"
+  status working
+  format 0x6B6F6F63 ; "cook"
+  driver realaud
+  dll "cook.shlb"
+
 audiocodec rasipr
   info "RealAudio Sipro"
   status working
@@ -1891,6 +1936,13 @@
   driver realaud
   dll "sipr3260.dll"
 
+audiocodec rasiprmac
+  info "Mac OS X RealAudio Sipro"
+  status working
+  format 0x72706973 ; "sipr"
+  driver realaud
+  dll "sipr.shlb"
+
 audiocodec raatrc
   info "RealAudio ATRAC3"
   status working
@@ -1905,6 +1957,13 @@
   driver realaud
   dll "atrc3260.dll"
 
+audiocodec raatrcmac
+  info "Mac OS X RealAudio ATRAC3"
+  status working
+  format 0x63727461 ; "atrc"
+  driver realaud
+  dll "atrc.shlb"
+
 audiocodec imaadpcm
   info "IMA ADPCM"
   status working
--- a/libmpcodecs/ad_realaud.c	Thu Jun 24 09:03:31 2004 +0000
+++ b/libmpcodecs/ad_realaud.c	Thu Jun 24 09:19:15 2004 +0000
@@ -16,11 +16,15 @@
 #include "ad_internal.h"
 #include "wine/windef.h"
 
+#ifdef USE_MACSHLB
+#include <CoreServices/CoreServices.h>
+#endif
+
 static ad_info_t info =  {
 	"RealAudio decoder",
 	"realaud",
-	"A'rpi", // win32 dlls support by alex
-	"Florian Schneider",
+	"Alex Beregszaszi",
+	"Florian Schneider, Arpad Gereoffy, Alex Beregszaszi, Donnie Smith",
 	"binary real audio codecs"
 };
 
@@ -66,6 +70,7 @@
 
 static int dll_type = 0; /* 0 = unix dlopen, 1 = win32 dll */
 #endif
+
 static void *rv_handle = NULL;
 
 #if 0
@@ -206,6 +211,113 @@
 }
 #endif
 
+
+#ifdef USE_MACSHLB
+/*
+ Helper function to create a function pointer (from a null terminated (!)
+ pascal string) like GetProcAddress(). Some assembler is required due
+ to different calling conventions, for further details, see 
+ http://developer.apple.com/ samplecode/CFM_MachO_CFM/listing1.html .
+
+ Caller is expected to DisposePtr(mfp).
+ N.B.: Code is used by vd_realaud.c as well.
+*/
+void *load_one_sym_mac(char *symbolName, CFragConnectionID *connID) {
+    OSErr err;
+    Ptr symbolAddr;
+    CFragSymbolClass symbolClass;
+    UInt32  *mfp;
+    char realname[255];
+    
+    if (strlen(symbolName) > 255)
+    {
+	mp_mpsg(MSGT_DECVIDEO, MSGL_V, "FindSymbol symbolname overflow\n");
+	return NULL;
+    }
+    
+    snprintf(realname, 255, "%c%s", strlen(symbolName), symbolName);
+
+    if ( (err = FindSymbol( *connID, realname, 
+                            &symbolAddr, &symbolClass )) != noErr ) {
+        mp_msg(MSGT_DECVIDEO,MSGL_V,"FindSymbol( \"%s\" ) failed with error code %d.\n", symbolName + 1, err );
+        return NULL;
+    }
+
+    if ( (mfp = (UInt32 *)NewPtr( 6 * sizeof(UInt32) )) == nil )
+        return NULL;
+
+    mfp[0] = 0x3D800000 | ((UInt32)symbolAddr >> 16);
+    mfp[1] = 0x618C0000 | ((UInt32)symbolAddr & 0xFFFF);
+    mfp[2] = 0x800C0000;
+    mfp[3] = 0x804C0004;
+    mfp[4] = 0x7C0903A6;
+    mfp[5] = 0x4E800420;
+    MakeDataExecutable( mfp, 6 * sizeof(UInt32) );
+
+    return( mfp );
+}
+
+static int load_syms_mac(char *path)
+{
+    Ptr mainAddr;
+    OSStatus status;
+    FSRef fsref;
+    FSSpec fsspec;
+    OSErr err;
+    Str255 errMessage;
+    CFragConnectionID *connID;
+
+    mp_msg(MSGT_DECVIDEO, MSGL_INFO, "opening mac shlb '%s'\n", path);
+
+    if ( (connID = (CFragConnectionID *)NewPtr( sizeof( CFragConnectionID ))) == nil ) {
+        mp_msg(MSGT_DECVIDEO,MSGL_WARN,"NewPtr() failed.\n" );
+        return 0;
+    }
+
+    if ( (status = FSPathMakeRef( path, &fsref, NULL )) != noErr ) {
+        mp_msg(MSGT_DECVIDEO,MSGL_WARN,"FSPathMakeRef() failed with error %d.\n", status );
+        return 0;
+    }
+
+    if ( (status = FSGetCatalogInfo( &fsref, kFSCatInfoNone, NULL, NULL, &fsspec, NULL )) != noErr ) {
+        mp_msg(MSGT_DECVIDEO,MSGL_WARN,"FSGetCatalogInfo() failed with error %d.\n", status );
+        return 0;
+    }
+
+    if ( (err = GetDiskFragment( &fsspec, 0, kCFragGoesToEOF, NULL, kPrivateCFragCopy, connID, &mainAddr, errMessage )) != noErr ) {
+
+        p2cstrcpy( errMessage, errMessage );
+        mp_msg(MSGT_DECVIDEO,MSGL_WARN,"GetDiskFragment() failed with error %d: %s\n", err, errMessage );
+        return 0;
+    }
+
+    raCloseCodec = load_one_sym_mac( "RACloseCodec", connID);
+    raDecode = load_one_sym_mac("RADecode", connID);
+    raFlush = load_one_sym_mac("RAFlush", connID);
+    raFreeDecoder = load_one_sym_mac("RAFreeDecoder", connID);
+    raGetFlavorProperty = load_one_sym_mac("\RAGetFlavorProperty", connID);
+    raOpenCodec = load_one_sym_mac("RAOpenCodec", connID);
+    raOpenCodec2 = load_one_sym_mac("RAOpenCodec2", connID);
+    raInitDecoder = load_one_sym_mac("RAInitDecoder", connID);
+    raSetFlavor = load_one_sym_mac("RASetFlavor", connID);
+    raSetDLLAccessPath = load_one_sym_mac("SetDLLAccessPath", connID);
+    raSetPwd = load_one_sym_mac("RASetPwd", connID); // optional, used by SIPR
+
+    if (raCloseCodec && raDecode && /*raFlush && */raFreeDecoder &&
+    raGetFlavorProperty && (raOpenCodec || raOpenCodec2) && raSetFlavor &&
+    /*raSetDLLAccessPath &&*/ raInitDecoder)
+    {
+    rv_handle = connID;
+    return 1;
+    }
+
+    mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Cannot resolve symbols - incompatible shlb: %s\n",path);
+    (void)CloseConnection(connID);
+    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)
@@ -220,6 +332,10 @@
 
     /* first try to load linux dlls, if failed and we're supporting win32 dlls,
        then try to load the windows ones */
+      
+#ifdef USE_MACSHLB
+    if (strstr(sh->codec->dll,".shlb") && !load_syms_mac(path))
+#endif
 #ifdef HAVE_LIBDL       
     if (strstr(sh->codec->dll,".dll") || !load_syms_linux(path))
 #endif
@@ -293,7 +409,7 @@
 	((short*)(sh->wf+1))[4], // codec data length
 	((char*)(sh->wf+1))+10 // extras
     };
-#ifdef USE_WIN32DLL
+#if defined(USE_WIN32DLL) || defined(USE_MACSHLB)
     wra_init_t winit_data={
 	sh->wf->nSamplesPerSec,
 	sh->wf->wBitsPerSample,
@@ -304,11 +420,17 @@
 	((short*)(sh->wf+1))[4], // codec data length
 	((char*)(sh->wf+1))+10 // extras
     };
+#endif
+#ifdef USE_MACSHLB
+	result=raInitDecoder(sh->context,&winit_data);
+#else
+#ifdef USE_WIN32DLL
     if (dll_type == 1)
 	result=wraInitDecoder(sh->context,&winit_data);
     else
 #endif
     result=raInitDecoder(sh->context,&init_data);
+#endif
     if(result){
       mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Decoder init failed, error code: 0x%X\n",result);
       return 0;
@@ -395,6 +517,21 @@
     if (raFreeDecoder) raFreeDecoder(sh->context);
     if (raCloseCodec) raCloseCodec(sh->context);
 
+#ifdef USE_MACSHLB
+    if (rv_handle){
+      (void)CloseConnection(rv_handle);
+      DisposePtr((Ptr)rv_handle);
+    }
+    if (raCloseCodec) DisposePtr((Ptr)raCloseCodec);
+    if (raDecode) DisposePtr((Ptr)raDecode);
+    if (raFlush) DisposePtr((Ptr)raFlush);
+    if (raFreeDecoder) DisposePtr((Ptr)raFreeDecoder);
+    if (raGetFlavorProperty) DisposePtr((Ptr)raGetFlavorProperty);
+    if (raOpenCodec) DisposePtr((Ptr)raOpenCodec);
+    if (raOpenCodec2) DisposePtr((Ptr)raOpenCodec2);
+    if (raInitDecoder) DisposePtr((Ptr)raInitDecoder);
+#endif
+
 #ifdef USE_WIN32DLL
     if (dll_type == 1)
     {
--- a/libmpcodecs/vd_realvid.c	Thu Jun 24 09:03:31 2004 +0000
+++ b/libmpcodecs/vd_realvid.c	Thu Jun 24 09:19:15 2004 +0000
@@ -14,11 +14,15 @@
 #include "vd_internal.h"
 #include "wine/windef.h"
 
+#ifdef USE_MACSHLB
+#include <CoreServices/CoreServices.h>
+#endif
+
 static vd_info_t info = {
 	"RealVideo decoder",
 	"realvid",
-	"Florian Schneider & A'rpi", // win32 dlls support by alex
-	"using original closed source codecs for Linux",
+	"Alex Beregszaszi",
+	"Florian Schneider, Arpad Gereoffy, Alex Beregszaszi, Donnie Smith",
 	"binary real video codecs"
 };
 
@@ -61,7 +65,7 @@
 #endif
 
 static void *rv_handle=NULL;
-static int inited;
+static int inited=0;
 #ifdef USE_WIN32DLL
 static int dll_type = 0; /* 0 = unix dlopen, 1 = win32 dll */
 #endif
@@ -177,6 +181,64 @@
 }
 #endif
 
+#ifdef USE_MACSHLB
+void *load_one_sym_mac(char *symbolName, CFragConnectionID *connID);
+
+static int load_syms_mac(char *path) {
+    Ptr mainAddr;
+    OSStatus status;
+    FSRef fsref;
+    FSSpec fsspec;
+    OSErr err;
+    Str255 errMessage;
+    CFragConnectionID *connID;
+
+    mp_msg(MSGT_DECVIDEO,MSGL_INFO, "opening mac shlb '%s'\n", path);
+
+    if ( (connID = (CFragConnectionID *)NewPtr( sizeof( CFragConnectionID ))) == nil ) {
+        mp_msg(MSGT_DECVIDEO,MSGL_WARN,"NewPtr() failed.\n" );
+        return 0;
+    }
+
+    if ( (status = FSPathMakeRef( path, &fsref, NULL )) != noErr ) {
+        mp_msg(MSGT_DECVIDEO,MSGL_WARN,"FSPathMakeRef() failed with error %d.\n", status );
+        return 0;
+    }
+
+    if ( (status = FSGetCatalogInfo( &fsref, kFSCatInfoNone, NULL, NULL, &fsspec, NULL )) != noErr ) {
+        mp_msg(MSGT_DECVIDEO,MSGL_WARN,"FSGetCatalogInfo() failed with error %d.\n", status );
+        return 0;
+    }
+
+    if ( (err = GetDiskFragment( &fsspec, 0, kCFragGoesToEOF, NULL, kPrivateCFragCopy, connID, &mainAddr, errMessage )) != noErr ) {
+        p2cstrcpy( errMessage, errMessage );
+        mp_msg(MSGT_DECVIDEO,MSGL_WARN,"GetDiskFragment() failed with error %d: %s\n", err, errMessage );
+        return 0;
+    }
+
+    rvyuv_custom_message = load_one_sym_mac("RV20toYUV420CustomMessage", connID);
+    rvyuv_free = load_one_sym_mac("RV20toYUV420Free", connID);
+    rvyuv_hive_message = load_one_sym_mac("RV20toYUV420HiveMessage", connID);
+    rvyuv_init = load_one_sym_mac("RV20toYUV420Init", connID);
+    rvyuv_transform = load_one_sym_mac("RV20toYUV420Transform", connID);
+
+    if(rvyuv_custom_message &&
+       rvyuv_free &&
+       rvyuv_hive_message &&
+       rvyuv_init &&
+       rvyuv_transform)
+    {
+	rv_handle = connID;
+	return 1;
+    }
+
+    mp_msg(MSGT_DECVIDEO,MSGL_WARN,"Error resolving symbols! (version incompatibility?)\n");
+    (void)CloseConnection(connID);
+    return 0; // error
+}
+#endif
+
+
 /* we need exact positions */
 struct rv_init_t {
 	short unk1;
@@ -208,6 +270,9 @@
 
 	/* first try to load linux dlls, if failed and we're supporting win32 dlls,
 	   then try to load the windows ones */
+#ifdef USE_MACSHLB
+	if (strstr(sh->codec->dll, ".shlb") && !load_syms_mac(path))
+#endif
 #ifdef HAVE_LIBDL       
 	if(strstr(sh->codec->dll,".dll") || !load_syms_linux(path))
 #endif
@@ -225,7 +290,6 @@
 //	if((sh->format!=0x30335652) && !mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_I420)) return 0;
 	// init codec:
 	sh->context=NULL;
-	inited=0;
 #ifdef USE_WIN32DLL
 	if (dll_type == 1)
 	    result=(*wrvyuv_init)(&init_data, &sh->context);
@@ -271,6 +335,17 @@
 #ifdef HAVE_LIBDL
 	if(rv_handle) dlclose(rv_handle);
 #endif
+#ifdef USE_MACSHLB
+	if (rv_handle){
+	    (void)CloseConnection(rv_handle);
+	    DisposePtr((Ptr)rv_handle);
+	}
+	if (rvyuv_custom_message) DisposePtr((Ptr)rvyuv_custom_message);
+	if (rvyuv_free) DisposePtr((Ptr)rvyuv_free);
+	if (rvyuv_hive_message) DisposePtr((Ptr)rvyuv_hive_message);
+	if (rvyuv_init) DisposePtr((Ptr)rvyuv_init);
+	if (rvyuv_transform) DisposePtr((Ptr)rvyuv_transform);
+#endif
 	rv_handle=NULL;
 }