📄 realaudio.c
字号:
/***************************************************************************** * realaudio.c: a realaudio decoder that uses the realaudio library/dll ***************************************************************************** * Copyright (C) 2005 the VideoLAN team * $Id$ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_aout.h>#include <vlc_codec.h>#ifdef LOADER/* Need the w32dll loader from mplayer */# include <wine/winerror.h># include <ldt_keeper.h># include <wine/windef.h>void *WINAPI LoadLibraryA( char *name );void *WINAPI GetProcAddress( void *handle, char *func );int WINAPI FreeLibrary( void *handle );#endif#ifndef WINAPI# define WINAPI#endif#if defined(HAVE_DL_DLOPEN)# if defined(HAVE_DLFCN_H) /* Linux, BSD, Hurd */# include <dlfcn.h># endif# if defined(HAVE_SYS_DL_H)# include <sys/dl.h># endif#endif/***************************************************************************** * Module descriptor *****************************************************************************/static int Open ( vlc_object_t * );static void Close( vlc_object_t * );vlc_module_begin(); set_description( N_("RealAudio library decoder") ); set_capability( "decoder", 10 ); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_VCODEC ); set_callbacks( Open, Close );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/static int OpenDll( decoder_t * );static int OpenNativeDll( decoder_t *, char *, char * );static int OpenWin32Dll( decoder_t *, char *, char * );static void CloseDll( decoder_t * );static aout_buffer_t *Decode( decoder_t *, block_t ** );struct decoder_sys_t{ audio_date_t end_date; /* Output buffer */ char *p_out; unsigned int i_out; /* Codec params */ void *context; short int i_codec_flavor; void *dll; unsigned long (*raCloseCodec)(void*); unsigned long (*raDecode)(void*, char*, unsigned long, char*, unsigned int*, long); unsigned long (*raFlush)(unsigned long, unsigned long, unsigned long); unsigned long (*raFreeDecoder)(void*); void* (*raGetFlavorProperty)(void*, unsigned long, unsigned long, int*); unsigned long (*raInitDecoder)(void*, void*); unsigned long (*raOpenCodec)(void*); unsigned long (*raOpenCodec2)(void*, void*); unsigned long (*raSetFlavor)(void*, unsigned long); void (*raSetDLLAccessPath)(char*); void (*raSetPwd)(char*, char*);#if defined(LOADER) ldt_fs_t *ldt_fs;#endif void *win32_dll; unsigned long (WINAPI *wraCloseCodec)(void*); unsigned long (WINAPI *wraDecode)(void*, char*, unsigned long, char*, unsigned int*, long); unsigned long (WINAPI *wraFlush)(unsigned long, unsigned long, unsigned long); unsigned long (WINAPI *wraFreeDecoder)(void*); void* (WINAPI *wraGetFlavorProperty)(void*, unsigned long, unsigned long, int*); unsigned long (WINAPI *wraInitDecoder)(void*, void*); unsigned long (WINAPI *wraOpenCodec)(void*); unsigned long (WINAPI *wraOpenCodec2)(void*, void*); unsigned long (WINAPI *wraSetFlavor)(void*, unsigned long); void (WINAPI *wraSetDLLAccessPath)(char*); void (WINAPI *wraSetPwd)(char*, char*);};/* 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;void *__builtin_new(unsigned long size) {return malloc(size);}void __builtin_delete(void *p) {free(p);}static const int pi_channels_maps[7] ={ 0, AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE};/***************************************************************************** * Open: probe the decoder and return score ***************************************************************************** * Tries to launch a decoder and return score so that the interface is able * to choose. *****************************************************************************/static int Open( vlc_object_t *p_this ){ decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys = p_dec->p_sys; switch( p_dec->fmt_in.i_codec ) { case VLC_FOURCC('c','o','o','k'): case VLC_FOURCC('a','t','r','c'): case VLC_FOURCC('s','i','p','r'): break; default: return VLC_EGENERIC; } /* Channel detection */ if( p_dec->fmt_in.audio.i_channels <= 0 || p_dec->fmt_in.audio.i_channels > 6 ) { msg_Err( p_dec, "invalid number of channels (not between 1 and 6): %i", p_dec->fmt_in.audio.i_channels ); return VLC_EGENERIC; } p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) ); if( !p_sys ) return VLC_ENOMEM; memset( p_sys, 0, sizeof(decoder_sys_t) ); /* Flavor for SIPR codecs */ p_sys->i_codec_flavor = -1; if( p_dec->fmt_in.i_codec == VLC_FOURCC('s','i','p','r') ) { p_sys->i_codec_flavor = p_dec->fmt_in.audio.i_flavor; msg_Dbg( p_dec, "Got sipr flavor %d", p_sys->i_codec_flavor ); } if( OpenDll( p_dec ) != VLC_SUCCESS ) { free( p_sys ); return VLC_EGENERIC; }#ifdef LOADER if( p_sys->win32_dll ) Close( p_this );#endif es_format_Init( &p_dec->fmt_out, AUDIO_ES, AOUT_FMT_S16_NE ); p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate; p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels; p_dec->fmt_out.audio.i_bitspersample = p_dec->fmt_in.audio.i_bitspersample; p_dec->fmt_out.audio.i_physical_channels = p_dec->fmt_out.audio.i_original_channels = pi_channels_maps[p_dec->fmt_out.audio.i_channels]; aout_DateInit( &p_sys->end_date, p_dec->fmt_out.audio.i_rate ); aout_DateSet( &p_sys->end_date, 0 ); p_dec->pf_decode_audio = Decode; p_sys->p_out = malloc( 4096 * 10 ); if( !p_sys->p_out ) { free( p_sys ); return VLC_ENOMEM; } p_sys->i_out = 0; return VLC_SUCCESS;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t *p_this ){ decoder_t *p_dec = (decoder_t*)p_this; CloseDll( p_dec ); free( p_dec->p_sys->p_out ); free( p_dec->p_sys );}/***************************************************************************** * OpenDll: *****************************************************************************/static int OpenDll( decoder_t *p_dec ){ char *psz_dll; int i, i_result; /** Find the good path for the dlls.**/ char *ppsz_path[] = { ".",#ifndef WIN32 "/usr/local/RealPlayer8/Codecs", "/usr/RealPlayer8/Codecs", "/usr/lib/RealPlayer8/Codecs", "/opt/RealPlayer8/Codecs", "/usr/lib/RealPlayer9/users/Real/Codecs", "/usr/lib/RealPlayer10/codecs", "/usr/lib/RealPlayer10GOLD/codecs", "/usr/lib/helix/player/codecs", "/usr/lib64/RealPlayer8/Codecs", "/usr/lib64/RealPlayer9/users/Real/Codecs", "/usr/lib64/RealPlayer10/codecs", "/usr/lib64/RealPlayer10GOLD/codecs", "/usr/lib/win32", "/usr/lib/codecs", "/usr/local/lib/codecs",#endif NULL, NULL, NULL };#ifdef WIN32 char psz_win32_real_codecs[MAX_PATH + 1]; char psz_win32_helix_codecs[MAX_PATH + 1]; { HKEY h_key; DWORD i_type, i_data = MAX_PATH + 1, i_index = 1; char *p_data; p_data = psz_win32_real_codecs; if( RegOpenKeyEx( HKEY_CLASSES_ROOT, _T("Software\\RealNetworks\\Preferences\\DT_Codecs"), 0, KEY_READ, &h_key ) == ERROR_SUCCESS ) { if( RegQueryValueEx( h_key, _T(""), 0, &i_type, (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS && i_type == REG_SZ ) { int i_len = strlen( p_data ); if( i_len && p_data[i_len-1] == '\\' ) p_data[i_len-1] = 0; ppsz_path[i_index++] = p_data; msg_Err( p_dec, "Real: %s", p_data ); } RegCloseKey( h_key ); } p_data = psz_win32_helix_codecs; if( RegOpenKeyEx( HKEY_CLASSES_ROOT, _T("Helix\\HelixSDK\\10.0\\Preferences\\DT_Codecs"), 0, KEY_READ, &h_key ) == ERROR_SUCCESS ) { if( RegQueryValueEx( h_key, _T(""), 0, &i_type, (LPBYTE)p_data, &i_data ) == ERROR_SUCCESS && i_type == REG_SZ ) { int i_len = strlen( p_data ); if( i_len && p_data[i_len-1] == '\\' ) p_data[i_len-1] = 0; ppsz_path[i_index++] = p_data; msg_Err( p_dec, "Real: %s", p_data ); } RegCloseKey( h_key ); } }#endif /** Try the native libraries first **/#ifndef WIN32 for( i = 0; ppsz_path[i]; i++ ) { /* Old format */ if( asprintf( &psz_dll, "%s/%4.4s.so.6.0", ppsz_path[i], (char *)&p_dec->fmt_in.i_codec ) != -1 ) { i_result = OpenNativeDll( p_dec, ppsz_path[i], psz_dll ); free( psz_dll ); if( i_result == VLC_SUCCESS ) return VLC_SUCCESS; } /* New format */ if( asprintf( &psz_dll, "%s/%4.4s.so", ppsz_path[i], (char *)&p_dec->fmt_in.i_codec ) != -1 ) { i_result = OpenNativeDll( p_dec, ppsz_path[i], psz_dll ); free( psz_dll ); if( i_result == VLC_SUCCESS ) return VLC_SUCCESS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -