Mercurial > audlegacy
annotate Plugins/Input/aac/src/libmp4.c @ 832:d2db0feae0ca trunk
[svn] Fix logic error that caused us to lock on to wav.
author | chainsaw |
---|---|
date | Mon, 13 Mar 2006 14:18:03 -0800 |
parents | f51680f2dab0 |
children | 3b2b0d68960c |
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 { | |
831
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
186 MP4FileHandle mp4file2; |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
187 gint mp4track; |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
188 |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
189 if(!filename) |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
190 return 0; |
61 | 191 |
831
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
192 if((mp4file2 = MP4Read(filename, 0))){ |
832
d2db0feae0ca
[svn] Fix logic error that caused us to lock on to wav.
chainsaw
parents:
831
diff
changeset
|
193 if((mp4track = getAACTrack(mp4file2)) > 0){ |
831
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
194 MP4Close(mp4file2); // This is a valid MP4 file, good to go |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
195 return 1; |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
196 } else { |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
197 MP4Close(mp4file2); // Corrupted MP4 file, will not try to play |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
198 return 0; |
61 | 199 } |
831
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
200 } else { // Not MP4, could be AAC, check extension |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
201 gchar* extension; |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
202 extension = strrchr(filename, '.'); |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
203 if (extension &&( |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
204 !strcasecmp(extension, ".mp4") || // official extension |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
205 !strcasecmp(extension, ".m4a") || // Apple mp4 extension |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
206 !strcasecmp(extension, ".aac") // old MPEG2/4-AAC extension |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
207 )) |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
208 return 1; |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
209 else |
f51680f2dab0
[svn] Be smarter about spotting MP4 files, only fall back on extension for AAC.
chainsaw
parents:
793
diff
changeset
|
210 return 0; |
61 | 211 } |
212 } | |
213 | |
214 static void mp4_about(void) | |
215 { | |
216 static GtkWidget *aboutbox; | |
217 | |
218 if(aboutbox!=NULL) | |
219 return; | |
220 aboutbox = xmms_show_message("About MP4 AAC player plugin", | |
221 "libfaad2-" FAAD2_VERSION "\n" | |
222 "libmp4v2-" LIBMP4V2_VERSION "\n" | |
223 "plugin version: " MP4_VERSION "\n" | |
224 MP4_ABOUT, | |
225 "Ok", FALSE, NULL, NULL); | |
226 gtk_signal_connect(GTK_OBJECT(aboutbox), "destroy", | |
227 GTK_SIGNAL_FUNC(gtk_widget_destroyed), | |
228 &aboutbox); | |
229 } | |
230 | |
231 static void mp4_pause(short flag) | |
232 { | |
233 mp4_ip.output->pause(flag); | |
234 } | |
235 | |
236 static void mp4_seek(int time) | |
237 { | |
238 seekPosition = time; | |
239 while(bPlaying && seekPosition!=-1) | |
240 xmms_usleep(10000); | |
241 } | |
242 | |
243 static int mp4_getTime(void) | |
244 { | |
245 if(!bPlaying) | |
246 return (-1); | |
247 else | |
248 return (mp4_ip.output->output_time()); | |
249 } | |
250 | |
251 static void mp4_cleanup(void) | |
252 { | |
253 } | |
254 | |
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
|
255 #if 0 |
61 | 256 static void mp4_getSongInfo(char *filename) |
257 { | |
258 if(mp4cfg.file_type == FILE_MP4) | |
259 getMP4info(filename); | |
260 else if(mp4cfg.file_type == FILE_AAC) | |
261 ; | |
262 } | |
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
|
263 #endif |
61 | 264 |
339 | 265 static gchar *mp4_get_song_title(char *filename) |
266 { | |
267 MP4FileHandle mp4file; | |
268 gchar *title = NULL; | |
269 | |
270 if (!(mp4file = MP4Read(filename, 0))) { | |
271 MP4Close(mp4file); | |
272 } else { | |
273 TitleInput *input; | |
274 gchar *tmpval; | |
275 | |
276 input = bmp_title_input_new(); | |
277 | |
278 MP4GetMetadataName(mp4file, &input->track_name); | |
279 MP4GetMetadataAlbum(mp4file, &input->album_name); | |
280 MP4GetMetadataArtist(mp4file, &input->performer); | |
281 MP4GetMetadataYear(mp4file, &tmpval); | |
282 MP4GetMetadataGenre(mp4file, &input->genre); | |
283 | |
340 | 284 if (tmpval) |
793 | 285 { |
340 | 286 input->year = atoi(tmpval); |
793 | 287 free(tmpval); |
288 } | |
339 | 289 |
290 input->file_name = g_path_get_basename(filename); | |
291 input->file_path = g_path_get_dirname(filename); | |
292 input->file_ext = extname(filename); | |
293 | |
294 title = xmms_get_titlestring(xmms_get_gentitle_format(), input); | |
295 | |
793 | 296 free (input->track_name); |
297 free (input->album_name); | |
298 free (input->performer); | |
299 free (input->genre); | |
339 | 300 free (input->file_name); |
301 free (input->file_path); | |
302 free (input); | |
303 } | |
304 | |
305 if (!title) | |
306 { | |
307 title = g_path_get_basename(filename); | |
308 if (extname(title)) | |
309 *(extname(title) - 1) = '\0'; | |
310 } | |
311 | |
312 return title; | |
313 } | |
314 | |
315 static void mp4_getSongTitle(char *filename, char **title_real, int *len_real) | |
316 { | |
317 (*title_real) = mp4_get_song_title(filename); | |
318 (*len_real) = -1; | |
319 } | |
320 | |
61 | 321 static void *mp4Decode(void *args) |
322 { | |
323 MP4FileHandle mp4file; | |
324 | |
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_lock(&mutex); |
61 | 326 seekPosition = -1; |
327 bPlaying = TRUE; | |
328 if(!(mp4file = MP4Read(args, 0))){ | |
329 mp4cfg.file_type = FILE_AAC; | |
330 MP4Close(mp4file); | |
331 }else{ | |
332 mp4cfg.file_type = FILE_MP4; | |
333 } | |
334 | |
335 if(mp4cfg.file_type == FILE_MP4){ | |
336 // We are reading a MP4 file | |
337 gint mp4track; | |
338 | |
339 if((mp4track = getAACTrack(mp4file)) < 0){ | |
340 //TODO: check here for others Audio format..... | |
341 g_print("Unsupported Audio track type\n"); | |
342 g_free(args); | |
343 MP4Close(mp4file); | |
344 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
345 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
|
346 g_thread_exit(NULL); |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
347 return(NULL); |
61 | 348 }else{ |
349 faacDecHandle decoder; | |
350 unsigned char *buffer = NULL; | |
351 guint bufferSize = 0; | |
352 gulong samplerate; | |
353 guchar channels; | |
344
a98a7f2dfc84
[svn] Display the MP4/AAC+ bitrate, instead of "VBR".
nenolod
parents:
342
diff
changeset
|
354 guint avgBitrate; |
61 | 355 MP4Duration duration; |
356 gulong msDuration; | |
357 MP4SampleId numSamples; | |
358 MP4SampleId sampleID = 1; | |
339 | 359 gchar *title; |
61 | 360 |
361 decoder = faacDecOpen(); | |
362 MP4GetTrackESConfiguration(mp4file, mp4track, &buffer, &bufferSize); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
363 if(!buffer) |
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
364 goto out; |
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
365 if(faacDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0) |
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
366 goto out; |
61 | 367 g_free(buffer); |
368 if(channels == 0){ | |
369 g_print("Number of Channels not supported\n"); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
370 goto out; |
61 | 371 } |
372 duration = MP4GetTrackDuration(mp4file, mp4track); | |
373 msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, duration, | |
374 MP4_MSECS_TIME_SCALE); | |
375 numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track); | |
345
9b19994a715c
[svn] ditto for samplerate... we should have full plugin compatibility now
nenolod
parents:
344
diff
changeset
|
376 samplerate = MP4GetTrackTimeScale(mp4file, mp4track); |
61 | 377 mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels); |
378 mp4_ip.output->flush(0); | |
339 | 379 title = mp4_get_song_title(args); |
344
a98a7f2dfc84
[svn] Display the MP4/AAC+ bitrate, instead of "VBR".
nenolod
parents:
342
diff
changeset
|
380 avgBitrate = MP4GetTrackBitRate(mp4file, mp4track); |
345
9b19994a715c
[svn] ditto for samplerate... we should have full plugin compatibility now
nenolod
parents:
344
diff
changeset
|
381 mp4_ip.set_info(title, msDuration, avgBitrate, samplerate, channels); |
61 | 382 |
383 while(bPlaying){ | |
384 void* sampleBuffer; | |
385 faacDecFrameInfo frameInfo; | |
386 gint rc; | |
387 | |
388 if(seekPosition!=-1){ | |
389 duration = MP4ConvertToTrackDuration(mp4file, | |
390 mp4track, | |
391 seekPosition*1000, | |
392 MP4_MSECS_TIME_SCALE); | |
393 sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0); | |
394 mp4_ip.output->flush(seekPosition*1000); | |
395 seekPosition = -1; | |
396 } | |
397 buffer=NULL; | |
398 bufferSize=0; | |
399 if(sampleID > numSamples){ | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
400 goto out; |
61 | 401 } |
402 rc = MP4ReadSample(mp4file, mp4track, sampleID++, &buffer, &bufferSize, | |
403 NULL, NULL, NULL, NULL); | |
404 if((rc==0) || (buffer== NULL)){ | |
405 g_print("MP4: read error\n"); | |
406 sampleBuffer = NULL; | |
407 sampleID=0; | |
408 mp4_ip.output->buffer_free(); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
409 goto out; |
61 | 410 }else{ |
411 sampleBuffer = faacDecDecode(decoder, &frameInfo, buffer, bufferSize); | |
412 if(frameInfo.error > 0){ | |
413 g_print("MP4: %s\n", | |
414 faacDecGetErrorMessage(frameInfo.error)); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
415 goto out; |
61 | 416 } |
417 if(buffer){ | |
418 g_free(buffer); buffer=NULL; bufferSize=0; | |
419 } | |
420 while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1) | |
421 xmms_usleep(30000); | |
422 } | |
346
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
423 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
|
424 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
|
425 channels, |
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
426 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
|
427 sampleBuffer, &bPlaying); |
61 | 428 } |
429 while(bPlaying && mp4_ip.output->buffer_free()){ | |
430 xmms_usleep(10000); | |
431 } | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
432 out: |
61 | 433 mp4_ip.output->close_audio(); |
434 g_free(args); | |
435 faacDecClose(decoder); | |
436 MP4Close(mp4file); | |
437 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
438 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
|
439 g_thread_exit(NULL); |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
440 return(NULL); |
61 | 441 } |
442 } else{ | |
443 // WE ARE READING AN AAC FILE | |
444 FILE *file = NULL; | |
445 faacDecHandle decoder = 0; | |
446 guchar *buffer = 0; | |
447 gulong bufferconsumed = 0; | |
448 gulong samplerate = 0; | |
449 guchar channels; | |
450 gulong buffervalid = 0; | |
451 TitleInput* input; | |
452 gchar *temp = g_strdup(args); | |
453 gchar *ext = strrchr(temp, '.'); | |
454 gchar *xmmstitle = NULL; | |
455 faacDecConfigurationPtr config; | |
456 | |
457 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
|
458 g_print("AAC: can't find file %s\n", (char*)args); |
61 | 459 bPlaying = FALSE; |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
460 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
|
461 g_thread_exit(NULL); |
61 | 462 } |
463 if((decoder = faacDecOpen()) == NULL){ | |
464 g_print("AAC: Open Decoder Error\n"); | |
465 fclose(file); | |
466 bPlaying = FALSE; | |
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 config = faacDecGetCurrentConfiguration(decoder); | |
471 config->useOldADTSFormat = 0; | |
472 faacDecSetConfiguration(decoder, config); | |
473 if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ | |
474 g_print("AAC: error g_malloc\n"); | |
475 fclose(file); | |
476 bPlaying = FALSE; | |
477 faacDecClose(decoder); | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
478 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
|
479 g_thread_exit(NULL); |
61 | 480 } |
481 if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){ | |
482 g_print("AAC: Error reading file\n"); | |
483 g_free(buffer); | |
484 fclose(file); | |
485 bPlaying = FALSE; | |
486 faacDecClose(decoder); | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
487 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
|
488 g_thread_exit(NULL); |
61 | 489 } |
490 XMMS_NEW_TITLEINPUT(input); | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
491 input->file_name = (char*)g_basename(temp); |
61 | 492 input->file_ext = ext ? ext+1 : NULL; |
493 input->file_path = temp; | |
407
33823c38e10d
[svn] Use glib function for glib types and care about pointer signedness.
chainsaw
parents:
387
diff
changeset
|
494 if(!g_ascii_strncasecmp((gchar*)buffer, "ID3", 3)){ |
61 | 495 gint size = 0; |
496 | |
497 fseek(file, 0, SEEK_SET); | |
498 size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; | |
499 size+=10; | |
500 fread(buffer, 1, size, file); | |
501 buffervalid = fread(buffer, 1, BUFFER_SIZE, file); | |
502 } | |
503 xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); | |
504 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
|
505 xmmstitle = g_path_get_basename(input->file_name); |
61 | 506 if(temp) g_free(temp); |
507 if(input->performer) g_free(input->performer); | |
508 if(input->album_name) g_free(input->album_name); | |
509 if(input->track_name) g_free(input->track_name); | |
510 if(input->genre) g_free(input->genre); | |
511 g_free(input); | |
512 bufferconsumed = faacDecInit(decoder, | |
513 buffer, | |
514 buffervalid, | |
515 &samplerate, | |
516 &channels); | |
517 if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ | |
518 g_print("AAC: Output Error\n"); | |
519 g_free(buffer); buffer=0; | |
520 faacDecClose(decoder); | |
521 fclose(file); | |
522 mp4_ip.output->close_audio(); | |
523 /* | |
524 if(positionTable){ | |
525 g_free(positionTable); positionTable=0; | |
526 } | |
527 */ | |
528 g_free(xmmstitle); | |
529 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
530 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
|
531 g_thread_exit(NULL); |
61 | 532 } |
533 //if(bSeek){ | |
534 //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels); | |
535 //}else{ | |
536 mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); | |
537 //} | |
538 mp4_ip.output->flush(0); | |
539 | |
540 while(bPlaying && buffervalid > 0){ | |
541 faacDecFrameInfo finfo; | |
542 unsigned long samplesdecoded; | |
543 char* sample_buffer = NULL; | |
544 /* | |
545 if(bSeek && seekPosition!=-1){ | |
546 fseek(file, positionTable[seekPosition], SEEK_SET); | |
547 bufferconsumed=0; | |
548 buffervalid = fread(buffer, 1, BUFFER_SIZE, file); | |
549 aac_ip.output->flush(seekPosition*1000); | |
550 seekPosition=-1; | |
551 } | |
552 */ | |
553 if(bufferconsumed > 0){ | |
554 memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); | |
555 buffervalid -= bufferconsumed; | |
556 buffervalid += fread(&buffer[buffervalid], 1, | |
557 BUFFER_SIZE-buffervalid, file); | |
558 bufferconsumed = 0; | |
559 } | |
560 sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid); | |
561 if(finfo.error){ | |
562 config = faacDecGetCurrentConfiguration(decoder); | |
563 if(config->useOldADTSFormat != 1){ | |
564 faacDecClose(decoder); | |
565 decoder = faacDecOpen(); | |
566 config = faacDecGetCurrentConfiguration(decoder); | |
567 config->useOldADTSFormat = 1; | |
568 faacDecSetConfiguration(decoder, config); | |
569 finfo.bytesconsumed=0; | |
570 finfo.samples = 0; | |
571 faacDecInit(decoder, | |
572 buffer, | |
573 buffervalid, | |
574 &samplerate, | |
575 &channels); | |
576 }else{ | |
577 g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error)); | |
578 buffervalid = 0; | |
579 } | |
580 } | |
581 bufferconsumed += finfo.bytesconsumed; | |
582 samplesdecoded = finfo.samples; | |
583 if((samplesdecoded<=0) && !sample_buffer){ | |
584 g_print("AAC: error sample decoding\n"); | |
585 continue; | |
586 } | |
587 while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){ | |
588 xmms_usleep(10000); | |
589 } | |
590 mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), | |
591 FMT_S16_LE, channels, | |
592 samplesdecoded<<1, sample_buffer); | |
593 mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1); | |
594 } | |
595 while(bPlaying && mp4_ip.output->buffer_playing()){ | |
596 xmms_usleep(10000); | |
597 } | |
598 mp4_ip.output->buffer_free(); | |
599 mp4_ip.output->close_audio(); | |
600 bPlaying = FALSE; | |
601 g_free(buffer); | |
602 faacDecClose(decoder); | |
603 g_free(xmmstitle); | |
604 fclose(file); | |
605 seekPosition = -1; | |
606 /* | |
607 if(positionTable){ | |
608 g_free(positionTable); positionTable=0; | |
609 } | |
610 */ | |
611 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
612 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
|
613 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
|
614 return(NULL); |
61 | 615 } |
616 } |