Mercurial > audlegacy
annotate Plugins/Input/aac/src/libmp4.c @ 416:cb00a4b01302 trunk
[svn] Convert to produce_audio usage.
| author | chainsaw |
|---|---|
| date | Tue, 10 Jan 2006 16:50:39 -0800 |
| parents | 33823c38e10d |
| children | 3c4bcd9b8719 |
| rev | line source |
|---|---|
| 61 | 1 /* |
| 2 * MP4/AAC decoder for xmms | |
| 3 * | |
| 4 * This decoding source code is completly independent of the faad2 | |
| 5 * package. | |
| 6 * This package exist for people who don't want to install | |
| 7 * faad2 and mpeg4ip project files. | |
| 8 * | |
| 9 * OPTIONNAL need | |
| 10 * -------------- | |
| 11 * libid3 (3.8.x - www.id3.org) | |
| 12 */ | |
| 13 | |
| 339 | 14 #include <glib.h> |
|
387
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
15 #include <glib/gi18n.h> |
| 61 | 16 #include <gtk/gtk.h> |
| 339 | 17 #include <string.h> |
| 18 #include <stdlib.h> | |
| 61 | 19 #include "faad.h" |
| 20 #include "mp4.h" | |
|
387
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
21 #include "tagging.h" |
| 61 | 22 |
| 23 #include <audacious/plugin.h> | |
|
346
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
24 #include <audacious/output.h> |
| 61 | 25 #include <libaudacious/util.h> |
| 26 #include <libaudacious/titlestring.h> | |
| 27 | |
|
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
28 #define MP4_VERSION "ver.- 15 December 2004" |
|
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
29 #define LIBMP4V2_VERSION "1.2.0" |
| 61 | 30 #define MP4_ABOUT "Written by ciberfred" |
| 31 #define BUFFER_SIZE FAAD_MIN_STREAMSIZE*64 | |
| 32 | |
|
387
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
33 const char *audmp4_id3_genres[GENRE_MAX] = { |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
34 N_("Blues"), N_("Classic Rock"), N_("Country"), N_("Dance"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
35 N_("Disco"), N_("Funk"), N_("Grunge"), N_("Hip-Hop"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
36 N_("Jazz"), N_("Metal"), N_("New Age"), N_("Oldies"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
37 N_("Other"), N_("Pop"), N_("R&B"), N_("Rap"), N_("Reggae"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
38 N_("Rock"), N_("Techno"), N_("Industrial"), N_("Alternative"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
39 N_("Ska"), N_("Death Metal"), N_("Pranks"), N_("Soundtrack"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
40 N_("Euro-Techno"), N_("Ambient"), N_("Trip-Hop"), N_("Vocal"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
41 N_("Jazz+Funk"), N_("Fusion"), N_("Trance"), N_("Classical"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
42 N_("Instrumental"), N_("Acid"), N_("House"), N_("Game"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
43 N_("Sound Clip"), N_("Gospel"), N_("Noise"), N_("AlternRock"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
44 N_("Bass"), N_("Soul"), N_("Punk"), N_("Space"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
45 N_("Meditative"), N_("Instrumental Pop"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
46 N_("Instrumental Rock"), N_("Ethnic"), N_("Gothic"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
47 N_("Darkwave"), N_("Techno-Industrial"), N_("Electronic"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
48 N_("Pop-Folk"), N_("Eurodance"), N_("Dream"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
49 N_("Southern Rock"), N_("Comedy"), N_("Cult"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
50 N_("Gangsta Rap"), N_("Top 40"), N_("Christian Rap"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
51 N_("Pop/Funk"), N_("Jungle"), N_("Native American"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
52 N_("Cabaret"), N_("New Wave"), N_("Psychedelic"), N_("Rave"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
53 N_("Showtunes"), N_("Trailer"), N_("Lo-Fi"), N_("Tribal"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
54 N_("Acid Punk"), N_("Acid Jazz"), N_("Polka"), N_("Retro"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
55 N_("Musical"), N_("Rock & Roll"), N_("Hard Rock"), N_("Folk"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
56 N_("Folk/Rock"), N_("National Folk"), N_("Swing"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
57 N_("Fast-Fusion"), N_("Bebob"), N_("Latin"), N_("Revival"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
58 N_("Celtic"), N_("Bluegrass"), N_("Avantgarde"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
59 N_("Gothic Rock"), N_("Progressive Rock"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
60 N_("Psychedelic Rock"), N_("Symphonic Rock"), N_("Slow Rock"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
61 N_("Big Band"), N_("Chorus"), N_("Easy Listening"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
62 N_("Acoustic"), N_("Humour"), N_("Speech"), N_("Chanson"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
63 N_("Opera"), N_("Chamber Music"), N_("Sonata"), N_("Symphony"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
64 N_("Booty Bass"), N_("Primus"), N_("Porn Groove"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
65 N_("Satire"), N_("Slow Jam"), N_("Club"), N_("Tango"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
66 N_("Samba"), N_("Folklore"), N_("Ballad"), N_("Power Ballad"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
67 N_("Rhythmic Soul"), N_("Freestyle"), N_("Duet"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
68 N_("Punk Rock"), N_("Drum Solo"), N_("A Cappella"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
69 N_("Euro-House"), N_("Dance Hall"), N_("Goa"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
70 N_("Drum & Bass"), N_("Club-House"), N_("Hardcore"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
71 N_("Terror"), N_("Indie"), N_("BritPop"), N_("Negerpunk"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
72 N_("Polsk Punk"), N_("Beat"), N_("Christian Gangsta Rap"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
73 N_("Heavy Metal"), N_("Black Metal"), N_("Crossover"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
74 N_("Contemporary Christian"), N_("Christian Rock"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
75 N_("Merengue"), N_("Salsa"), N_("Thrash Metal"), |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
76 N_("Anime"), N_("JPop"), N_("Synthpop") |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
77 }; |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
78 |
|
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
79 |
| 61 | 80 static void mp4_init(void); |
| 81 static void mp4_about(void); | |
| 82 static void mp4_play(char *); | |
| 83 static void mp4_stop(void); | |
| 84 static void mp4_pause(short); | |
| 85 static void mp4_seek(int); | |
| 86 static int mp4_getTime(void); | |
| 87 static void mp4_cleanup(void); | |
| 88 static int mp4_isFile(char *); | |
| 339 | 89 static void mp4_getSongTitle(char *filename, char **, int *); |
| 61 | 90 static void* mp4Decode(void *); |
| 91 | |
|
346
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
92 void audmp4_file_info_box(gchar *); |
|
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
93 |
| 61 | 94 InputPlugin mp4_ip = |
| 95 { | |
| 96 0, // handle | |
| 97 0, // filename | |
|
344
a98a7f2dfc84
[svn] Display the MP4/AAC+ bitrate, instead of "VBR".
nenolod
parents:
342
diff
changeset
|
98 "MP4 Audio Plugin", |
| 61 | 99 mp4_init, |
| 100 mp4_about, | |
| 101 0, // configuration | |
| 102 mp4_isFile, | |
| 103 0, //scandir | |
| 104 mp4_play, | |
| 105 mp4_stop, | |
| 106 mp4_pause, | |
| 107 mp4_seek, | |
| 108 0, // set equalizer | |
| 109 mp4_getTime, | |
| 110 0, // get volume | |
| 111 0, | |
| 112 mp4_cleanup, | |
| 113 0, // obsolete | |
| 114 0, // send visualisation data | |
| 115 0, // set player window info | |
| 116 0, // set song title text | |
| 339 | 117 mp4_getSongTitle, // get song title text |
|
342
320f0205ad45
[svn] Initial fileinfo box, loosely based around the mpg123-clone one.
nenolod
parents:
340
diff
changeset
|
118 audmp4_file_info_box, // info box |
| 61 | 119 0, // to output plugin |
| 120 }; | |
| 121 | |
| 122 typedef struct _mp4cfg{ | |
| 123 gshort file_type; | |
| 124 #define FILE_UNKNOW 0 | |
| 125 #define FILE_MP4 1 | |
| 126 #define FILE_AAC 2 | |
| 127 } Mp4Config; | |
| 128 | |
| 129 static Mp4Config mp4cfg; | |
| 130 static gboolean bPlaying = FALSE; | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
131 static GThread *decodeThread; |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
132 GStaticMutex mutex = G_STATIC_MUTEX_INIT; |
| 61 | 133 static int seekPosition = -1; |
| 134 | |
|
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
135 void getMP4info(char*); |
|
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
136 int getAACTrack(MP4FileHandle); |
|
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
137 |
| 339 | 138 /* |
| 139 * Function extname (filename) | |
| 140 * | |
| 141 * Return pointer within filename to its extenstion, or NULL if | |
| 142 * filename has no extension. | |
| 143 * | |
| 144 */ | |
| 145 static gchar * | |
| 146 extname(const char *filename) | |
| 147 { | |
| 148 gchar *ext = strrchr(filename, '.'); | |
| 149 | |
| 150 if (ext != NULL) | |
| 151 ++ext; | |
| 152 | |
| 153 return ext; | |
| 154 } | |
| 61 | 155 |
| 156 InputPlugin *get_iplugin_info(void) | |
| 157 { | |
| 158 return(&mp4_ip); | |
| 159 } | |
| 160 | |
| 161 static void mp4_init(void) | |
| 162 { | |
| 163 mp4cfg.file_type = FILE_UNKNOW; | |
| 164 seekPosition = -1; | |
| 165 return; | |
| 166 } | |
| 167 | |
| 168 static void mp4_play(char *filename) | |
| 169 { | |
| 170 bPlaying = TRUE; | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
171 decodeThread = g_thread_create((GThreadFunc)mp4Decode, g_strdup(filename), TRUE, NULL); |
| 61 | 172 return; |
| 173 } | |
| 174 | |
| 175 static void mp4_stop(void) | |
| 176 { | |
| 177 if(bPlaying){ | |
| 178 bPlaying = FALSE; | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
179 g_thread_join(decodeThread); |
| 61 | 180 mp4_ip.output->close_audio(); |
| 181 } | |
| 182 } | |
| 183 | |
| 184 static int mp4_isFile(char *filename) | |
| 185 { | |
|
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
186 if(filename){ |
|
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
187 gchar* extention; |
| 61 | 188 |
|
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
189 extention = strrchr(filename, '.'); |
|
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
190 if (extention &&( |
|
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
191 !strcasecmp(extention, ".mp4") || // official extention |
|
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
192 !strcasecmp(extention, ".m4a") || // Apple mp4 extention |
|
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
193 !strcasecmp(extention, ".aac") // old MPEG2/4-AAC extention |
| 61 | 194 )){ |
| 195 return (1); | |
| 196 } | |
| 197 } | |
| 198 return(0); | |
| 199 } | |
| 200 | |
| 201 static void mp4_about(void) | |
| 202 { | |
| 203 static GtkWidget *aboutbox; | |
| 204 | |
| 205 if(aboutbox!=NULL) | |
| 206 return; | |
| 207 aboutbox = xmms_show_message("About MP4 AAC player plugin", | |
| 208 "libfaad2-" FAAD2_VERSION "\n" | |
| 209 "libmp4v2-" LIBMP4V2_VERSION "\n" | |
| 210 "plugin version: " MP4_VERSION "\n" | |
| 211 MP4_ABOUT, | |
| 212 "Ok", FALSE, NULL, NULL); | |
| 213 gtk_signal_connect(GTK_OBJECT(aboutbox), "destroy", | |
| 214 GTK_SIGNAL_FUNC(gtk_widget_destroyed), | |
| 215 &aboutbox); | |
| 216 } | |
| 217 | |
| 218 static void mp4_pause(short flag) | |
| 219 { | |
| 220 mp4_ip.output->pause(flag); | |
| 221 } | |
| 222 | |
| 223 static void mp4_seek(int time) | |
| 224 { | |
| 225 seekPosition = time; | |
| 226 while(bPlaying && seekPosition!=-1) | |
| 227 xmms_usleep(10000); | |
| 228 } | |
| 229 | |
| 230 static int mp4_getTime(void) | |
| 231 { | |
| 232 if(!bPlaying) | |
| 233 return (-1); | |
| 234 else | |
| 235 return (mp4_ip.output->output_time()); | |
| 236 } | |
| 237 | |
| 238 static void mp4_cleanup(void) | |
| 239 { | |
| 240 } | |
| 241 | |
|
387
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
242 #if 0 |
| 61 | 243 static void mp4_getSongInfo(char *filename) |
| 244 { | |
| 245 if(mp4cfg.file_type == FILE_MP4) | |
| 246 getMP4info(filename); | |
| 247 else if(mp4cfg.file_type == FILE_AAC) | |
| 248 ; | |
| 249 } | |
|
387
7f0e78f42032
[svn] Disable adplug if the includes are missing (or in a very lame place). Stop blowing holes in my ship.
chainsaw
parents:
346
diff
changeset
|
250 #endif |
| 61 | 251 |
| 339 | 252 static gchar *mp4_get_song_title(char *filename) |
| 253 { | |
| 254 MP4FileHandle mp4file; | |
| 255 gchar *title = NULL; | |
| 256 | |
| 257 if (!(mp4file = MP4Read(filename, 0))) { | |
| 258 MP4Close(mp4file); | |
| 259 } else { | |
| 260 TitleInput *input; | |
| 261 gchar *tmpval; | |
| 262 | |
| 263 input = bmp_title_input_new(); | |
| 264 | |
| 265 MP4GetMetadataName(mp4file, &input->track_name); | |
| 266 MP4GetMetadataAlbum(mp4file, &input->album_name); | |
| 267 MP4GetMetadataArtist(mp4file, &input->performer); | |
| 268 MP4GetMetadataYear(mp4file, &tmpval); | |
| 269 MP4GetMetadataGenre(mp4file, &input->genre); | |
| 270 | |
| 340 | 271 if (tmpval) |
| 272 input->year = atoi(tmpval); | |
| 339 | 273 |
| 274 input->file_name = g_path_get_basename(filename); | |
| 275 input->file_path = g_path_get_dirname(filename); | |
| 276 input->file_ext = extname(filename); | |
| 277 | |
| 278 title = xmms_get_titlestring(xmms_get_gentitle_format(), input); | |
| 279 | |
| 280 free (input->file_name); | |
| 281 free (input->file_path); | |
| 282 free (input); | |
| 283 } | |
| 284 | |
| 285 if (!title) | |
| 286 { | |
| 287 title = g_path_get_basename(filename); | |
| 288 if (extname(title)) | |
| 289 *(extname(title) - 1) = '\0'; | |
| 290 } | |
| 291 | |
| 292 return title; | |
| 293 } | |
| 294 | |
| 295 static void mp4_getSongTitle(char *filename, char **title_real, int *len_real) | |
| 296 { | |
| 297 (*title_real) = mp4_get_song_title(filename); | |
| 298 (*len_real) = -1; | |
| 299 } | |
| 300 | |
| 61 | 301 static void *mp4Decode(void *args) |
| 302 { | |
| 303 MP4FileHandle mp4file; | |
| 304 | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
305 g_static_mutex_lock(&mutex); |
| 61 | 306 seekPosition = -1; |
| 307 bPlaying = TRUE; | |
| 308 if(!(mp4file = MP4Read(args, 0))){ | |
| 309 mp4cfg.file_type = FILE_AAC; | |
| 310 MP4Close(mp4file); | |
| 311 }else{ | |
| 312 mp4cfg.file_type = FILE_MP4; | |
| 313 } | |
| 314 | |
| 315 if(mp4cfg.file_type == FILE_MP4){ | |
| 316 // We are reading a MP4 file | |
| 317 gint mp4track; | |
| 318 | |
| 319 if((mp4track = getAACTrack(mp4file)) < 0){ | |
| 320 //TODO: check here for others Audio format..... | |
| 321 g_print("Unsupported Audio track type\n"); | |
| 322 g_free(args); | |
| 323 MP4Close(mp4file); | |
| 324 bPlaying = FALSE; | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
325 g_static_mutex_unlock(&mutex); |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
326 g_thread_exit(NULL); |
|
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
327 return(NULL); |
| 61 | 328 }else{ |
| 329 faacDecHandle decoder; | |
| 330 unsigned char *buffer = NULL; | |
| 331 guint bufferSize = 0; | |
| 332 gulong samplerate; | |
| 333 guchar channels; | |
|
344
a98a7f2dfc84
[svn] Display the MP4/AAC+ bitrate, instead of "VBR".
nenolod
parents:
342
diff
changeset
|
334 guint avgBitrate; |
| 61 | 335 MP4Duration duration; |
| 336 gulong msDuration; | |
| 337 MP4SampleId numSamples; | |
| 338 MP4SampleId sampleID = 1; | |
| 339 | 339 gchar *title; |
| 61 | 340 |
| 341 decoder = faacDecOpen(); | |
| 342 MP4GetTrackESConfiguration(mp4file, mp4track, &buffer, &bufferSize); | |
|
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
343 if(!buffer) |
|
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
344 goto out; |
|
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
345 if(faacDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0) |
|
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
346 goto out; |
| 61 | 347 g_free(buffer); |
| 348 if(channels == 0){ | |
| 349 g_print("Number of Channels not supported\n"); | |
|
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
350 goto out; |
| 61 | 351 } |
| 352 duration = MP4GetTrackDuration(mp4file, mp4track); | |
| 353 msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, duration, | |
| 354 MP4_MSECS_TIME_SCALE); | |
| 355 numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track); | |
|
345
9b19994a715c
[svn] ditto for samplerate... we should have full plugin compatibility now
nenolod
parents:
344
diff
changeset
|
356 samplerate = MP4GetTrackTimeScale(mp4file, mp4track); |
| 61 | 357 mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels); |
| 358 mp4_ip.output->flush(0); | |
| 339 | 359 title = mp4_get_song_title(args); |
|
344
a98a7f2dfc84
[svn] Display the MP4/AAC+ bitrate, instead of "VBR".
nenolod
parents:
342
diff
changeset
|
360 avgBitrate = MP4GetTrackBitRate(mp4file, mp4track); |
|
345
9b19994a715c
[svn] ditto for samplerate... we should have full plugin compatibility now
nenolod
parents:
344
diff
changeset
|
361 mp4_ip.set_info(title, msDuration, avgBitrate, samplerate, channels); |
| 61 | 362 |
| 363 while(bPlaying){ | |
| 364 void* sampleBuffer; | |
| 365 faacDecFrameInfo frameInfo; | |
| 366 gint rc; | |
| 367 | |
| 368 if(seekPosition!=-1){ | |
| 369 duration = MP4ConvertToTrackDuration(mp4file, | |
| 370 mp4track, | |
| 371 seekPosition*1000, | |
| 372 MP4_MSECS_TIME_SCALE); | |
| 373 sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0); | |
| 374 mp4_ip.output->flush(seekPosition*1000); | |
| 375 seekPosition = -1; | |
| 376 } | |
| 377 buffer=NULL; | |
| 378 bufferSize=0; | |
| 379 if(sampleID > numSamples){ | |
|
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
380 goto out; |
| 61 | 381 } |
| 382 rc = MP4ReadSample(mp4file, mp4track, sampleID++, &buffer, &bufferSize, | |
| 383 NULL, NULL, NULL, NULL); | |
| 384 if((rc==0) || (buffer== NULL)){ | |
| 385 g_print("MP4: read error\n"); | |
| 386 sampleBuffer = NULL; | |
| 387 sampleID=0; | |
| 388 mp4_ip.output->buffer_free(); | |
|
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
389 goto out; |
| 61 | 390 }else{ |
| 391 sampleBuffer = faacDecDecode(decoder, &frameInfo, buffer, bufferSize); | |
| 392 if(frameInfo.error > 0){ | |
| 393 g_print("MP4: %s\n", | |
| 394 faacDecGetErrorMessage(frameInfo.error)); | |
|
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
395 goto out; |
| 61 | 396 } |
| 397 if(buffer){ | |
| 398 g_free(buffer); buffer=NULL; bufferSize=0; | |
| 399 } | |
| 400 while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1) | |
| 401 xmms_usleep(30000); | |
| 402 } | |
|
346
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
403 produce_audio(mp4_ip.output->written_time(), |
|
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
404 FMT_S16_NE, |
|
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
405 channels, |
|
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
406 frameInfo.samples<<1, |
|
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
407 sampleBuffer, &bPlaying); |
| 61 | 408 } |
| 409 while(bPlaying && mp4_ip.output->buffer_free()){ | |
| 410 xmms_usleep(10000); | |
| 411 } | |
|
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
412 out: |
| 61 | 413 mp4_ip.output->close_audio(); |
| 414 g_free(args); | |
| 415 faacDecClose(decoder); | |
| 416 MP4Close(mp4file); | |
| 417 bPlaying = FALSE; | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
418 g_static_mutex_unlock(&mutex); |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
419 g_thread_exit(NULL); |
|
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
420 return(NULL); |
| 61 | 421 } |
| 422 } else{ | |
| 423 // WE ARE READING AN AAC FILE | |
| 424 FILE *file = NULL; | |
| 425 faacDecHandle decoder = 0; | |
| 426 guchar *buffer = 0; | |
| 427 gulong bufferconsumed = 0; | |
| 428 gulong samplerate = 0; | |
| 429 guchar channels; | |
| 430 gulong buffervalid = 0; | |
| 431 TitleInput* input; | |
| 432 gchar *temp = g_strdup(args); | |
| 433 gchar *ext = strrchr(temp, '.'); | |
| 434 gchar *xmmstitle = NULL; | |
| 435 faacDecConfigurationPtr config; | |
| 436 | |
| 437 if((file = fopen(args, "rb")) == 0){ | |
|
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
438 g_print("AAC: can't find file %s\n", (char*)args); |
| 61 | 439 bPlaying = FALSE; |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
440 g_static_mutex_unlock(&mutex); |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
441 g_thread_exit(NULL); |
| 61 | 442 } |
| 443 if((decoder = faacDecOpen()) == NULL){ | |
| 444 g_print("AAC: Open Decoder Error\n"); | |
| 445 fclose(file); | |
| 446 bPlaying = FALSE; | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
447 g_static_mutex_unlock(&mutex); |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
448 g_thread_exit(NULL); |
| 61 | 449 } |
| 450 config = faacDecGetCurrentConfiguration(decoder); | |
| 451 config->useOldADTSFormat = 0; | |
| 452 faacDecSetConfiguration(decoder, config); | |
| 453 if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ | |
| 454 g_print("AAC: error g_malloc\n"); | |
| 455 fclose(file); | |
| 456 bPlaying = FALSE; | |
| 457 faacDecClose(decoder); | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
458 g_static_mutex_unlock(&mutex); |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
459 g_thread_exit(NULL); |
| 61 | 460 } |
| 461 if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){ | |
| 462 g_print("AAC: Error reading file\n"); | |
| 463 g_free(buffer); | |
| 464 fclose(file); | |
| 465 bPlaying = FALSE; | |
| 466 faacDecClose(decoder); | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
467 g_static_mutex_unlock(&mutex); |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
468 g_thread_exit(NULL); |
| 61 | 469 } |
| 470 XMMS_NEW_TITLEINPUT(input); | |
|
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
471 input->file_name = (char*)g_basename(temp); |
| 61 | 472 input->file_ext = ext ? ext+1 : NULL; |
| 473 input->file_path = temp; | |
|
407
33823c38e10d
[svn] Use glib function for glib types and care about pointer signedness.
chainsaw
parents:
387
diff
changeset
|
474 if(!g_ascii_strncasecmp((gchar*)buffer, "ID3", 3)){ |
| 61 | 475 gint size = 0; |
| 476 | |
| 477 fseek(file, 0, SEEK_SET); | |
| 478 size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; | |
| 479 size+=10; | |
| 480 fread(buffer, 1, size, file); | |
| 481 buffervalid = fread(buffer, 1, BUFFER_SIZE, file); | |
| 482 } | |
| 483 xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); | |
| 484 if(xmmstitle == NULL) | |
|
320
d8889f819081
[svn] Dereferencing type-punned pointer will break strict-aliasing rules squashed by Mark Loeser <halcy0n@gentoo.org>.
chainsaw
parents:
319
diff
changeset
|
485 xmmstitle = g_path_get_basename(input->file_name); |
| 61 | 486 if(temp) g_free(temp); |
| 487 if(input->performer) g_free(input->performer); | |
| 488 if(input->album_name) g_free(input->album_name); | |
| 489 if(input->track_name) g_free(input->track_name); | |
| 490 if(input->genre) g_free(input->genre); | |
| 491 g_free(input); | |
| 492 bufferconsumed = faacDecInit(decoder, | |
| 493 buffer, | |
| 494 buffervalid, | |
| 495 &samplerate, | |
| 496 &channels); | |
| 497 if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ | |
| 498 g_print("AAC: Output Error\n"); | |
| 499 g_free(buffer); buffer=0; | |
| 500 faacDecClose(decoder); | |
| 501 fclose(file); | |
| 502 mp4_ip.output->close_audio(); | |
| 503 /* | |
| 504 if(positionTable){ | |
| 505 g_free(positionTable); positionTable=0; | |
| 506 } | |
| 507 */ | |
| 508 g_free(xmmstitle); | |
| 509 bPlaying = FALSE; | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
510 g_static_mutex_unlock(&mutex); |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
511 g_thread_exit(NULL); |
| 61 | 512 } |
| 513 //if(bSeek){ | |
| 514 //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels); | |
| 515 //}else{ | |
| 516 mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); | |
| 517 //} | |
| 518 mp4_ip.output->flush(0); | |
| 519 | |
| 520 while(bPlaying && buffervalid > 0){ | |
| 521 faacDecFrameInfo finfo; | |
| 522 unsigned long samplesdecoded; | |
| 523 char* sample_buffer = NULL; | |
| 524 /* | |
| 525 if(bSeek && seekPosition!=-1){ | |
| 526 fseek(file, positionTable[seekPosition], SEEK_SET); | |
| 527 bufferconsumed=0; | |
| 528 buffervalid = fread(buffer, 1, BUFFER_SIZE, file); | |
| 529 aac_ip.output->flush(seekPosition*1000); | |
| 530 seekPosition=-1; | |
| 531 } | |
| 532 */ | |
| 533 if(bufferconsumed > 0){ | |
| 534 memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); | |
| 535 buffervalid -= bufferconsumed; | |
| 536 buffervalid += fread(&buffer[buffervalid], 1, | |
| 537 BUFFER_SIZE-buffervalid, file); | |
| 538 bufferconsumed = 0; | |
| 539 } | |
| 540 sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid); | |
| 541 if(finfo.error){ | |
| 542 config = faacDecGetCurrentConfiguration(decoder); | |
| 543 if(config->useOldADTSFormat != 1){ | |
| 544 faacDecClose(decoder); | |
| 545 decoder = faacDecOpen(); | |
| 546 config = faacDecGetCurrentConfiguration(decoder); | |
| 547 config->useOldADTSFormat = 1; | |
| 548 faacDecSetConfiguration(decoder, config); | |
| 549 finfo.bytesconsumed=0; | |
| 550 finfo.samples = 0; | |
| 551 faacDecInit(decoder, | |
| 552 buffer, | |
| 553 buffervalid, | |
| 554 &samplerate, | |
| 555 &channels); | |
| 556 }else{ | |
| 557 g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error)); | |
| 558 buffervalid = 0; | |
| 559 } | |
| 560 } | |
| 561 bufferconsumed += finfo.bytesconsumed; | |
| 562 samplesdecoded = finfo.samples; | |
| 563 if((samplesdecoded<=0) && !sample_buffer){ | |
| 564 g_print("AAC: error sample decoding\n"); | |
| 565 continue; | |
| 566 } | |
| 567 while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){ | |
| 568 xmms_usleep(10000); | |
| 569 } | |
| 570 mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), | |
| 571 FMT_S16_LE, channels, | |
| 572 samplesdecoded<<1, sample_buffer); | |
| 573 mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1); | |
| 574 } | |
| 575 while(bPlaying && mp4_ip.output->buffer_playing()){ | |
| 576 xmms_usleep(10000); | |
| 577 } | |
| 578 mp4_ip.output->buffer_free(); | |
| 579 mp4_ip.output->close_audio(); | |
| 580 bPlaying = FALSE; | |
| 581 g_free(buffer); | |
| 582 faacDecClose(decoder); | |
| 583 g_free(xmmstitle); | |
| 584 fclose(file); | |
| 585 seekPosition = -1; | |
| 586 /* | |
| 587 if(positionTable){ | |
| 588 g_free(positionTable); positionTable=0; | |
| 589 } | |
| 590 */ | |
| 591 bPlaying = FALSE; | |
|
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
592 g_static_mutex_unlock(&mutex); |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
593 g_thread_exit(NULL); |
|
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
594 return(NULL); |
| 61 | 595 } |
| 596 } |
