Mercurial > audlegacy-plugins
changeset 583:dad887da4642 trunk
[svn] - Fixed crash at opening AAC files
- However, still crashes when current song is stopped (can't fix this
now)
author | mf0102 |
---|---|
date | Tue, 30 Jan 2007 12:55:38 -0800 |
parents | f9e813a27f9f |
children | 5e2b137a24fe |
files | ChangeLog src/aac/src/libmp4.c |
diffstat | 2 files changed, 515 insertions(+), 532 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Tue Jan 30 11:17:25 2007 -0800 +++ b/ChangeLog Tue Jan 30 12:55:38 2007 -0800 @@ -1,3 +1,11 @@ +2007-01-30 19:17:25 +0000 William Pitcock <nenolod@sacredspiral.co.uk> + revision [1250] + - pass a valid InputPlayback handle to the play thread + + trunk/src/console/Audacious_Driver.cxx | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + + 2007-01-30 19:05:31 +0000 Giacomo Lozito <james@develia.org> revision [1248] - mpg123: do not try to pick a tuple from http:// sources
--- a/src/aac/src/libmp4.c Tue Jan 30 11:17:25 2007 -0800 +++ b/src/aac/src/libmp4.c Tue Jan 30 12:55:38 2007 -0800 @@ -13,110 +13,105 @@ #include <audacious/vfs.h> #include <audacious/i18n.h> -#define MP4_VERSION VERSION +#define MP4_VERSION VERSION /* * BUFFER_SIZE is the highest amount of memory that can be pulled. * We use this for sanity checks, among other things, as mp4ff needs * a labotomy sometimes. */ -#define BUFFER_SIZE FAAD_MIN_STREAMSIZE*64 +#define BUFFER_SIZE FAAD_MIN_STREAMSIZE*64 /* * AAC_MAGIC is the pattern that marks the beginning of an MP4 container. */ #define AAC_MAGIC (unsigned char [4]) { 0xFF, 0xF9, 0x5C, 0x80 } -static void mp4_init(void); -static void mp4_about(void); -static void mp4_play(InputPlayback *); -static void mp4_stop(InputPlayback *); -static void mp4_pause(InputPlayback *, short); -static void mp4_seek(InputPlayback *, int); -static int mp4_getTime(InputPlayback *); -static void mp4_cleanup(void); -static int mp4_IsOurFD(char *, VFSFile *); -static int mp4_IsOurFile(char *); -static void mp4_getSongTitle(char *filename, char **, int *); -static void* mp4Decode(void *); -static TitleInput *mp4_get_song_tuple(char *); - -void audmp4_file_info_box(gchar *); -gboolean buffer_playing; +static void mp4_init(void); +static void mp4_about(void); +static int mp4_is_our_file(char *); +static void mp4_play(InputPlayback *); +static void mp4_stop(InputPlayback *); +static void mp4_pause(InputPlayback *, short); +static void mp4_seek(InputPlayback *, int); +static int mp4_get_time(InputPlayback *); +static void mp4_cleanup(void); +static void mp4_get_song_title_len(char *filename, char **, int *); +static TitleInput* mp4_get_song_tuple(char *); +static int mp4_is_our_fd(char *, VFSFile *); gchar *mp4_fmts[] = { "m4a", "mp4", "aac", NULL }; +static void * mp4_decode(void *); +static gchar * mp4_get_song_title(char *filename); +static void audmp4_file_info_box(gchar *); +gboolean buffer_playing; + InputPlugin mp4_ip = - { - 0, // handle - 0, // filename +{ + 0, // handle + 0, // filename "MP4 Audio Plugin", mp4_init, mp4_about, - 0, // configuration - mp4_IsOurFile, - 0, //scandir + 0, // configuration + mp4_is_our_file, + 0, //scandir mp4_play, mp4_stop, mp4_pause, mp4_seek, - 0, // set equalizer - mp4_getTime, - 0, // get volume + 0, // set equalizer + mp4_get_time, + 0, // get volume 0, mp4_cleanup, - 0, // obsolete - 0, // send visualisation data - 0, // set player window info - 0, // set song title text - mp4_getSongTitle, // get song title text + 0, // obsolete + 0, // send visualisation data + 0, // set player window info + 0, // set song title text + mp4_get_song_title_len, // get song title text 0, // info box - 0, // to output plugin + 0, // to output plugin mp4_get_song_tuple, 0, 0, - mp4_IsOurFD, + mp4_is_our_fd, mp4_fmts, - }; +}; -typedef struct _mp4cfg{ - gshort file_type; -#define FILE_UNKNOW 0 +typedef struct _mp4cfg +{ +#define FILE_UNKNOWN 0 #define FILE_MP4 1 #define FILE_AAC 2 -} Mp4Config; + gshort file_type; +} Mp4Config; -static Mp4Config mp4cfg; -static GThread *decodeThread; -GStaticMutex mutex = G_STATIC_MUTEX_INIT; -static int seekPosition = -1; +static Mp4Config mp4cfg; +static GThread *decodeThread; +GStaticMutex mutex = G_STATIC_MUTEX_INIT; +static int seekPosition = -1; void getMP4info(char*); int getAACTrack(mp4ff_t *); -static uint32_t mp4_read_callback(void *data, void *buffer, uint32_t len) +static guint32 mp4_read_callback(void *data, void *buffer, guint32 len) { - if (data == NULL || buffer == NULL) - return -1; + if (data == NULL || buffer == NULL) + return -1; - return vfs_fread(buffer, 1, len, (VFSFile *) data); + return vfs_fread(buffer, 1, len, (VFSFile *) data); } -static uint32_t mp4_seek_callback(void *data, uint64_t pos) +static guint32 mp4_seek_callback(void *data, guint64 pos) { - if (data == NULL) - return -1; + if (data == NULL) + return -1; - return vfs_fseek((VFSFile *) data, pos, SEEK_SET); + return vfs_fseek((VFSFile *) data, pos, SEEK_SET); } -/* - * Function extname (filename) - * - * Return pointer within filename to its extenstion, or NULL if - * filename has no extension. - * - */ static gchar * extname(const char *filename) { @@ -130,32 +125,33 @@ InputPlugin *get_iplugin_info(void) { - return(&mp4_ip); + return(&mp4_ip); } static void mp4_init(void) { - mp4cfg.file_type = FILE_UNKNOW; - seekPosition = -1; - return; + mp4cfg.file_type = FILE_UNKNOWN; + seekPosition = -1; + return; } static void mp4_play(InputPlayback *playback) { - buffer_playing = TRUE; - decodeThread = g_thread_create((GThreadFunc)mp4Decode, playback, TRUE, NULL); + buffer_playing = TRUE; + decodeThread = g_thread_create((GThreadFunc)mp4_decode, playback, TRUE, NULL); } static void mp4_stop(InputPlayback *playback) { - if(buffer_playing){ - buffer_playing = FALSE; - playback->output->close_audio(); - g_thread_join(decodeThread); - } + if (buffer_playing) + { + buffer_playing = FALSE; + g_thread_join(decodeThread); + playback->output->close_audio(); + } } -static int mp4_IsOurFile(char *filename) +static int mp4_is_our_file(char *filename) { VFSFile *file; gchar* extension; @@ -170,16 +166,16 @@ vfs_fclose(file); return 1; } - if (!memcmp(magic, "ID3", 3)) { // ID3 tag bolted to the front, obfuscated magic bytes + if (!memcmp(magic, "ID3", 3)) { // ID3 tag bolted to the front, obfuscated magic bytes vfs_fclose(file); if (extension &&( - !strcasecmp(extension, ".mp4") || // official extension - !strcasecmp(extension, ".m4a") || // Apple mp4 extension - !strcasecmp(extension, ".aac") // old MPEG2/4-AAC extension - )) - return 1; - else - return 0; + !strcasecmp(extension, ".mp4") || // official extension + !strcasecmp(extension, ".m4a") || // Apple mp4 extension + !strcasecmp(extension, ".aac") // old MPEG2/4-AAC extension + )) + return 1; + else + return 0; } if (!memcmp(&magic[4], "ftyp", 4)) { vfs_fclose(file); @@ -190,7 +186,7 @@ return 0; } -static int mp4_IsOurFD(char *filename, VFSFile* file) +static int mp4_is_our_fd(char *filename, VFSFile* file) { gchar* extension; gchar magic[8]; @@ -201,11 +197,11 @@ return 1; if (!memcmp(&magic[4], "ftyp", 4)) return 1; - if (!memcmp(magic, "ID3", 3)) { // ID3 tag bolted to the front, obfuscated magic bytes + if (!memcmp(magic, "ID3", 3)) { // ID3 tag bolted to the front, obfuscated magic bytes if (extension &&( - !strcasecmp(extension, ".mp4") || // official extension - !strcasecmp(extension, ".m4a") || // Apple mp4 extension - !strcasecmp(extension, ".aac") // old MPEG2/4-AAC extension + !strcasecmp(extension, ".mp4") || // official extension + !strcasecmp(extension, ".m4a") || // Apple mp4 extension + !strcasecmp(extension, ".aac") // old MPEG2/4-AAC extension )) return 1; else @@ -214,34 +210,34 @@ return 0; } -static void mp4_about(void) +static void mp4_about(void) { static GtkWidget *aboutbox; if(aboutbox!=NULL) return; aboutbox = xmms_show_message("About MP4 AAC player plugin", - "Using libfaad2-" FAAD2_VERSION " for decoding.\n" - "Copyright (c) 2005-2006 Audacious team", - "Ok", FALSE, NULL, NULL); + "Using libfaad2-" FAAD2_VERSION " for decoding.\n" + "Copyright (c) 2005-2006 Audacious team", + "Ok", FALSE, NULL, NULL); g_signal_connect(G_OBJECT(aboutbox), "destroy", G_CALLBACK(gtk_widget_destroyed), &aboutbox); } -static void mp4_pause(InputPlayback *playback, short flag) +static void mp4_pause(InputPlayback *playback, short flag) { playback->output->pause(flag); } -static void mp4_seek(InputPlayback *data, int time) +static void mp4_seek(InputPlayback *data, int time) { seekPosition = time; while(buffer_playing && seekPosition!=-1) xmms_usleep(10000); } -static int mp4_getTime(InputPlayback *playback) +static int mp4_get_time(InputPlayback *playback) { if(!buffer_playing) return (-1); @@ -249,526 +245,505 @@ return (playback->output->output_time()); } -static void mp4_cleanup(void) +static void mp4_cleanup(void) { } static TitleInput *mp4_get_song_tuple(char *fn) { - mp4ff_callback_t *mp4cb = g_malloc0(sizeof(mp4ff_callback_t)); - VFSFile *mp4fh; - mp4ff_t *mp4file; - TitleInput *input = NULL; - gchar *filename = g_strdup(fn); + mp4ff_callback_t *mp4cb = g_malloc0(sizeof(mp4ff_callback_t)); + VFSFile *mp4fh; + mp4ff_t *mp4file; + TitleInput *input = NULL; + gchar *filename = g_strdup(fn); - mp4fh = vfs_fopen(filename, "rb"); - mp4cb->read = mp4_read_callback; - mp4cb->seek = mp4_seek_callback; - mp4cb->user_data = mp4fh; + mp4fh = vfs_fopen(filename, "rb"); + mp4cb->read = mp4_read_callback; + mp4cb->seek = mp4_seek_callback; + mp4cb->user_data = mp4fh; - if (!(mp4file = mp4ff_open_read(mp4cb))) { - g_free(mp4cb); - vfs_fclose(mp4fh); - } else { - gint mp4track= getAACTrack(mp4file); - gint numSamples = mp4ff_num_samples(mp4file, mp4track); - guint framesize = 1024; - gulong samplerate; - guchar channels; - gint msDuration; - mp4AudioSpecificConfig mp4ASC; - gchar *tmpval; - guchar *buffer = NULL; - guint bufferSize = 0; - faacDecHandle decoder; + if (!(mp4file = mp4ff_open_read(mp4cb))) { + g_free(mp4cb); + vfs_fclose(mp4fh); + } else { + gint mp4track= getAACTrack(mp4file); + gint numSamples = mp4ff_num_samples(mp4file, mp4track); + guint framesize = 1024; + gulong samplerate; + guchar channels; + gint msDuration; + mp4AudioSpecificConfig mp4ASC; + gchar *tmpval; + guchar *buffer = NULL; + guint bufferSize = 0; + faacDecHandle decoder; - if (mp4track == -1) - return NULL; + if (mp4track == -1) + return NULL; + + decoder = faacDecOpen(); + mp4ff_get_decoder_config(mp4file, mp4track, &buffer, &bufferSize); - decoder = faacDecOpen(); - mp4ff_get_decoder_config(mp4file, mp4track, &buffer, &bufferSize); + if ( !buffer ) { + faacDecClose(decoder); + return FALSE; + } + if ( faacDecInit2(decoder, buffer, bufferSize, + &samplerate, &channels) < 0 ) { + faacDecClose(decoder); - if ( !buffer ) { - faacDecClose(decoder); - return FALSE; - } - if ( faacDecInit2(decoder, buffer, bufferSize, - &samplerate, &channels) < 0 ) { - faacDecClose(decoder); + return FALSE; + } - return FALSE; - } + /* Add some hacks for SBR profile */ + if (AudioSpecificConfig(buffer, bufferSize, &mp4ASC) >= 0) { + if (mp4ASC.frameLengthFlag == 1) framesize = 960; + if (mp4ASC.sbr_present_flag == 1) framesize *= 2; + } + + g_free(buffer); - /* Add some hacks for SBR profile */ - if (AudioSpecificConfig(buffer, bufferSize, &mp4ASC) >= 0) { - if (mp4ASC.frameLengthFlag == 1) framesize = 960; - if (mp4ASC.sbr_present_flag == 1) framesize *= 2; - } - - g_free(buffer); + faacDecClose(decoder); + + msDuration = ((float)numSamples * (float)(framesize - 1.0)/(float)samplerate) * 1000; + + input = bmp_title_input_new(); - faacDecClose(decoder); - - msDuration = ((float)numSamples * (float)(framesize - 1.0)/(float)samplerate) * 1000; + mp4ff_meta_get_title(mp4file, &input->track_name); + mp4ff_meta_get_album(mp4file, &input->album_name); + mp4ff_meta_get_artist(mp4file, &input->performer); + mp4ff_meta_get_date(mp4file, &tmpval); + mp4ff_meta_get_genre(mp4file, &input->genre); - input = bmp_title_input_new(); + if (tmpval) + { + input->year = atoi(tmpval); + free(tmpval); + } - mp4ff_meta_get_title(mp4file, &input->track_name); - mp4ff_meta_get_album(mp4file, &input->album_name); - mp4ff_meta_get_artist(mp4file, &input->performer); - mp4ff_meta_get_date(mp4file, &tmpval); - mp4ff_meta_get_genre(mp4file, &input->genre); + input->file_name = g_path_get_basename(filename); + input->file_path = g_path_get_dirname(filename); + input->file_ext = extname(filename); + input->length = msDuration; - if (tmpval) - { - input->year = atoi(tmpval); - free(tmpval); - } + free (mp4cb); + vfs_fclose(mp4fh); + } - input->file_name = g_path_get_basename(filename); - input->file_path = g_path_get_dirname(filename); - input->file_ext = extname(filename); - input->length = msDuration; + return input; +} - free (mp4cb); - vfs_fclose(mp4fh); - } - - return input; +static void mp4_get_song_title_len(char *filename, char **title, int *len) +{ + (*title) = mp4_get_song_title(filename); + (*len) = -1; } static gchar *mp4_get_song_title(char *filename) { - mp4ff_callback_t *mp4cb = g_malloc0(sizeof(mp4ff_callback_t)); - VFSFile *mp4fh; - mp4ff_t *mp4file; - gchar *title = NULL; + mp4ff_callback_t *mp4cb = g_malloc0(sizeof(mp4ff_callback_t)); + VFSFile *mp4fh; + mp4ff_t *mp4file; + gchar *title = NULL; - mp4fh = vfs_fopen(filename, "rb"); - mp4cb->read = mp4_read_callback; - mp4cb->seek = mp4_seek_callback; - mp4cb->user_data = mp4fh; + mp4fh = vfs_fopen(filename, "rb"); + mp4cb->read = mp4_read_callback; + mp4cb->seek = mp4_seek_callback; + mp4cb->user_data = mp4fh; - if (!(mp4file = mp4ff_open_read(mp4cb))) { - g_free(mp4cb); - vfs_fclose(mp4fh); - } else { - TitleInput *input; - gchar *tmpval; - - input = bmp_title_input_new(); + if (!(mp4file = mp4ff_open_read(mp4cb))) { + g_free(mp4cb); + vfs_fclose(mp4fh); + } else { + TitleInput *input; + gchar *tmpval; - mp4ff_meta_get_title(mp4file, &input->track_name); - mp4ff_meta_get_album(mp4file, &input->album_name); - mp4ff_meta_get_artist(mp4file, &input->performer); - mp4ff_meta_get_date(mp4file, &tmpval); - mp4ff_meta_get_genre(mp4file, &input->genre); + input = bmp_title_input_new(); - if (tmpval) - { - input->year = atoi(tmpval); - free(tmpval); - } + mp4ff_meta_get_title(mp4file, &input->track_name); + mp4ff_meta_get_album(mp4file, &input->album_name); + mp4ff_meta_get_artist(mp4file, &input->performer); + mp4ff_meta_get_date(mp4file, &tmpval); + mp4ff_meta_get_genre(mp4file, &input->genre); - input->file_name = g_path_get_basename(filename); - input->file_path = g_path_get_dirname(filename); - input->file_ext = extname(filename); - - title = xmms_get_titlestring(xmms_get_gentitle_format(), input); + if (tmpval) + { + input->year = atoi(tmpval); + free(tmpval); + } - free (input->track_name); - free (input->album_name); - free (input->performer); - free (input->genre); - free (input->file_name); - free (input->file_path); - free (input); + input->file_name = g_path_get_basename(filename); + input->file_path = g_path_get_dirname(filename); + input->file_ext = extname(filename); + + title = xmms_get_titlestring(xmms_get_gentitle_format(), input); - free (mp4cb); - vfs_fclose(mp4fh); - } + free (input->track_name); + free (input->album_name); + free (input->performer); + free (input->genre); + free (input->file_name); + free (input->file_path); + free (input); - if (!title) - { - title = g_path_get_basename(filename); - if (extname(title)) - *(extname(title) - 1) = '\0'; - } + free (mp4cb); + vfs_fclose(mp4fh); + } - return title; -} + if (!title) + { + title = g_path_get_basename(filename); + if (extname(title)) + *(extname(title) - 1) = '\0'; + } -static void mp4_getSongTitle(char *filename, char **title_real, int *len_real) -{ - (*title_real) = mp4_get_song_title(filename); - (*len_real) = -1; + return title; } static int my_decode_mp4( InputPlayback *playback, char *filename, mp4ff_t *mp4file ) { - // We are reading a MP4 file - gint mp4track= getAACTrack(mp4file); + // We are reading a MP4 file + gint mp4track= getAACTrack(mp4file); - if ( mp4track < 0 ) { - //TODO: check here for others Audio format..... - g_print("Unsupported Audio track type\n"); - } - else { - faacDecHandle decoder; - unsigned char *buffer = NULL; - guint bufferSize = 0; - gulong samplerate; - guchar channels; - //guint avgBitrate; - gulong msDuration; - gulong numSamples; - gulong sampleID = 1; - unsigned int framesize = 1024; - mp4AudioSpecificConfig mp4ASC; + if ( mp4track < 0 ) { + //TODO: check here for others Audio format..... + g_print("Unsupported Audio track type\n"); + } + else { + faacDecHandle decoder; + unsigned char *buffer = NULL; + guint bufferSize = 0; + gulong samplerate; + guchar channels; + //guint avgBitrate; + gulong msDuration; + gulong numSamples; + gulong sampleID = 1; + unsigned int framesize = 1024; + mp4AudioSpecificConfig mp4ASC; - gchar *xmmstitle = NULL; + gchar *xmmstitle = NULL; + xmmstitle = mp4_get_song_title(filename); + if(xmmstitle == NULL) + xmmstitle = g_strdup(filename); - xmmstitle = mp4_get_song_title(filename); - - if(xmmstitle == NULL) - xmmstitle = g_strdup(filename); + decoder = faacDecOpen(); + mp4ff_get_decoder_config(mp4file, mp4track, &buffer, &bufferSize); + if ( !buffer ) { + faacDecClose(decoder); + return FALSE; + } + if ( faacDecInit2(decoder, buffer, bufferSize, + &samplerate, &channels) < 0 ) { + faacDecClose(decoder); - decoder = faacDecOpen(); - mp4ff_get_decoder_config(mp4file, mp4track, &buffer, &bufferSize); - if ( !buffer ) { - faacDecClose(decoder); - return FALSE; - } - if ( faacDecInit2(decoder, buffer, bufferSize, - &samplerate, &channels) < 0 ) { - faacDecClose(decoder); + return FALSE; + } - return FALSE; - } + /* Add some hacks for SBR profile */ + if (AudioSpecificConfig(buffer, bufferSize, &mp4ASC) >= 0) { + if (mp4ASC.frameLengthFlag == 1) framesize = 960; + if (mp4ASC.sbr_present_flag == 1) framesize *= 2; + } + + g_free(buffer); + if( !channels ) { + faacDecClose(decoder); - /* Add some hacks for SBR profile */ - if (AudioSpecificConfig(buffer, bufferSize, &mp4ASC) >= 0) { - if (mp4ASC.frameLengthFlag == 1) framesize = 960; - if (mp4ASC.sbr_present_flag == 1) framesize *= 2; - } - - g_free(buffer); - if( !channels ) { - faacDecClose(decoder); + return FALSE; + } + numSamples = mp4ff_num_samples(mp4file, mp4track); + msDuration = ((float)numSamples * (float)(framesize - 1.0)/(float)samplerate) * 1000; + playback->output->open_audio(FMT_S16_NE, samplerate, channels); + playback->output->flush(0); - return FALSE; - } - numSamples = mp4ff_num_samples(mp4file, mp4track); - msDuration = ((float)numSamples * (float)(framesize - 1.0)/(float)samplerate) * 1000; - playback->output->open_audio(FMT_S16_NE, samplerate, channels); - playback->output->flush(0); + mp4_ip.set_info(xmmstitle, msDuration, + mp4ff_get_avg_bitrate( mp4file, mp4track ), + samplerate,channels); - mp4_ip.set_info(xmmstitle, msDuration, - mp4ff_get_avg_bitrate( mp4file, mp4track ), - samplerate,channels); + while ( buffer_playing ) { + void* sampleBuffer; + faacDecFrameInfo frameInfo; + gint rc; - while ( buffer_playing ) { - void* sampleBuffer; - faacDecFrameInfo frameInfo; - gint rc; + /* Seek if seek position has changed */ + if ( seekPosition!=-1 ) { + sampleID = (float)seekPosition*(float)samplerate/(float)(framesize - 1.0); + playback->output->flush(seekPosition*1000); + seekPosition = -1; + } - /* Seek if seek position has changed */ - if ( seekPosition!=-1 ) { - sampleID = (float)seekPosition*(float)samplerate/(float)(framesize - 1.0); - playback->output->flush(seekPosition*1000); - seekPosition = -1; - } + /* Otherwise continue playing */ + buffer=NULL; + bufferSize=0; - /* Otherwise continue playing */ - buffer=NULL; - bufferSize=0; + /* If we've run to the end of the file, we're done. */ + if(sampleID >= numSamples){ + /* Finish playing before we close the + output. */ + while ( playback->output->buffer_playing() ) { + xmms_usleep(10000); + } - /* If we've run to the end of the file, we're done. */ - if(sampleID >= numSamples){ - /* Finish playing before we close the - output. */ - while ( playback->output->buffer_playing() ) { - xmms_usleep(10000); - } + playback->output->flush(seekPosition*1000); + playback->output->close_audio(); + faacDecClose(decoder); - playback->output->flush(seekPosition*1000); - playback->output->close_audio(); - faacDecClose(decoder); + g_static_mutex_lock(&mutex); + buffer_playing = FALSE; + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); - g_static_mutex_lock(&mutex); - buffer_playing = FALSE; - g_static_mutex_unlock(&mutex); - g_thread_exit(NULL); + return FALSE; + } + rc= mp4ff_read_sample(mp4file, mp4track, + sampleID++, &buffer, &bufferSize); - return FALSE; - } - rc= mp4ff_read_sample(mp4file, mp4track, - sampleID++, &buffer, &bufferSize); + /*g_print(":: %d/%d\n", sampleID-1, numSamples);*/ - /*g_print(":: %d/%d\n", sampleID-1, numSamples);*/ + /* If we can't read the file, we're done. */ + if((rc == 0) || (buffer== NULL) || (bufferSize == 0) || (bufferSize > BUFFER_SIZE)){ + g_print("MP4: read error\n"); + sampleBuffer = NULL; + sampleID=0; + playback->output->buffer_free(); + playback->output->close_audio(); - /* If we can't read the file, we're done. */ - if((rc == 0) || (buffer== NULL) || (bufferSize == 0) || (bufferSize > BUFFER_SIZE)){ - g_print("MP4: read error\n"); - sampleBuffer = NULL; - sampleID=0; - playback->output->buffer_free(); - playback->output->close_audio(); + faacDecClose(decoder); - faacDecClose(decoder); + return FALSE; + } - return FALSE; - } +/* g_print(" :: %d/%d\n", bufferSize, BUFFER_SIZE); */ -/* g_print(" :: %d/%d\n", bufferSize, BUFFER_SIZE); */ + sampleBuffer= faacDecDecode(decoder, + &frameInfo, + buffer, + bufferSize); - sampleBuffer= faacDecDecode(decoder, - &frameInfo, - buffer, - bufferSize); - - /* If there was an error decoding, we're done. */ - if(frameInfo.error > 0){ - g_print("MP4: %s\n", - faacDecGetErrorMessage(frameInfo.error)); - playback->output->close_audio(); - faacDecClose(decoder); + /* If there was an error decoding, we're done. */ + if(frameInfo.error > 0){ + g_print("MP4: %s\n", + faacDecGetErrorMessage(frameInfo.error)); + playback->output->close_audio(); + faacDecClose(decoder); - return FALSE; - } - if(buffer){ - g_free(buffer); - buffer=NULL; - bufferSize=0; - } - if (buffer_playing == FALSE) - { - playback->output->close_audio(); - return FALSE; - } - produce_audio(playback->output->written_time(), - FMT_S16_NE, - channels, - frameInfo.samples<<1, - sampleBuffer, &buffer_playing); - } - playback->output->close_audio(); + return FALSE; + } + if(buffer){ + g_free(buffer); + buffer=NULL; + bufferSize=0; + } + if (buffer_playing == FALSE) + { + playback->output->close_audio(); + return FALSE; + } + produce_audio(playback->output->written_time(), + FMT_S16_NE, + channels, + frameInfo.samples<<1, + sampleBuffer, &buffer_playing); + } + playback->output->close_audio(); - faacDecClose(decoder); - } + faacDecClose(decoder); + } - return TRUE; + return TRUE; } static void my_decode_aac( InputPlayback *playback, char *filename ) { - // WE ARE READING AN AAC FILE - VFSFile *file = NULL; - faacDecHandle decoder = 0; - guchar *buffer = 0; - gulong bufferconsumed = 0; - gulong samplerate = 0; - guchar channels; - gulong buffervalid = 0; - TitleInput* input; - gchar *temp = g_strdup(filename); - gchar *ext = strrchr(temp, '.'); - gchar *xmmstitle = NULL; - faacDecConfigurationPtr config; + // WE ARE READING AN AAC FILE + VFSFile *file = NULL; + faacDecHandle decoder = 0; + guchar *buffer = 0; + gulong bufferconsumed = 0; + gulong samplerate = 0; + guchar channels; + gulong buffervalid = 0; + TitleInput* input; + gchar *temp = g_strdup(filename); + gchar *ext = strrchr(temp, '.'); + gchar *xmmstitle = NULL; + faacDecConfigurationPtr config; - if((file = vfs_fopen(filename, "rb")) == 0){ - g_print("AAC: can't find file %s\n", filename); - buffer_playing = FALSE; - g_static_mutex_unlock(&mutex); - g_thread_exit(NULL); - } - if((decoder = faacDecOpen()) == NULL){ - g_print("AAC: Open Decoder Error\n"); - vfs_fclose(file); - buffer_playing = FALSE; - g_static_mutex_unlock(&mutex); - g_thread_exit(NULL); - } - config = faacDecGetCurrentConfiguration(decoder); - config->useOldADTSFormat = 0; - faacDecSetConfiguration(decoder, config); - if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ - g_print("AAC: error g_malloc\n"); - vfs_fclose(file); - buffer_playing = FALSE; - faacDecClose(decoder); - g_static_mutex_unlock(&mutex); - g_thread_exit(NULL); - } - if((buffervalid = vfs_fread(buffer, 1, BUFFER_SIZE, file))==0){ - g_print("AAC: Error reading file\n"); - g_free(buffer); - vfs_fclose(file); - buffer_playing = FALSE; - faacDecClose(decoder); - g_static_mutex_unlock(&mutex); - g_thread_exit(NULL); - } - XMMS_NEW_TITLEINPUT(input); - input->file_name = (char*)g_basename(temp); - input->file_ext = ext ? ext+1 : NULL; - input->file_path = temp; - if(!strncmp((char*)buffer, "ID3", 3)){ - gint size = 0; + if((file = vfs_fopen(filename, "rb")) == 0){ + g_print("AAC: can't find file %s\n", filename); + buffer_playing = FALSE; + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); + } + if((decoder = faacDecOpen()) == NULL){ + g_print("AAC: Open Decoder Error\n"); + vfs_fclose(file); + buffer_playing = FALSE; + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); + } + config = faacDecGetCurrentConfiguration(decoder); + config->useOldADTSFormat = 0; + faacDecSetConfiguration(decoder, config); + if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ + g_print("AAC: error g_malloc\n"); + vfs_fclose(file); + buffer_playing = FALSE; + faacDecClose(decoder); + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); + } + if((buffervalid = vfs_fread(buffer, 1, BUFFER_SIZE, file))==0){ + g_print("AAC: Error reading file\n"); + g_free(buffer); + vfs_fclose(file); + buffer_playing = FALSE; + faacDecClose(decoder); + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); + } + XMMS_NEW_TITLEINPUT(input); + input->file_name = (char*)g_basename(temp); + input->file_ext = ext ? ext+1 : NULL; + input->file_path = temp; + if(!strncmp((char*)buffer, "ID3", 3)){ + gint size = 0; - vfs_fseek(file, 0, SEEK_SET); - size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; - size+=10; - vfs_fread(buffer, 1, size, file); - buffervalid = vfs_fread(buffer, 1, BUFFER_SIZE, file); - } - xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); - if(xmmstitle == NULL) - xmmstitle = g_strdup(input->file_name); - if(temp) g_free(temp); - if(input->performer) g_free(input->performer); - if(input->album_name) g_free(input->album_name); - if(input->track_name) g_free(input->track_name); - if(input->genre) g_free(input->genre); - g_free(input); - bufferconsumed = faacDecInit(decoder, - buffer, - buffervalid, - &samplerate, - &channels); - if(playback->output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ - g_print("AAC: Output Error\n"); - g_free(buffer); buffer=0; - faacDecClose(decoder); - vfs_fclose(file); - playback->output->close_audio(); - g_free(xmmstitle); - buffer_playing = FALSE; - g_static_mutex_unlock(&mutex); - g_thread_exit(NULL); - } + vfs_fseek(file, 0, SEEK_SET); + size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; + size+=10; + vfs_fread(buffer, 1, size, file); + buffervalid = vfs_fread(buffer, 1, BUFFER_SIZE, file); + } + xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); + if(xmmstitle == NULL) + xmmstitle = g_strdup(input->file_name); + if(temp) g_free(temp); + if(input->performer) g_free(input->performer); + if(input->album_name) g_free(input->album_name); + if(input->track_name) g_free(input->track_name); + if(input->genre) g_free(input->genre); + g_free(input); + bufferconsumed = faacDecInit(decoder, + buffer, + buffervalid, + &samplerate, + &channels); + if(playback->output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ + g_print("AAC: Output Error\n"); + g_free(buffer); buffer=0; + faacDecClose(decoder); + vfs_fclose(file); + playback->output->close_audio(); + g_free(xmmstitle); + buffer_playing = FALSE; + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); + } - mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); - playback->output->flush(0); + mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); + playback->output->flush(0); - while(buffer_playing && buffervalid > 0){ - faacDecFrameInfo finfo; - unsigned long samplesdecoded; - char* sample_buffer = NULL; + while(buffer_playing && buffervalid > 0){ + faacDecFrameInfo finfo; + unsigned long samplesdecoded; + char* sample_buffer = NULL; - if(bufferconsumed > 0){ - memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); - buffervalid -= bufferconsumed; - buffervalid += vfs_fread(&buffer[buffervalid], 1, - BUFFER_SIZE-buffervalid, file); - bufferconsumed = 0; - } - sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid); - if(finfo.error){ - config = faacDecGetCurrentConfiguration(decoder); - if(config->useOldADTSFormat != 1){ - faacDecClose(decoder); - decoder = faacDecOpen(); - config = faacDecGetCurrentConfiguration(decoder); - config->useOldADTSFormat = 1; - faacDecSetConfiguration(decoder, config); - finfo.bytesconsumed=0; - finfo.samples = 0; - faacDecInit(decoder, - buffer, - buffervalid, - &samplerate, - &channels); - }else{ - g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error)); - buffervalid = 0; - } - } - bufferconsumed += finfo.bytesconsumed; - samplesdecoded = finfo.samples; - if((samplesdecoded<=0) && !sample_buffer){ - g_print("AAC: error sample decoding\n"); - continue; - } - produce_audio(playback->output->written_time(), - FMT_S16_LE, channels, - samplesdecoded<<1, sample_buffer, &buffer_playing); - } - playback->output->buffer_free(); - playback->output->close_audio(); - buffer_playing = FALSE; - g_free(buffer); - faacDecClose(decoder); - g_free(xmmstitle); - vfs_fclose(file); - seekPosition = -1; + if(bufferconsumed > 0){ + memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); + buffervalid -= bufferconsumed; + buffervalid += vfs_fread(&buffer[buffervalid], 1, + BUFFER_SIZE-buffervalid, file); + bufferconsumed = 0; + } + sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid); + if(finfo.error){ + config = faacDecGetCurrentConfiguration(decoder); + if(config->useOldADTSFormat != 1){ + faacDecClose(decoder); + decoder = faacDecOpen(); + config = faacDecGetCurrentConfiguration(decoder); + config->useOldADTSFormat = 1; + faacDecSetConfiguration(decoder, config); + finfo.bytesconsumed=0; + finfo.samples = 0; + faacDecInit(decoder, + buffer, + buffervalid, + &samplerate, + &channels); + }else{ + g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error)); + buffervalid = 0; + } + } + bufferconsumed += finfo.bytesconsumed; + samplesdecoded = finfo.samples; + if((samplesdecoded<=0) && !sample_buffer){ + g_print("AAC: error sample decoding\n"); + continue; + } + produce_audio(playback->output->written_time(), + FMT_S16_LE, channels, + samplesdecoded<<1, sample_buffer, &buffer_playing); + } + playback->output->buffer_free(); + playback->output->close_audio(); + buffer_playing = FALSE; + g_free(buffer); + faacDecClose(decoder); + g_free(xmmstitle); + vfs_fclose(file); + seekPosition = -1; - buffer_playing = FALSE; - g_static_mutex_unlock(&mutex); - g_thread_exit(NULL); + buffer_playing = FALSE; + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); } -static void *mp4Decode( void *args ) +static void *mp4_decode( void *args ) { - mp4ff_callback_t *mp4cb = g_malloc0(sizeof(mp4ff_callback_t)); - VFSFile *mp4fh; - mp4ff_t *mp4file; + mp4ff_callback_t *mp4cb = g_malloc0(sizeof(mp4ff_callback_t)); + VFSFile *mp4fh; + mp4ff_t *mp4file; - InputPlayback *playback = args; - char* url= (char*)playback->data; - char filename[255]; - memset( filename, '\0', 255 ); + InputPlayback *playback = args; + char *filename = playback->filename; -#if 0 - /* If we have a URL-style string, de-URLise it... */ - if ( !strncmp( url, "file://", 7 ) ) { - char *output= curl_unescape( url, 0 ); - char *tmp= output+7; - - strncpy( filename, tmp, 254 ); + mp4fh = vfs_fopen(filename, "rb"); + mp4cb->read = mp4_read_callback; + mp4cb->seek = mp4_seek_callback; + mp4cb->user_data = mp4fh; - curl_free( output ); - } - else { - strncpy( filename, url, 254 ); - } -#endif - - strncpy( filename, url, 254 ); + g_static_mutex_lock(&mutex); + seekPosition= -1; + buffer_playing= TRUE; + g_static_mutex_unlock(&mutex); - mp4fh = vfs_fopen(filename, "rb"); - mp4cb->read = mp4_read_callback; - mp4cb->seek = mp4_seek_callback; - mp4cb->user_data = mp4fh; + mp4file= mp4ff_open_read(mp4cb); + if( !mp4file ) { + mp4cfg.file_type = FILE_AAC; + vfs_fclose(mp4fh); + g_free(mp4cb); + } + else { + mp4cfg.file_type = FILE_MP4; + } - g_static_mutex_lock(&mutex); - seekPosition= -1; - buffer_playing= TRUE; - g_static_mutex_unlock(&mutex); + if ( mp4cfg.file_type == FILE_MP4 ) { + my_decode_mp4( playback, filename, mp4file ); - mp4file= mp4ff_open_read(mp4cb); - if( !mp4file ) { - mp4cfg.file_type = FILE_AAC; - vfs_fclose(mp4fh); - g_free(mp4cb); - } - else { - mp4cfg.file_type = FILE_MP4; - } - - if ( mp4cfg.file_type == FILE_MP4 ) { - my_decode_mp4( playback, filename, mp4file ); + g_free(args); + vfs_fclose(mp4fh); + g_static_mutex_lock(&mutex); + buffer_playing = FALSE; + g_static_mutex_unlock(&mutex); + g_thread_exit(NULL); + } + else { + my_decode_aac( playback, filename ); + } - g_free(args); - vfs_fclose(mp4fh); - g_static_mutex_lock(&mutex); - buffer_playing = FALSE; - g_static_mutex_unlock(&mutex); - g_thread_exit(NULL); - } - else { - my_decode_aac( playback, filename ); - } - - return NULL; + return NULL; }