[MPlayer-dev-eng] [PATCH] Real Audio/Video support for Mac OS X (again)

Donnie Smith xc0bead2d8130df59 at f4n.org
Mon Jul 21 15:28:36 CEST 2003


Hi,

I haven't received much feedback on my previous messages/patches, see
http://mplayerhq.hu/pipermail/mplayer-dev-eng/2003-June/019418.html and
http://mplayerhq.hu/pipermail/mplayer-dev-eng/2003-June/019423.html.
Therefor I decided to update the patches (for CVS 20030721) and put them 
all in a bundle, realmac.patch, that patches configure, DOCS/en/codecs.html, 
etc/codecs.html and libmpcodecs/{vd_realvid.c,ad_realaud.c}.

Comments? Also, would it be possible to put a Mac OS X codecs package
(with the Real-codecs) on the download page (I'd be happy to create it)?

A different matter is the iconv problem in libvo/font_load_ft.c, see
http://mplayerhq.hu/pipermail/mplayer-dev-eng/2003-June/019467.html.
I mentioned a possible fix, but creating a patch for it is rather
tedious, so I'd prefer comments before creating a patch... 

The second attachment, minor.patch, fixes a minor problem in ad_realaud.c.

Donnie Smith
-------------- next part --------------
--- MPlayer-20030721.orig/configure	2003-07-19 23:41:32.000000000 +0200
+++ MPlayer-20030721/configure	2003-07-21 13:59:33.000000000 +0200
@@ -179,6 +179,7 @@
   --enable-jpeg		 enable jpeg input/output support [autodetect]
   --enable-liblzo	 enable external liblzo support [autodetect]
   --disable-win32        disable Win32 DLL support [autodetect]
+  --disable-macshlb      disable Mac OS X SHLB support [autodetect]
   --disable-dshow        disable Win32/DirectShow support [autodetect]
   --disable-qtx          disable Quicktime codecs [autodetect]
   --disable-xanim        disable XAnim DLL support [autodetect]
@@ -1081,6 +1082,7 @@
 _alsa=auto
 _fastmemcpy=yes
 _unrarlib=yes
+_macshlb=auto
 _win32=auto
 _dshow=yes
 _select=yes
@@ -1435,6 +1437,8 @@
   --disable-mmx) # 3Dnow! and MMX2 require MMX
         _3dnow=no _3dnowex=no _mmx=no _mmx2=no ;;
 
+  --enable-macshlb) _macshlb=yes ;;
+  --disable-macshlb) _macshlb=no ;;
   --enable-win32) _win32=yes ;;
   --disable-win32) _win32=no _dshow=no ;;
   --enable-dshow) _win32=yes _dshow=yes ;;
@@ -4256,6 +4260,21 @@
   echores "$_faad"
 fi
 
+echocheck "Mac OS X codec SHLB support"
+if test "$_macshlb" = auto ; then
+  if test "$_macosx" = yes ; then
+    _macshlb=yes
+  else
+    _macshlb=no
+  fi
+fi
+echores "$_macshlb"
+if test "$_macshlb" = yes ; then
+  _def_macshlb='#define USE_MACSHLB 1'
+else
+  _def_macshlb='#undef USE_MACSHLB'
+fi
+
 if test "$_win32" = auto ; then
   if x86 ; then
     qnx && _win32=no
@@ -4402,18 +4421,18 @@
 echocheck "RealPlayer DLL"
 if test "$_real" = auto ; then
   _real=no
-  if test "$_dl" = yes || test "$_win32" = yes ; then
+  if test "$_dl" = yes || test "$_win32" = yes || test "$_macshlb" = yes ; then
 #  if test "$_dl" = yes  ; then
-    if linux || freebsd || netbsd || cygwin || mingw32 ; then
+    if linux || freebsd || netbsd || cygwin || mingw32 || darwin ; then
       _real=yes
     else
-      echores "no (tested only on Linux/FreeBSD/NetBSD/Cygwin/MINGW32)"
+      echores "no (tested only on Linux/FreeBSD/NetBSD/Cygwin/MINGW32/Darwin)"
     fi
     if test "$_real" = yes ; then
       if test -z "$_reallibdir" ; then
 	for I in "$_libdir/codecs" "$_libdir/real" /usr/lib/real \
 	  /usr/lib/RealPlayer{9,8,}/Codecs /usr/local/RealPlayer{9,8,}/Codecs \
