X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Frealaudio.c;h=90f620ffc8baa3fdb8c9e141ea11fe43981cfdf1;hb=857b51f9c9ace345a6b6a9a45a20829101830abb;hp=d284233213ea72176388fa3cb8b2e415f5fe245e;hpb=dcb53b6f05371d0aa60c106370d907d1914489db;p=vlc diff --git a/modules/codec/realaudio.c b/modules/codec/realaudio.c index d284233213..90f620ffc8 100644 --- a/modules/codec/realaudio.c +++ b/modules/codec/realaudio.c @@ -2,7 +2,7 @@ * realaudio.c: a realaudio decoder that uses the realaudio library/dll ***************************************************************************** * Copyright (C) 2005 the VideoLAN team - * $Id: quicktime.c 11664 2005-07-09 06:17:09Z courmisch $ + * $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 @@ -16,7 +16,7 @@ * * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -79,25 +79,13 @@ struct decoder_sys_t { audio_date_t end_date; - /* Frame buffer for data reordering */ - int i_subpacket; - int i_frame_size; - char *p_frame; - int i_frame; - /* Output buffer */ - char *p_out_buffer; char *p_out; unsigned int i_out; /* Codec params */ void *context; - int i_subpacket_size; - int i_subpacket_h; int i_codec_flavor; - int i_coded_frame_size; - int i_extra; - uint8_t *p_extra; void *dll; unsigned long (*raCloseCodec)(void*); @@ -119,20 +107,20 @@ struct decoder_sys_t #endif void *win32_dll; - unsigned long WINAPI (*wraCloseCodec)(void*); - unsigned long WINAPI (*wraDecode)(void*, char*, unsigned long, char*, + 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 (WINAPI *wraFlush)(unsigned long, unsigned long, unsigned long); - unsigned long WINAPI (*wraFreeDecoder)(void*); - void* WINAPI (*wraGetFlavorProperty)(void*, 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*); + 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 */ @@ -200,14 +188,17 @@ static int Open( vlc_object_t *p_this ) p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) ); memset( p_sys, 0, sizeof(decoder_sys_t) ); - if( p_dec->fmt_in.i_extra >= 10 ) + p_sys->i_codec_flavor = -1; + if( p_dec->fmt_in.i_codec == VLC_FOURCC('s','i','p','r') ) { - p_sys->i_subpacket_size = ((short *)(p_dec->fmt_in.p_extra))[0]; - p_sys->i_subpacket_h = ((short *)(p_dec->fmt_in.p_extra))[1]; - p_sys->i_codec_flavor = ((short *)(p_dec->fmt_in.p_extra))[2]; - p_sys->i_coded_frame_size = ((short *)(p_dec->fmt_in.p_extra))[3]; - p_sys->i_extra = ((short*)(p_dec->fmt_in.p_extra))[4]; - p_sys->p_extra = p_dec->fmt_in.p_extra + 10; + if( p_dec->fmt_in.audio.i_bitspersample > 1531 ) + p_sys->i_codec_flavor = 3; + else if( p_dec->fmt_in.audio.i_bitspersample > 937 ) + p_sys->i_codec_flavor = 1; + else if( p_dec->fmt_in.audio.i_bitspersample > 719 ) + p_sys->i_codec_flavor = 0; + else + p_sys->i_codec_flavor = 2; } if( OpenDll( p_dec ) != VLC_SUCCESS ) @@ -234,14 +225,7 @@ static int Open( vlc_object_t *p_this ) p_dec->pf_decode_audio = Decode; - p_sys->i_frame_size = - p_dec->fmt_in.audio.i_blockalign * p_sys->i_subpacket_h; - p_sys->p_frame = malloc( p_sys->i_frame_size ); - p_sys->i_subpacket = 0; - p_sys->i_frame = 0; - - p_sys->p_out_buffer = malloc( 4096 * 10 ); - p_sys->p_out = 0; + p_sys->p_out = malloc( 4096 * 10 ); p_sys->i_out = 0; return VLC_SUCCESS; @@ -255,8 +239,7 @@ static void Close( vlc_object_t *p_this ) decoder_t *p_dec = (decoder_t*)p_this; CloseDll( p_dec ); - if( p_dec->p_sys->p_frame ) free( p_dec->p_sys->p_frame ); - if( p_dec->p_sys->p_out_buffer ) free( p_dec->p_sys->p_out_buffer ); + if( p_dec->p_sys->p_out ) free( p_dec->p_sys->p_out ); free( p_dec->p_sys ); } @@ -265,7 +248,7 @@ static void Close( vlc_object_t *p_this ) *****************************************************************************/ static int OpenDll( decoder_t *p_dec ) { - char *psz_codec, *psz_dll; + char *psz_dll; int i, i_result; char *ppsz_path[] = @@ -281,50 +264,79 @@ static int OpenDll( decoder_t *p_dec ) "/usr/lib64/RealPlayer9/users/Real/Codecs", "/usr/lib/win32", #endif + NULL, + NULL, NULL }; - switch( p_dec->fmt_in.i_codec ) - { - case VLC_FOURCC('c','o','o','k'): - psz_codec = "cook.so.6.0"; - break; - case VLC_FOURCC('2','8','_','8'): - psz_codec = "28_8.so.6.0"; - break; - case VLC_FOURCC('1','4','_','4'): - psz_codec = "14_4.so.6.0"; - break; - default: - return VLC_EGENERIC; - } +#ifdef WIN32 + char psz_win32_real_codecs[MAX_PATH + 1]; + char psz_win32_helix_codecs[MAX_PATH + 1]; +#endif for( i = 0; ppsz_path[i]; i++ ) { - asprintf( &psz_dll, "%s/%s", ppsz_path[i], psz_codec ); + asprintf( &psz_dll, "%s/%4.4s.so.6.0", ppsz_path[i], + (char *)&p_dec->fmt_in.i_codec ); i_result = OpenNativeDll( p_dec, ppsz_path[i], psz_dll ); free( psz_dll ); if( i_result == VLC_SUCCESS ) return VLC_SUCCESS; } - switch( p_dec->fmt_in.i_codec ) +#ifdef WIN32 { - case VLC_FOURCC('c','o','o','k'): - psz_codec = "cook3260.dll"; - break; - case VLC_FOURCC('2','8','_','8'): - psz_codec = "28_83260.dll"; - break; - case VLC_FOURCC('1','4','_','4'): - psz_codec = "14_43260.dll"; - break; - default: - return VLC_EGENERIC; + 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 for( i = 0; ppsz_path[i]; i++ ) { - asprintf( &psz_dll, "%s\\%s", ppsz_path[i], psz_codec ); + /* New format */ + asprintf( &psz_dll, "%s\\%4.4s.dll", ppsz_path[i], + (char *)&p_dec->fmt_in.i_codec ); + i_result = OpenWin32Dll( p_dec, ppsz_path[i], psz_dll ); + free( psz_dll ); + if( i_result == VLC_SUCCESS ) return VLC_SUCCESS; + + /* Old format */ + asprintf( &psz_dll, "%s\\%4.4s3260.dll", ppsz_path[i], + (char *)&p_dec->fmt_in.i_codec ); i_result = OpenWin32Dll( p_dec, ppsz_path[i], psz_dll ); free( psz_dll ); if( i_result == VLC_SUCCESS ) return VLC_SUCCESS; @@ -348,9 +360,9 @@ static int OpenNativeDll( decoder_t *p_dec, char *psz_path, char *psz_dll ) p_dec->fmt_in.audio.i_bitspersample, p_dec->fmt_in.audio.i_channels, 100, /* quality */ - p_sys->i_subpacket_size, - p_sys->i_coded_frame_size, - p_sys->i_extra, p_sys->p_extra + p_dec->fmt_in.audio.i_blockalign, /* subpacket size */ + p_dec->fmt_in.audio.i_blockalign, /* coded frame size */ + p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra }; msg_Dbg( p_dec, "opening library '%s'", psz_dll ); @@ -400,26 +412,29 @@ static int OpenNativeDll( decoder_t *p_dec, char *psz_path, char *psz_dll ) goto error_native; } - i_result = p_sys->raSetFlavor( context, p_sys->i_codec_flavor ); - if( i_result ) + if( p_sys->i_codec_flavor >= 0 ) { - msg_Err( p_dec, "decoder flavor setup failed, error code: 0x%x", - i_result ); - goto error_native; - } + i_result = p_sys->raSetFlavor( context, p_sys->i_codec_flavor ); + if( i_result ) + { + msg_Err( p_dec, "decoder flavor setup failed, error code: 0x%x", + i_result ); + goto error_native; + } - p_prop = p_sys->raGetFlavorProperty( context, p_sys->i_codec_flavor, - 0, &i_prop ); - msg_Dbg( p_dec, "audio codec: [%d] %s", - p_sys->i_codec_flavor, (char *)p_prop ); + p_prop = p_sys->raGetFlavorProperty( context, p_sys->i_codec_flavor, + 0, &i_prop ); + msg_Dbg( p_dec, "audio codec: [%d] %s", + p_sys->i_codec_flavor, (char *)p_prop ); - p_prop = p_sys->raGetFlavorProperty( context, p_sys->i_codec_flavor, - 1, &i_prop ); - if( p_prop ) - { - int i_bps = ((*((int*)p_prop))+4)/8; - msg_Dbg( p_dec, "audio bitrate: %5.3f kbit/s (%d bps)", - (*((int*)p_prop))*0.001f, i_bps ); + p_prop = p_sys->raGetFlavorProperty( context, p_sys->i_codec_flavor, + 1, &i_prop ); + if( p_prop ) + { + int i_bps = ((*((int*)p_prop))+4)/8; + msg_Dbg( p_dec, "audio bitrate: %5.3f kbit/s (%d bps)", + (*((int*)p_prop))*0.001f, i_bps ); + } } p_sys->context = context; @@ -450,12 +465,12 @@ static int OpenWin32Dll( decoder_t *p_dec, char *psz_path, char *psz_dll ) p_dec->fmt_in.audio.i_bitspersample, p_dec->fmt_in.audio.i_channels, 100, /* quality */ - p_sys->i_subpacket_size, - p_sys->i_coded_frame_size, - p_sys->i_extra, p_sys->p_extra + p_dec->fmt_in.audio.i_blockalign, /* subpacket size */ + p_dec->fmt_in.audio.i_blockalign, /* coded frame size */ + p_dec->fmt_in.i_extra, p_dec->fmt_in.p_extra }; - msg_Err( p_dec, "opening win32 dll '%s'", psz_dll ); + msg_Dbg( p_dec, "opening win32 dll '%s'", psz_dll ); #ifdef LOADER Setup_LDT_Keeper(); @@ -509,26 +524,29 @@ static int OpenWin32Dll( decoder_t *p_dec, char *psz_path, char *psz_dll ) goto error_win32; } - i_result = p_sys->wraSetFlavor( context, p_sys->i_codec_flavor ); - if( i_result ) + if( p_sys->i_codec_flavor >= 0 ) { - msg_Err( p_dec, "decoder flavor setup failed, error code: 0x%x", - i_result ); - goto error_win32; - } + i_result = p_sys->wraSetFlavor( context, p_sys->i_codec_flavor ); + if( i_result ) + { + msg_Err( p_dec, "decoder flavor setup failed, error code: 0x%x", + i_result ); + goto error_win32; + } - p_prop = p_sys->wraGetFlavorProperty( context, p_sys->i_codec_flavor, - 0, &i_prop ); - msg_Dbg( p_dec, "audio codec: [%d] %s", - p_sys->i_codec_flavor, (char *)p_prop ); + p_prop = p_sys->wraGetFlavorProperty( context, p_sys->i_codec_flavor, + 0, &i_prop ); + msg_Dbg( p_dec, "audio codec: [%d] %s", + p_sys->i_codec_flavor, (char *)p_prop ); - p_prop = p_sys->wraGetFlavorProperty( context, p_sys->i_codec_flavor, - 1, &i_prop ); - if( p_prop ) - { - int i_bps = ((*((int*)p_prop))+4)/8; - msg_Dbg( p_dec, "audio bitrate: %5.3f kbit/s (%d bps)", - (*((int*)p_prop))*0.001f, i_bps ); + p_prop = p_sys->wraGetFlavorProperty( context, p_sys->i_codec_flavor, + 1, &i_prop ); + if( p_prop ) + { + int i_bps = ((*((int*)p_prop))+4)/8; + msg_Dbg( p_dec, "audio bitrate: %5.3f kbit/s (%d bps)", + (*((int*)p_prop))*0.001f, i_bps ); + } } p_sys->context = context; @@ -588,6 +606,8 @@ static aout_buffer_t *Decode( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; aout_buffer_t *p_aout_buffer = 0; + unsigned int i_result; + int i_samples; block_t *p_block; #ifdef LOADER @@ -604,112 +624,51 @@ static aout_buffer_t *Decode( decoder_t *p_dec, block_t **pp_block ) } #endif - /* Output 1024 samples at a time - * (the audio output doesn't like big audio packets) */ - if( p_sys->i_out ) - { - int i_out; - int i_samples = p_sys->i_out * 8 / - p_dec->fmt_out.audio.i_bitspersample / - p_dec->fmt_out.audio.i_channels; - - i_samples = __MIN( i_samples, 1024 ); - i_out = i_samples * p_dec->fmt_out.audio.i_bitspersample * - p_dec->fmt_out.audio.i_channels / 8; - - p_aout_buffer = p_dec->pf_aout_buffer_new( p_dec, i_samples ); - if( p_aout_buffer == NULL ) return NULL; - memcpy( p_aout_buffer->p_buffer, p_sys->p_out, i_out ); - - p_sys->i_out -= i_out; - p_sys->p_out += i_out; - - /* Date management */ - p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date ); - p_aout_buffer->end_date = - aout_DateIncrement( &p_sys->end_date, i_samples ); - - return p_aout_buffer; - } - - /* If we have a full frame ready then we can start decoding */ - if( p_sys->i_frame ) - { - unsigned int i_result; - - p_sys->p_out = p_sys->p_out_buffer; + if( pp_block == NULL || *pp_block == NULL ) return NULL; + p_block = *pp_block; - if( p_sys->dll ) - i_result = p_sys->raDecode( p_sys->context, p_sys->p_frame + - p_sys->i_frame_size - p_sys->i_frame, - p_dec->fmt_in.audio.i_blockalign, - p_sys->p_out, &p_sys->i_out, -1 ); - else - i_result = p_sys->wraDecode( p_sys->context, p_sys->p_frame + - p_sys->i_frame_size - p_sys->i_frame, - p_dec->fmt_in.audio.i_blockalign, - p_sys->p_out, &p_sys->i_out, -1 ); + if( p_sys->dll ) + i_result = p_sys->raDecode( p_sys->context, (char *)p_block->p_buffer, + (unsigned long)p_block->i_buffer, + p_sys->p_out, &p_sys->i_out, -1 ); + else + i_result = p_sys->wraDecode( p_sys->context, (char *)p_block->p_buffer, + (unsigned long)p_block->i_buffer, + p_sys->p_out, &p_sys->i_out, -1 ); #if 0 - msg_Err( p_dec, "decoded: %i samples (%i)", - p_sys->i_out * 8 / p_dec->fmt_out.audio.i_bitspersample / - p_dec->fmt_out.audio.i_channels, i_result ); + msg_Err( p_dec, "decoded: %i samples (%i)", + p_sys->i_out * 8 / p_dec->fmt_out.audio.i_bitspersample / + p_dec->fmt_out.audio.i_channels, i_result ); #endif - p_sys->i_frame -= p_dec->fmt_in.audio.i_blockalign; - - return Decode( p_dec, pp_block ); - } - - - if( pp_block == NULL || *pp_block == NULL ) return NULL; - p_block = *pp_block; - - //msg_Err( p_dec, "Decode: "I64Fd", %i", p_block->i_pts, p_block->i_buffer ); - /* Date management */ - if( /* !p_sys->i_subpacket && */ p_block && p_block->i_pts > 0 && + if( p_block->i_pts > 0 && p_block->i_pts != aout_DateGet( &p_sys->end_date ) ) { aout_DateSet( &p_sys->end_date, p_block->i_pts ); } -#if 0 if( !aout_DateGet( &p_sys->end_date ) ) { /* We've just started the stream, wait for the first PTS. */ if( p_block ) block_Release( p_block ); return NULL; } -#endif - - if( p_sys->i_subpacket_size ) - { - /* 'cook' way */ - int sps = p_sys->i_subpacket_size; - int w = p_dec->fmt_in.audio.i_blockalign; - int h = p_sys->i_subpacket_h; - /* int cfs = p_sys->i_coded_frame_size; */ - int x, y; - w /= sps; - y = p_sys->i_subpacket; + i_samples = p_sys->i_out * 8 / + p_dec->fmt_out.audio.i_bitspersample /p_dec->fmt_out.audio.i_channels; - for( x = 0; x < w; x++ ) - { - memcpy( p_sys->p_frame + sps * (h*x+((h+1)/2)*(y&1)+(y>>1)), - p_block->p_buffer, sps ); - p_block->p_buffer += sps; - } - - p_sys->i_subpacket = (p_sys->i_subpacket + 1) % p_sys->i_subpacket_h; + p_aout_buffer = + p_dec->pf_aout_buffer_new( p_dec, i_samples ); + if( p_aout_buffer ) + { + memcpy( p_aout_buffer->p_buffer, p_sys->p_out, p_sys->i_out ); - if( !p_sys->i_subpacket ) - { - /* We have a complete frame */ - p_sys->i_frame = p_sys->i_frame_size; - p_aout_buffer = Decode( p_dec, pp_block ); - } + /* Date management */ + p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date ); + p_aout_buffer->end_date = + aout_DateIncrement( &p_sys->end_date, i_samples ); } block_Release( p_block );