[MPlayer-dev-eng] [PATCH] Real Audio/Video support for Mac OS X
Donnie Smith
xc0bead2d8130df59 at f4n.org
Fri Jun 18 17:14:22 CEST 2004
On Fri, Jun 18, 2004 at 00:38:23 +0200, Diego Biurrun wrote:
> Please update/recreate your patches, I guess they have a fair chance
> of being accepted.
Patch attached, far less work than I expected, the old patch basically
applied straight off. Therefore, I didn't check the code that
carefully, since I did that last year. I'm sure there's room for
improvements though.
I'd be surprised if I didn't make any mistakes with the DOCS-patch,
someone familiar with the XML format used (which is new to me): please
check it carefully and suggest possible fixes.
I admit that the pncrt.Shlb-copying (see the DOCS part of the patch)
is somewhat of a kludge, but I couldn't find any better way to fix it
last year. It should be possible to modify the shlb-paths, but I never
succeeded in doing so. If someone is interested, please try to fix it.
Another thing that's not too pretty is the sharing of
load_one_sym_mac() between ad_realaud.c and vd_realvid.c, but as far
as I know, there's no suitable place to put general platform dependant
functions.
When playing Real-media with -ao macosx (which is the default on Mac
OS X) one often gets buffer underruns (causing "chopped" audio):
-verbose 1, gives lots and lots of "AO: [macosx] Buffer underrun".
For me, it only occurs when playing tracks with both audio and video,
suppressing the video track makes the audio play just fine. I think
there might be some latency in the Real video codecs which breaks the
macosx-ao. If someone is interested in investigating, it occurs for me
with samples/real/Ah_My_Goddess_01.rm (but not manonfires.rm, for
example), and more so when the CPU usage is high and the frames of the
movies change fast. (For reference, it should be: koh-i-nih, na na na,
ih neh!)
Note that it does NOT happen with -ao sdl, so I'm blaming it solely on
the macosx ao.
Also, note that RealOne for Mac OS X doesn't ship with all codecs.
Instead, the player downloads them when needed (great "honest" way of
tracking what "uncommon" codecs users are intrested in, I guess). They
are permanently stored though, so you can use them with mplayer once
you have them. Perhaps a package should be created and put on
http://www.mplayerhq.hu/homepage/dload.html ?
Tell me what you think.
Donnie Smith
-------------- next part --------------
--- MPlayer-20040618.orig/libmpcodecs/vd_realvid.c Fri Apr 30 12:26:26 2004
+++ MPlayer-20040618/libmpcodecs/vd_realvid.c Fri Jun 18 14:25:35 2004
@@ -14,10 +14,14 @@
#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
+ "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"
};
@@ -177,6 +181,67 @@
}
#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;
@@ -214,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 +338,17 @@
#endif
#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-20040618.orig/libmpcodecs/ad_realaud.c Fri Apr 30 12:26:26 2004
+++ MPlayer-20040618/libmpcodecs/ad_realaud.c Fri Jun 18 14:25:10 2004
@@ -16,10 +16,14 @@
#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
+ "A'rpi", // win32 dlls support by alex, mac os x shlb support by Donnie Smith
"Florian Schneider",
"binary real audio codecs"
};
@@ -206,6 +210,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, 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;
+
+ 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)
@@ -226,6 +328,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 RealAudio section of the DOCS!\n");
@@ -293,7 +398,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 +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 +505,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)
--- MPlayer-20040618.orig/DOCS/xml/en/codecs.xml Wed May 12 00:50:05 2004
+++ MPlayer-20040618/DOCS/xml/en/codecs.xml Fri Jun 18 13:56:17 2004
@@ -428,7 +428,15 @@
<note><para>
<application>RealPlayer</application> libraries currently
<emphasis role="bold">only work with Linux, FreeBSD, NetBSD and Cygwin on the x86,
-Alpha and PowerPC (Linux/Alpha and Linux/PowerPC have been tested) platforms</emphasis>.
+Alpha and PowerPC (Linux/Alpha and Linux/PowerPC have been tested) platforms and with Mac OS X</emphasis>.
+</para>
+<para>
+On Mac OS X you must make sure <command>pncrt.Shlb</command> (including it's resource fork!) is in the same directory
+as the Real codecs. Copy them using, for example
+<command>ditto -rsrcFork "RealOne Player.app/Contents/MacOS/pncrt.Shlb" "RealOne Player.app/Contents/MacOS/Library/Codecs"</command>
+Not doing so, or forgetting to copy the resource fork, will result in errors such as:
+<command>GetDiskFragment() failed with error -2804: <<Unknown disk fragment>><<Unknown disk
+fragment>><pncrt.Shlb><></command>
</para></note>
</sect3>
--- MPlayer-20040618.orig/configure Tue Jun 15 09:01:02 2004
+++ MPlayer-20040618/configure Fri Jun 18 13:49:00 2004
@@ -191,6 +191,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]
@@ -1201,6 +1202,7 @@
_alsa=auto
_fastmemcpy=yes
_unrarlib=yes
+_macshlb=auto
_win32=auto
_dshow=yes
_select=yes
@@ -1584,6 +1586,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 ;;
@@ -4852,7 +4856,20 @@
_ld_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
@@ -5000,18 +5017,19 @@
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 || win32 ; then
+ if linux || freebsd || netbsd || win32 || darwin ; then
_real=yes
else
- echores "no (tested only on Linux/FreeBSD/NetBSD/Cygwin/MinGW)"
+ echores "no (tested only on Linux/FreeBSD/NetBSD/Cygwin/MinGW/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 \
+ {~,}/Applications/RealOne\ Player.app/Contents/MacOS/Library/Codecs \
"$_win32libdir"; do
if test -d "$I" ; then
_reallibdir="$I"
@@ -6366,6 +6384,9 @@
/* Mac OS X specific features */
$_def_macosx
+
+/* Mac OS X SHLB support */
+$_def_macshlb
/* Build our Win32-loader */
$_def_win32_loader
--- MPlayer-20040618.orig/etc/codecs.conf Fri Jun 11 10:09:24 2004
+++ MPlayer-20040618/etc/codecs.conf Fri Jun 18 16:57:06 2004
@@ -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
@@ -1904,6 +1956,13 @@
format 0x63727461 ; "atrc"
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"
More information about the MPlayer-dev-eng
mailing list