-	  /usr/local/lib/RealPlayer{9,8,}/Codecs /opt/RealPlayer{9,8,}/{Real/,}Codecs ; do
+	  /usr/local/lib/RealPlayer{9,8,}/Codecs /opt/RealPlayer{9,8,}/{Real/,}Codecs {~,}/Applications/RealOne\ Player.app/Contents/MacOS/Library/Codecs ; do
           if test -d "$I" ; then
             _reallibdir="$I"
             break
@@ -5686,6 +5705,9 @@
 /* Mac OS X specific features */
 $_def_macosx
 
+/* Mac OS X SHLB support */
+$_def_macshlb
+
 /* Build our Win32-loader */
 $_def_win32_loader
 
--- MPlayer-20030721.orig/DOCS/en/codecs.html	2003-07-13 17:56:16.000000000 +0200
+++ MPlayer-20030721/DOCS/en/codecs.html	2003-07-21 14:20:00.000000000 +0200
@@ -267,7 +267,16 @@
 
 <P><B>Note:</B> RealPlayer libraries currently <B>only work with Linux, FreeBSD,
   NetBSD and Cygwin on the x86, Alpha and PowerPC (Linux/Alpha and Linux/PowerPC
-  have been tested) platforms.</B></P>
+  have been tested) platforms and with Mac OS X.</B></P>
+<P>On Mac OS X you must make sure <CODE>pncrt.Shlb</CODE> (including it's
+  resource fork!) is in the same directory as the Real codecs.
+  Copy them using, for example, <CODE>ditto</CODE>:
+    <PRE>
+    ditto -rsrcFork "RealOne Player.app/Contents/MacOS/pncrt.Shlb" "RealOne Player.app/Contents/MacOS/Library/Codecs"</PRE>
+  Not doing so, or forgetting to copy the resource fork, will result in
+  errors such as: <CODE>GetDiskFragment() failed with error -2804:
+  &lt;&lt;Unknown disk fragment&gt;&gt;&lt;&lt;Unknown disk 
+  fragment&gt;&gt;&lt;pncrt.Shlb&gt;&lt;&gt;</CODE>.</P>
 
 
 <H4><A NAME="xvid">2.2.1.9 XviD</A></H4>
--- MPlayer-20030721.orig/etc/codecs.conf	2003-07-13 17:56:18.000000000 +0200
+++ MPlayer-20030721/etc/codecs.conf	2003-07-21 14:06:52.000000000 +0200
@@ -941,6 +941,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
@@ -957,6 +965,14 @@
   dll "drv33260.dll"
   out I420
 
+videocodec rv30mac
+  info "Mac OS X RealPlayer 8 RV30 decoder"
+  status working
+  fourcc RV30,rv30
+  driver realvid
+  dll "drv3.shlb"
+  out I420
+
 videocodec rv20
   info "Linux RealPlayer 8 RV20 decoder"
   status working
@@ -973,6 +989,14 @@
   dll "drv23260.dll"
   out I420
 
+videocodec rv20mac
+  info "Mac OS X RealPlayer 8 RV20 decoder"
+  status working
+  fourcc RV20,rv20
+  driver realvid
+  dll "drv2.shlb"
+  out I420
+
 ; others:
 
 videocodec ffrv10
@@ -1606,6 +1630,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
@@ -1620,6 +1651,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
--- MPlayer-20030721.orig/libmpcodecs/vd_realvid.c	2003-07-20 00:05:16.000000000 +0200
+++ MPlayer-20030721/libmpcodecs/vd_realvid.c	2003-07-21 14:10:03.000000000 +0200
@@ -13,10 +13,14 @@
 
 #include "vd_internal.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
+	"Florian Schneider & A'rpi", // win32 dlls support by alex, mac os x shlb support by Donnie Smith
 	"using original closed source codecs for Linux",
 	"binary real video codecs"
 };
@@ -176,6 +180,68 @@
 }
 #endif
 
