Mercurial > audlegacy
annotate Plugins/Input/aac/src/libmp4.c @ 842:3b2b0d68960c trunk
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
author | chainsaw |
---|---|
date | Sat, 18 Mar 2006 08:56:03 -0800 |
parents | d2db0feae0ca |
children | cfa2d55986fd |
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> | |
842
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
27 #include <libaudacious/vfs.h> |
61 | 28 |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
29 #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
|
30 #define LIBMP4V2_VERSION "1.2.0" |
61 | 31 #define MP4_ABOUT "Written by ciberfred" |
32 #define BUFFER_SIZE FAAD_MIN_STREAMSIZE*64 | |
33 | |
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
|
34 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
|
35 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
|
36 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
|
37 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
|
38 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
|
39 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
|
40 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
|
41 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
|
42 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
|
43 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
|
44 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
|
45 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
|
46 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
|
47 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
|
48 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
|
49 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
|
50 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
|
51 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
|
52 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
|
53 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
|
54 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
|
55 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
|
56 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
|
57 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
|
58 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
|
59 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
|
60 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
|
61 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
|
62 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
|
63 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
|
64 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
|
65 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
|
66 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
|
67 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
|
68 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
|
69 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
|
70 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
|
71 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
|
72 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
|
73 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
|
74 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
|
75 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
|
76 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
|
77 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
|
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 |
842
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
80 #define AAC_MAGIC (unsigned char [4]) { 0xFF, 0xF9, 0x5C, 0x80 } |
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
|
81 |
61 | 82 static void mp4_init(void); |
83 static void mp4_about(void); | |
84 static void mp4_play(char *); | |
85 static void mp4_stop(void); | |
86 static void mp4_pause(short); | |
87 static void mp4_seek(int); | |
88 static int mp4_getTime(void); | |
89 static void mp4_cleanup(void); | |
842
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
90 static int mp4_IsOurFile(char *); |
339 | 91 static void mp4_getSongTitle(char *filename, char **, int *); |
61 | 92 static void* mp4Decode(void *); |
93 | |
346
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
94 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
|
95 |
61 | 96 InputPlugin mp4_ip = |
97 { | |
98 0, // handle | |
99 0, // filename | |
344
a98a7f2dfc84
[svn] Display the MP4/AAC+ bitrate, instead of "VBR".
nenolod
parents:
342
diff
changeset
|
100 "MP4 Audio Plugin", |
61 | 101 mp4_init, |
102 mp4_about, | |
103 0, // configuration | |
842
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
104 mp4_IsOurFile, |
61 | 105 0, //scandir |
106 mp4_play, | |
107 mp4_stop, | |
108 mp4_pause, | |
109 mp4_seek, | |
110 0, // set equalizer | |
111 mp4_getTime, | |
112 0, // get volume | |
113 0, | |
114 mp4_cleanup, | |
115 0, // obsolete | |
116 0, // send visualisation data | |
117 0, // set player window info | |
118 0, // set song title text | |
339 | 119 mp4_getSongTitle, // get song title text |
342
320f0205ad45
[svn] Initial fileinfo box, loosely based around the mpg123-clone one.
nenolod
parents:
340
diff
changeset
|
120 audmp4_file_info_box, // info box |
61 | 121 0, // to output plugin |
122 }; | |
123 | |
124 typedef struct _mp4cfg{ | |
125 gshort file_type; | |
126 #define FILE_UNKNOW 0 | |
127 #define FILE_MP4 1 | |
128 #define FILE_AAC 2 | |
129 } Mp4Config; | |
130 | |
131 static Mp4Config mp4cfg; | |
132 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
|
133 static GThread *decodeThread; |
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
134 GStaticMutex mutex = G_STATIC_MUTEX_INIT; |
61 | 135 static int seekPosition = -1; |
136 | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
137 void getMP4info(char*); |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
138 int getAACTrack(MP4FileHandle); |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
139 |
339 | 140 /* |
141 * Function extname (filename) | |
142 * | |
143 * Return pointer within filename to its extenstion, or NULL if | |
144 * filename has no extension. | |
145 * | |
146 */ | |
147 static gchar * | |
148 extname(const char *filename) | |
149 { | |
150 gchar *ext = strrchr(filename, '.'); | |
151 | |
152 if (ext != NULL) | |
153 ++ext; | |
154 | |
155 return ext; | |
156 } | |
61 | 157 |
158 InputPlugin *get_iplugin_info(void) | |
159 { | |
160 return(&mp4_ip); | |
161 } | |
162 | |
163 static void mp4_init(void) | |
164 { | |
165 mp4cfg.file_type = FILE_UNKNOW; | |
166 seekPosition = -1; | |
167 return; | |
168 } | |
169 | |
170 static void mp4_play(char *filename) | |
171 { | |
172 bPlaying = TRUE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
173 decodeThread = g_thread_create((GThreadFunc)mp4Decode, g_strdup(filename), TRUE, NULL); |
61 | 174 return; |
175 } | |
176 | |
177 static void mp4_stop(void) | |
178 { | |
179 if(bPlaying){ | |
180 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
181 g_thread_join(decodeThread); |
61 | 182 mp4_ip.output->close_audio(); |
183 } | |
184 } | |
185 | |
842
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
186 static int mp4_IsOurFile(char *filename) |
61 | 187 { |
842
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
188 VFSFile *file; |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
189 gchar* extension; |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
190 gchar magic[4]; |
61 | 191 |
842
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
192 extension = strrchr(filename, '.'); |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
193 if ((file = vfs_fopen(filename, "rb"))) { |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
194 vfs_fread(magic, 1, 4, file); |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
195 if (!memcmp(magic, AAC_MAGIC, 4)) { |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
196 vfs_fclose(file); |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
197 return 1; |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
198 } |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
199 if (!strncmp(magic, "ID3", 3)) { // ID3 tag bolted to the front, obfuscated magic bytes |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
200 vfs_fclose(file); |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
201 if (extension &&( |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
202 !strcasecmp(extension, ".mp4") || // official extension |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
203 !strcasecmp(extension, ".m4a") || // Apple mp4 extension |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
204 !strcasecmp(extension, ".aac") // old MPEG2/4-AAC extension |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
205 )) |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
206 return 1; |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
207 else |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
208 return 0; |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
209 } |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
210 vfs_fread(magic, 1, 4, file); |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
211 if (!strncasecmp(magic, "ftyp", 6)) { |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
212 vfs_fclose(file); |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
213 return 1; |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
214 } |
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
215 vfs_fclose(file); |
61 | 216 } |
842
3b2b0d68960c
[svn] Use magic bytes to identify AAC and MP4 as the decoder insists on reading the entire file before making a decision. This can be upsetting to users of large playlists, so reduce that to two 4-byte reads. Extension checking still needed for files that have been butchered by bad taggers, sorry.
chainsaw
parents:
832
diff
changeset
|
217 return 0; |
61 | 218 } |
219 | |
220 static void mp4_about(void) | |
221 { | |
222 static GtkWidget *aboutbox; | |
223 | |
224 if(aboutbox!=NULL) | |
225 return; | |
226 aboutbox = xmms_show_message("About MP4 AAC player plugin", | |
227 "libfaad2-" FAAD2_VERSION "\n" | |
228 "libmp4v2-" LIBMP4V2_VERSION "\n" | |
229 "plugin version: " MP4_VERSION "\n" | |
230 MP4_ABOUT, | |
231 "Ok", FALSE, NULL, NULL); | |
232 gtk_signal_connect(GTK_OBJECT(aboutbox), "destroy", | |
233 GTK_SIGNAL_FUNC(gtk_widget_destroyed), | |
234 &aboutbox); | |
235 } | |
236 | |
237 static void mp4_pause(short flag) | |
238 { | |
239 mp4_ip.output->pause(flag); | |
240 } | |
241 | |
242 static void mp4_seek(int time) | |
243 { | |
244 seekPosition = time; | |
245 while(bPlaying && seekPosition!=-1) | |
246 xmms_usleep(10000); | |
247 } | |
248 | |
249 static int mp4_getTime(void) | |
250 { | |
251 if(!bPlaying) | |
252 return (-1); | |
253 else | |
254 return (mp4_ip.output->output_time()); | |
255 } | |
256 | |
257 static void mp4_cleanup(void) | |
258 { | |
259 } | |
260 | |
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
|
261 #if 0 |
61 | 262 static void mp4_getSongInfo(char *filename) |
263 { | |
264 if(mp4cfg.file_type == FILE_MP4) | |
265 getMP4info(filename); | |
266 else if(mp4cfg.file_type == FILE_AAC) | |
267 ; | |
268 } | |
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
|
269 #endif |
61 | 270 |
339 | 271 static gchar *mp4_get_song_title(char *filename) |
272 { | |
273 MP4FileHandle mp4file; | |
274 gchar *title = NULL; | |
275 | |
276 if (!(mp4file = MP4Read(filename, 0))) { | |
277 MP4Close(mp4file); | |
278 } else { | |
279 TitleInput *input; | |
280 gchar *tmpval; | |
281 | |
282 input = bmp_title_input_new(); | |
283 | |
284 MP4GetMetadataName(mp4file, &input->track_name); | |
285 MP4GetMetadataAlbum(mp4file, &input->album_name); | |
286 MP4GetMetadataArtist(mp4file, &input->performer); | |
287 MP4GetMetadataYear(mp4file, &tmpval); | |
288 MP4GetMetadataGenre(mp4file, &input->genre); | |
289 | |
340 | 290 if (tmpval) |
793 | 291 { |
340 | 292 input->year = atoi(tmpval); |
793 | 293 free(tmpval); |
294 } | |
339 | 295 |
296 input->file_name = g_path_get_basename(filename); | |
297 input->file_path = g_path_get_dirname(filename); | |
298 input->file_ext = extname(filename); | |
299 | |
300 title = xmms_get_titlestring(xmms_get_gentitle_format(), input); | |
301 | |
793 | 302 free (input->track_name); |
303 free (input->album_name); | |
304 free (input->performer); | |
305 free (input->genre); | |
339 | 306 free (input->file_name); |
307 free (input->file_path); | |
308 free (input); | |
309 } | |
310 | |
311 if (!title) | |
312 { | |
313 title = g_path_get_basename(filename); | |
314 if (extname(title)) | |
315 *(extname(title) - 1) = '\0'; | |
316 } | |
317 | |
318 return title; | |
319 } | |
320 | |
321 static void mp4_getSongTitle(char *filename, char **title_real, int *len_real) | |
322 { | |
323 (*title_real) = mp4_get_song_title(filename); | |
324 (*len_real) = -1; | |
325 } | |
326 | |
61 | 327 static void *mp4Decode(void *args) |
328 { | |
329 MP4FileHandle mp4file; | |
330 | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
331 g_static_mutex_lock(&mutex); |
61 | 332 seekPosition = -1; |
333 bPlaying = TRUE; | |
334 if(!(mp4file = MP4Read(args, 0))){ | |
335 mp4cfg.file_type = FILE_AAC; | |
336 MP4Close(mp4file); | |
337 }else{ | |
338 mp4cfg.file_type = FILE_MP4; | |
339 } | |
340 | |
341 if(mp4cfg.file_type == FILE_MP4){ | |
342 // We are reading a MP4 file | |
343 gint mp4track; | |
344 | |
345 if((mp4track = getAACTrack(mp4file)) < 0){ | |
346 //TODO: check here for others Audio format..... | |
347 g_print("Unsupported Audio track type\n"); | |
348 g_free(args); | |
349 MP4Close(mp4file); | |
350 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
351 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
|
352 g_thread_exit(NULL); |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
353 return(NULL); |
61 | 354 }else{ |
355 faacDecHandle decoder; | |
356 unsigned char *buffer = NULL; | |
357 guint bufferSize = 0; | |
358 gulong samplerate; | |
359 guchar channels; | |
344
a98a7f2dfc84
[svn] Display the MP4/AAC+ bitrate, instead of "VBR".
nenolod
parents:
342
diff
changeset
|
360 guint avgBitrate; |
61 | 361 MP4Duration duration; |
362 gulong msDuration; | |
363 MP4SampleId numSamples; | |
364 MP4SampleId sampleID = 1; | |
339 | 365 gchar *title; |
61 | 366 |
367 decoder = faacDecOpen(); | |
368 MP4GetTrackESConfiguration(mp4file, mp4track, &buffer, &bufferSize); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
369 if(!buffer) |
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
370 goto out; |
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
371 if(faacDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0) |
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
372 goto out; |
61 | 373 g_free(buffer); |
374 if(channels == 0){ | |
375 g_print("Number of Channels not supported\n"); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
376 goto out; |
61 | 377 } |
378 duration = MP4GetTrackDuration(mp4file, mp4track); | |
379 msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, duration, | |
380 MP4_MSECS_TIME_SCALE); | |
381 numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track); | |
345
9b19994a715c
[svn] ditto for samplerate... we should have full plugin compatibility now
nenolod
parents:
344
diff
changeset
|
382 samplerate = MP4GetTrackTimeScale(mp4file, mp4track); |
61 | 383 mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels); |
384 mp4_ip.output->flush(0); | |
339 | 385 title = mp4_get_song_title(args); |
344
a98a7f2dfc84
[svn] Display the MP4/AAC+ bitrate, instead of "VBR".
nenolod
parents:
342
diff
changeset
|
386 avgBitrate = MP4GetTrackBitRate(mp4file, mp4track); |
345
9b19994a715c
[svn] ditto for samplerate... we should have full plugin compatibility now
nenolod
parents:
344
diff
changeset
|
387 mp4_ip.set_info(title, msDuration, avgBitrate, samplerate, channels); |
61 | 388 |
389 while(bPlaying){ | |
390 void* sampleBuffer; | |
391 faacDecFrameInfo frameInfo; | |
392 gint rc; | |
393 | |
394 if(seekPosition!=-1){ | |
395 duration = MP4ConvertToTrackDuration(mp4file, | |
396 mp4track, | |
397 seekPosition*1000, | |
398 MP4_MSECS_TIME_SCALE); | |
399 sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0); | |
400 mp4_ip.output->flush(seekPosition*1000); | |
401 seekPosition = -1; | |
402 } | |
403 buffer=NULL; | |
404 bufferSize=0; | |
405 if(sampleID > numSamples){ | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
406 goto out; |
61 | 407 } |
408 rc = MP4ReadSample(mp4file, mp4track, sampleID++, &buffer, &bufferSize, | |
409 NULL, NULL, NULL, NULL); | |
410 if((rc==0) || (buffer== NULL)){ | |
411 g_print("MP4: read error\n"); | |
412 sampleBuffer = NULL; | |
413 sampleID=0; | |
414 mp4_ip.output->buffer_free(); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
415 goto out; |
61 | 416 }else{ |
417 sampleBuffer = faacDecDecode(decoder, &frameInfo, buffer, bufferSize); | |
418 if(frameInfo.error > 0){ | |
419 g_print("MP4: %s\n", | |
420 faacDecGetErrorMessage(frameInfo.error)); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
421 goto out; |
61 | 422 } |
423 if(buffer){ | |
424 g_free(buffer); buffer=NULL; bufferSize=0; | |
425 } | |
426 while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1) | |
427 xmms_usleep(30000); | |
428 } | |
346
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
429 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
|
430 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
|
431 channels, |
430658951e30
[svn] Use produce_audio() to pass the audio through the new audacious filterchain stuff. (EQ support!!!)
nenolod
parents:
345
diff
changeset
|
432 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
|
433 sampleBuffer, &bPlaying); |
61 | 434 } |
435 while(bPlaying && mp4_ip.output->buffer_free()){ | |
436 xmms_usleep(10000); | |
437 } | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
438 out: |
61 | 439 mp4_ip.output->close_audio(); |
440 g_free(args); | |
441 faacDecClose(decoder); | |
442 MP4Close(mp4file); | |
443 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
444 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
|
445 g_thread_exit(NULL); |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
446 return(NULL); |
61 | 447 } |
448 } else{ | |
449 // WE ARE READING AN AAC FILE | |
450 FILE *file = NULL; | |
451 faacDecHandle decoder = 0; | |
452 guchar *buffer = 0; | |
453 gulong bufferconsumed = 0; | |
454 gulong samplerate = 0; | |
455 guchar channels; | |
456 gulong buffervalid = 0; | |
457 TitleInput* input; | |
458 gchar *temp = g_strdup(args); | |
459 gchar *ext = strrchr(temp, '.'); | |
460 gchar *xmmstitle = NULL; | |
461 faacDecConfigurationPtr config; | |
462 | |
463 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
|
464 g_print("AAC: can't find file %s\n", (char*)args); |
61 | 465 bPlaying = FALSE; |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
466 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
|
467 g_thread_exit(NULL); |
61 | 468 } |
469 if((decoder = faacDecOpen()) == NULL){ | |
470 g_print("AAC: Open Decoder Error\n"); | |
471 fclose(file); | |
472 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
473 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
|
474 g_thread_exit(NULL); |
61 | 475 } |
476 config = faacDecGetCurrentConfiguration(decoder); | |
477 config->useOldADTSFormat = 0; | |
478 faacDecSetConfiguration(decoder, config); | |
479 if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ | |
480 g_print("AAC: error g_malloc\n"); | |
481 fclose(file); | |
482 bPlaying = FALSE; | |
483 faacDecClose(decoder); | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
484 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
|
485 g_thread_exit(NULL); |
61 | 486 } |
487 if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){ | |
488 g_print("AAC: Error reading file\n"); | |
489 g_free(buffer); | |
490 fclose(file); | |
491 bPlaying = FALSE; | |
492 faacDecClose(decoder); | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
493 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
|
494 g_thread_exit(NULL); |
61 | 495 } |
496 XMMS_NEW_TITLEINPUT(input); | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
497 input->file_name = (char*)g_basename(temp); |
61 | 498 input->file_ext = ext ? ext+1 : NULL; |
499 input->file_path = temp; | |
407
33823c38e10d
[svn] Use glib function for glib types and care about pointer signedness.
chainsaw
parents:
387
diff
changeset
|
500 if(!g_ascii_strncasecmp((gchar*)buffer, "ID3", 3)){ |
61 | 501 gint size = 0; |
502 | |
503 fseek(file, 0, SEEK_SET); | |
504 size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; | |
505 size+=10; | |
506 fread(buffer, 1, size, file); | |
507 buffervalid = fread(buffer, 1, BUFFER_SIZE, file); | |
508 } | |
509 xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); | |
510 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
|
511 xmmstitle = g_path_get_basename(input->file_name); |
61 | 512 if(temp) g_free(temp); |
513 if(input->performer) g_free(input->performer); | |
514 if(input->album_name) g_free(input->album_name); | |
515 if(input->track_name) g_free(input->track_name); | |
516 if(input->genre) g_free(input->genre); | |
517 g_free(input); | |
518 bufferconsumed = faacDecInit(decoder, | |
519 buffer, | |
520 buffervalid, | |
521 &samplerate, | |
522 &channels); | |
523 if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ | |
524 g_print("AAC: Output Error\n"); | |
525 g_free(buffer); buffer=0; | |
526 faacDecClose(decoder); | |
527 fclose(file); | |
528 mp4_ip.output->close_audio(); | |
529 /* | |
530 if(positionTable){ | |
531 g_free(positionTable); positionTable=0; | |
532 } | |
533 */ | |
534 g_free(xmmstitle); | |
535 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
536 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
|
537 g_thread_exit(NULL); |
61 | 538 } |
539 //if(bSeek){ | |
540 //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels); | |
541 //}else{ | |
542 mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); | |
543 //} | |
544 mp4_ip.output->flush(0); | |
545 | |
546 while(bPlaying && buffervalid > 0){ | |
547 faacDecFrameInfo finfo; | |
548 unsigned long samplesdecoded; | |
549 char* sample_buffer = NULL; | |
550 /* | |
551 if(bSeek && seekPosition!=-1){ | |
552 fseek(file, positionTable[seekPosition], SEEK_SET); | |
553 bufferconsumed=0; | |
554 buffervalid = fread(buffer, 1, BUFFER_SIZE, file); | |
555 aac_ip.output->flush(seekPosition*1000); | |
556 seekPosition=-1; | |
557 } | |
558 */ | |
559 if(bufferconsumed > 0){ | |
560 memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); | |
561 buffervalid -= bufferconsumed; | |
562 buffervalid += fread(&buffer[buffervalid], 1, | |
563 BUFFER_SIZE-buffervalid, file); | |
564 bufferconsumed = 0; | |
565 } | |
566 sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid); | |
567 if(finfo.error){ | |
568 config = faacDecGetCurrentConfiguration(decoder); | |
569 if(config->useOldADTSFormat != 1){ | |
570 faacDecClose(decoder); | |
571 decoder = faacDecOpen(); | |
572 config = faacDecGetCurrentConfiguration(decoder); | |
573 config->useOldADTSFormat = 1; | |
574 faacDecSetConfiguration(decoder, config); | |
575 finfo.bytesconsumed=0; | |
576 finfo.samples = 0; | |
577 faacDecInit(decoder, | |
578 buffer, | |
579 buffervalid, | |
580 &samplerate, | |
581 &channels); | |
582 }else{ | |
583 g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error)); | |
584 buffervalid = 0; | |
585 } | |
586 } | |
587 bufferconsumed += finfo.bytesconsumed; | |
588 samplesdecoded = finfo.samples; | |
589 if((samplesdecoded<=0) && !sample_buffer){ | |
590 g_print("AAC: error sample decoding\n"); | |
591 continue; | |
592 } | |
593 while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){ | |
594 xmms_usleep(10000); | |
595 } | |
596 mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), | |
597 FMT_S16_LE, channels, | |
598 samplesdecoded<<1, sample_buffer); | |
599 mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1); | |
600 } | |
601 while(bPlaying && mp4_ip.output->buffer_playing()){ | |
602 xmms_usleep(10000); | |
603 } | |
604 mp4_ip.output->buffer_free(); | |
605 mp4_ip.output->close_audio(); | |
606 bPlaying = FALSE; | |
607 g_free(buffer); | |
608 faacDecClose(decoder); | |
609 g_free(xmmstitle); | |
610 fclose(file); | |
611 seekPosition = -1; | |
612 /* | |
613 if(positionTable){ | |
614 g_free(positionTable); positionTable=0; | |
615 } | |
616 */ | |
617 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
618 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
|
619 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
|
620 return(NULL); |
61 | 621 } |
622 } |