+#ifdef USE_MACSHLB
+void *load_one_sym_mac(char *symbolName, CFragConnectionID *connID);
+static int load_syms_mac(char *path) {
+    void *handle;
+
+    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;
+    }
+
+    rv_handle = connID;
+
+    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("\x19RV20toYUV420CustomMessage", connID);
+    rvyuv_free = load_one_sym_mac("\x10RV20toYUV420Free", connID);
+    rvyuv_hive_message = load_one_sym_mac("\x17RV20toYUV420HiveMessage", connID);
+    rvyuv_init = load_one_sym_mac("\x10RV20toYUV420Init", connID);
+    rvyuv_transform = load_one_sym_mac("\x15RV20toYUV420Transform", 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;
@@ -213,6 +279,9 @@
 #ifdef USE_WIN32DLL
 	    if (!load_syms_windows(sh->codec->dll))
 #endif
+#ifdef USE_MACSHLB
+        if (!load_syms_mac(path))
+#endif
 	{
 		mp_msg(MSGT_DECVIDEO,MSGL_ERR,MSGTR_MissingDLLcodec,sh->codec->dll);
 		mp_msg(MSGT_DECVIDEO,MSGL_HINT,"Read the RealVideo section of the DOCS!\n");
@@ -270,6 +339,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;
 }
 
--- MPlayer-20030721.orig/libmpcodecs/ad_realaud.c	2003-07-20 00:05:16.000000000 +0200
+++ MPlayer-20030721/libmpcodecs/ad_realaud.c	2003-07-21 14:11:23.000000000 +0200
@@ -15,10 +15,14 @@
 
 #include "ad_internal.h"
 
+#ifdef USE_MACSHLB
+#include <CoreServices/CoreServices.h>
+#endif
+
 static ad_info_t info =  {
 	"RealAudio decoder",
 	"realaud",
-	"A'rpi", // win32 dlls support by alex
+	"A'rpi", // win32 dlls support by alex, mac os x shlb support by Donnie Smith
 	"Florian Schneider",
 	"binary real audio codecs"
 };
@@ -205,6 +209,104 @@
 }
 #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, see http://developer.apple.com/samplecode/
+ Sample_Code/Runtime_Architecture/CFM_MachO_CFM/CFM_MachO_CFM.c.htm for
+ further details.
+
+ Caller is expected to DisposePtr(mfp).
+ 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;
+
+    if ( (err = FindSymbol( *connID, symbolName, 
+                            &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( "\xcRACloseCodec", connID);
+    raDecode = load_one_sym_mac("\x8RADecode", connID);
+    raFlush = load_one_sym_mac("\x7RAFlush", connID);
+    raFreeDecoder = load_one_sym_mac("\xdRAFreeDecoder", connID);
+    raGetFlavorProperty = load_one_sym_mac("\x13RAGetFlavorProperty", connID);
+    raOpenCodec = load_one_sym_mac("\xbRAOpenCodec", connID);
+    raOpenCodec2 = load_one_sym_mac("\xcRAOpenCodec2", connID);
+    raInitDecoder = load_one_sym_mac("\xdRAInitDecoder", connID);
+    raSetFlavor = load_one_sym_mac("\xbRASetFlavor", connID);
+    raSetDLLAccessPath = load_one_sym_mac("\x10SetDLLAccessPath", connID);
+    raSetPwd = load_one_sym_mac("\x8RASetPwd", 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)
@@ -225,6 +327,9 @@
 #ifdef USE_WIN32DLL
 	if (!load_sysm_windows(sh->codec->dll))
 #endif
+#ifdef USE_MACSHLB
+    if (!load_syms_mac(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");
@@ -292,7 +397,8 @@
 	((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,
@@ -303,11 +409,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;
@@ -394,6 +506,20 @@
     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)
     {
-------------- next part --------------
--- MPlayer-20030721.orig/libmpcodecs/ad_realaud.c	2003-07-20 00:05:16.000000000 +0200
+++ MPlayer-20030721/libmpcodecs/ad_realaud.c	2003-07-21 14:28:02.000000000 +0200
@@ -401,7 +401,7 @@
     } else
 #endif
 // this dlclose() causes some memory corruption, and crashes soon (in caller):
-//    if (rv_handle) dlclose(rv_handle);
+    if (rv_handle) ;//dlclose(rv_handle);
     rv_handle = NULL;
 }
 


More information about the MPlayer-dev-eng mailing list