Mercurial > audlegacy
annotate Plugins/Input/aac/src/libmp4.c @ 250:b9e6cdce7219 trunk
[svn] Reduce code duplication and add a return statement.
author | chainsaw |
---|---|
date | Sat, 03 Dec 2005 09:27:11 -0800 |
parents | 094ef8a0a9fd |
children | 1e642d74d68c |
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 | |
14 #include <gtk/gtk.h> | |
15 #include "faad.h" | |
16 #include "mp4.h" | |
17 | |
18 #include <audacious/plugin.h> | |
19 #include <libaudacious/util.h> | |
20 #include <libaudacious/configfile.h> | |
21 #include <libaudacious/titlestring.h> | |
22 | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
23 #define MP4_DESCRIPTION "MP4 & MPEG2/4-AAC for bmp-0.9.7" |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
24 #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
|
25 #define LIBMP4V2_VERSION "1.2.0" |
61 | 26 #define MP4_ABOUT "Written by ciberfred" |
27 #define BUFFER_SIZE FAAD_MIN_STREAMSIZE*64 | |
28 | |
29 static void mp4_init(void); | |
30 static void mp4_about(void); | |
31 static void mp4_play(char *); | |
32 static void mp4_stop(void); | |
33 static void mp4_pause(short); | |
34 static void mp4_seek(int); | |
35 static int mp4_getTime(void); | |
36 static void mp4_cleanup(void); | |
37 static void mp4_getSongInfo(char *); | |
38 static int mp4_isFile(char *); | |
39 static void* mp4Decode(void *); | |
40 | |
41 InputPlugin mp4_ip = | |
42 { | |
43 0, // handle | |
44 0, // filename | |
45 MP4_DESCRIPTION, | |
46 mp4_init, | |
47 mp4_about, | |
48 0, // configuration | |
49 mp4_isFile, | |
50 0, //scandir | |
51 mp4_play, | |
52 mp4_stop, | |
53 mp4_pause, | |
54 mp4_seek, | |
55 0, // set equalizer | |
56 mp4_getTime, | |
57 0, // get volume | |
58 0, | |
59 mp4_cleanup, | |
60 0, // obsolete | |
61 0, // send visualisation data | |
62 0, // set player window info | |
63 0, // set song title text | |
64 0, // get song title text | |
65 mp4_getSongInfo, // info box | |
66 0, // to output plugin | |
67 }; | |
68 | |
69 typedef struct _mp4cfg{ | |
70 gshort file_type; | |
71 #define FILE_UNKNOW 0 | |
72 #define FILE_MP4 1 | |
73 #define FILE_AAC 2 | |
74 } Mp4Config; | |
75 | |
76 static Mp4Config mp4cfg; | |
77 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
|
78 static GThread *decodeThread; |
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
79 GStaticMutex mutex = G_STATIC_MUTEX_INIT; |
61 | 80 static int seekPosition = -1; |
81 | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
82 void getMP4info(char*); |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
83 int getAACTrack(MP4FileHandle); |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
84 |
61 | 85 |
86 InputPlugin *get_iplugin_info(void) | |
87 { | |
88 return(&mp4_ip); | |
89 } | |
90 | |
91 static void mp4_init(void) | |
92 { | |
93 mp4cfg.file_type = FILE_UNKNOW; | |
94 seekPosition = -1; | |
95 return; | |
96 } | |
97 | |
98 static void mp4_play(char *filename) | |
99 { | |
100 bPlaying = TRUE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
101 decodeThread = g_thread_create((GThreadFunc)mp4Decode, g_strdup(filename), TRUE, NULL); |
61 | 102 return; |
103 } | |
104 | |
105 static void mp4_stop(void) | |
106 { | |
107 if(bPlaying){ | |
108 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
109 g_thread_join(decodeThread); |
61 | 110 mp4_ip.output->close_audio(); |
111 } | |
112 } | |
113 | |
114 static int mp4_isFile(char *filename) | |
115 { | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
116 if(filename){ |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
117 gchar* extention; |
61 | 118 |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
119 extention = strrchr(filename, '.'); |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
120 if (extention &&( |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
121 !strcasecmp(extention, ".mp4") || // official extention |
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
122 !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
|
123 !strcasecmp(extention, ".aac") // old MPEG2/4-AAC extention |
61 | 124 )){ |
125 return (1); | |
126 } | |
127 } | |
128 return(0); | |
129 } | |
130 | |
131 static void mp4_about(void) | |
132 { | |
133 static GtkWidget *aboutbox; | |
134 | |
135 if(aboutbox!=NULL) | |
136 return; | |
137 aboutbox = xmms_show_message("About MP4 AAC player plugin", | |
138 "libfaad2-" FAAD2_VERSION "\n" | |
139 "libmp4v2-" LIBMP4V2_VERSION "\n" | |
140 "plugin version: " MP4_VERSION "\n" | |
141 MP4_ABOUT, | |
142 "Ok", FALSE, NULL, NULL); | |
143 gtk_signal_connect(GTK_OBJECT(aboutbox), "destroy", | |
144 GTK_SIGNAL_FUNC(gtk_widget_destroyed), | |
145 &aboutbox); | |
146 } | |
147 | |
148 static void mp4_pause(short flag) | |
149 { | |
150 mp4_ip.output->pause(flag); | |
151 } | |
152 | |
153 static void mp4_seek(int time) | |
154 { | |
155 seekPosition = time; | |
156 while(bPlaying && seekPosition!=-1) | |
157 xmms_usleep(10000); | |
158 } | |
159 | |
160 static int mp4_getTime(void) | |
161 { | |
162 if(!bPlaying) | |
163 return (-1); | |
164 else | |
165 return (mp4_ip.output->output_time()); | |
166 } | |
167 | |
168 static void mp4_cleanup(void) | |
169 { | |
170 } | |
171 | |
172 static void mp4_getSongInfo(char *filename) | |
173 { | |
174 if(mp4cfg.file_type == FILE_MP4) | |
175 getMP4info(filename); | |
176 else if(mp4cfg.file_type == FILE_AAC) | |
177 ; | |
178 } | |
179 | |
180 static void *mp4Decode(void *args) | |
181 { | |
182 MP4FileHandle mp4file; | |
183 | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
184 g_static_mutex_lock(&mutex); |
61 | 185 seekPosition = -1; |
186 bPlaying = TRUE; | |
187 if(!(mp4file = MP4Read(args, 0))){ | |
188 mp4cfg.file_type = FILE_AAC; | |
189 MP4Close(mp4file); | |
190 }else{ | |
191 mp4cfg.file_type = FILE_MP4; | |
192 } | |
193 | |
194 if(mp4cfg.file_type == FILE_MP4){ | |
195 // We are reading a MP4 file | |
196 gint mp4track; | |
197 | |
198 if((mp4track = getAACTrack(mp4file)) < 0){ | |
199 //TODO: check here for others Audio format..... | |
200 g_print("Unsupported Audio track type\n"); | |
201 g_free(args); | |
202 MP4Close(mp4file); | |
203 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
204 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
|
205 g_thread_exit(NULL); |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
206 return(NULL); |
61 | 207 }else{ |
208 faacDecHandle decoder; | |
209 unsigned char *buffer = NULL; | |
210 guint bufferSize = 0; | |
211 gulong samplerate; | |
212 guchar channels; | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
213 //guint avgBitrate; |
61 | 214 MP4Duration duration; |
215 gulong msDuration; | |
216 MP4SampleId numSamples; | |
217 MP4SampleId sampleID = 1; | |
218 | |
219 decoder = faacDecOpen(); | |
220 MP4GetTrackESConfiguration(mp4file, mp4track, &buffer, &bufferSize); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
221 if(!buffer) |
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
222 goto out; |
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
223 if(faacDecInit2(decoder, buffer, bufferSize, &samplerate, &channels)<0) |
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
224 goto out; |
61 | 225 g_free(buffer); |
226 if(channels == 0){ | |
227 g_print("Number of Channels not supported\n"); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
228 goto out; |
61 | 229 } |
230 duration = MP4GetTrackDuration(mp4file, mp4track); | |
231 msDuration = MP4ConvertFromTrackDuration(mp4file, mp4track, duration, | |
232 MP4_MSECS_TIME_SCALE); | |
233 numSamples = MP4GetTrackNumberOfSamples(mp4file, mp4track); | |
234 mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels); | |
235 mp4_ip.output->flush(0); | |
236 mp4_ip.set_info(args, msDuration, -1, samplerate/1000, channels); | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
237 g_print("MP4 - %d channels @ %d Hz\n", channels, (int)samplerate); |
61 | 238 |
239 while(bPlaying){ | |
240 void* sampleBuffer; | |
241 faacDecFrameInfo frameInfo; | |
242 gint rc; | |
243 | |
244 if(seekPosition!=-1){ | |
245 duration = MP4ConvertToTrackDuration(mp4file, | |
246 mp4track, | |
247 seekPosition*1000, | |
248 MP4_MSECS_TIME_SCALE); | |
249 sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0); | |
250 mp4_ip.output->flush(seekPosition*1000); | |
251 seekPosition = -1; | |
252 } | |
253 buffer=NULL; | |
254 bufferSize=0; | |
255 if(sampleID > numSamples){ | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
256 goto out; |
61 | 257 } |
258 rc = MP4ReadSample(mp4file, mp4track, sampleID++, &buffer, &bufferSize, | |
259 NULL, NULL, NULL, NULL); | |
260 //g_print("%d/%d\n", sampleID-1, numSamples); | |
261 if((rc==0) || (buffer== NULL)){ | |
262 g_print("MP4: read error\n"); | |
263 sampleBuffer = NULL; | |
264 sampleID=0; | |
265 mp4_ip.output->buffer_free(); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
266 goto out; |
61 | 267 }else{ |
268 sampleBuffer = faacDecDecode(decoder, &frameInfo, buffer, bufferSize); | |
269 if(frameInfo.error > 0){ | |
270 g_print("MP4: %s\n", | |
271 faacDecGetErrorMessage(frameInfo.error)); | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
272 goto out; |
61 | 273 } |
274 if(buffer){ | |
275 g_free(buffer); buffer=NULL; bufferSize=0; | |
276 } | |
277 while(bPlaying && mp4_ip.output->buffer_free()<frameInfo.samples<<1) | |
278 xmms_usleep(30000); | |
279 } | |
280 mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), | |
281 FMT_S16_NE, | |
282 channels, | |
283 frameInfo.samples<<1, | |
284 sampleBuffer); | |
285 mp4_ip.output->write_audio(sampleBuffer, frameInfo.samples<<1); | |
286 } | |
287 while(bPlaying && mp4_ip.output->buffer_free()){ | |
288 xmms_usleep(10000); | |
289 } | |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
290 out: |
61 | 291 mp4_ip.output->close_audio(); |
292 g_free(args); | |
293 faacDecClose(decoder); | |
294 MP4Close(mp4file); | |
295 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
296 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
|
297 g_thread_exit(NULL); |
250
b9e6cdce7219
[svn] Reduce code duplication and add a return statement.
chainsaw
parents:
200
diff
changeset
|
298 return(NULL); |
61 | 299 } |
300 } else{ | |
301 // WE ARE READING AN AAC FILE | |
302 FILE *file = NULL; | |
303 faacDecHandle decoder = 0; | |
304 guchar *buffer = 0; | |
305 gulong bufferconsumed = 0; | |
306 gulong samplerate = 0; | |
307 guchar channels; | |
308 gulong buffervalid = 0; | |
309 TitleInput* input; | |
310 gchar *temp = g_strdup(args); | |
311 gchar *ext = strrchr(temp, '.'); | |
312 gchar *xmmstitle = NULL; | |
313 faacDecConfigurationPtr config; | |
314 | |
315 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
|
316 g_print("AAC: can't find file %s\n", (char*)args); |
61 | 317 bPlaying = FALSE; |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
318 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
|
319 g_thread_exit(NULL); |
61 | 320 } |
321 if((decoder = faacDecOpen()) == NULL){ | |
322 g_print("AAC: Open Decoder Error\n"); | |
323 fclose(file); | |
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); |
61 | 327 } |
328 config = faacDecGetCurrentConfiguration(decoder); | |
329 config->useOldADTSFormat = 0; | |
330 faacDecSetConfiguration(decoder, config); | |
331 if((buffer = g_malloc(BUFFER_SIZE)) == NULL){ | |
332 g_print("AAC: error g_malloc\n"); | |
333 fclose(file); | |
334 bPlaying = FALSE; | |
335 faacDecClose(decoder); | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
336 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
|
337 g_thread_exit(NULL); |
61 | 338 } |
339 if((buffervalid = fread(buffer, 1, BUFFER_SIZE, file))==0){ | |
340 g_print("AAC: Error reading file\n"); | |
341 g_free(buffer); | |
342 fclose(file); | |
343 bPlaying = FALSE; | |
344 faacDecClose(decoder); | |
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); |
61 | 347 } |
348 XMMS_NEW_TITLEINPUT(input); | |
199
0a2ad94e8607
[svn] Synced with bmp-mp4. Build system is fragile, but should work now.
chainsaw
parents:
61
diff
changeset
|
349 input->file_name = (char*)g_basename(temp); |
61 | 350 input->file_ext = ext ? ext+1 : NULL; |
351 input->file_path = temp; | |
352 if(!strncmp(buffer, "ID3", 3)){ | |
353 gint size = 0; | |
354 | |
355 fseek(file, 0, SEEK_SET); | |
356 size = (buffer[6]<<21) | (buffer[7]<<14) | (buffer[8]<<7) | buffer[9]; | |
357 size+=10; | |
358 fread(buffer, 1, size, file); | |
359 buffervalid = fread(buffer, 1, BUFFER_SIZE, file); | |
360 } | |
361 xmmstitle = xmms_get_titlestring(xmms_get_gentitle_format(), input); | |
362 if(xmmstitle == NULL) | |
363 xmmstitle = g_strdup(input->file_name); | |
364 if(temp) g_free(temp); | |
365 if(input->performer) g_free(input->performer); | |
366 if(input->album_name) g_free(input->album_name); | |
367 if(input->track_name) g_free(input->track_name); | |
368 if(input->genre) g_free(input->genre); | |
369 g_free(input); | |
370 bufferconsumed = faacDecInit(decoder, | |
371 buffer, | |
372 buffervalid, | |
373 &samplerate, | |
374 &channels); | |
375 if(mp4_ip.output->open_audio(FMT_S16_NE,samplerate,channels) == FALSE){ | |
376 g_print("AAC: Output Error\n"); | |
377 g_free(buffer); buffer=0; | |
378 faacDecClose(decoder); | |
379 fclose(file); | |
380 mp4_ip.output->close_audio(); | |
381 /* | |
382 if(positionTable){ | |
383 g_free(positionTable); positionTable=0; | |
384 } | |
385 */ | |
386 g_free(xmmstitle); | |
387 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
388 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
|
389 g_thread_exit(NULL); |
61 | 390 } |
391 //if(bSeek){ | |
392 //mp4_ip.set_info(xmmstitle, lenght*1000, -1, samplerate, channels); | |
393 //}else{ | |
394 mp4_ip.set_info(xmmstitle, -1, -1, samplerate, channels); | |
395 //} | |
396 mp4_ip.output->flush(0); | |
397 | |
398 while(bPlaying && buffervalid > 0){ | |
399 faacDecFrameInfo finfo; | |
400 unsigned long samplesdecoded; | |
401 char* sample_buffer = NULL; | |
402 /* | |
403 if(bSeek && seekPosition!=-1){ | |
404 fseek(file, positionTable[seekPosition], SEEK_SET); | |
405 bufferconsumed=0; | |
406 buffervalid = fread(buffer, 1, BUFFER_SIZE, file); | |
407 aac_ip.output->flush(seekPosition*1000); | |
408 seekPosition=-1; | |
409 } | |
410 */ | |
411 if(bufferconsumed > 0){ | |
412 memmove(buffer, &buffer[bufferconsumed], buffervalid-bufferconsumed); | |
413 buffervalid -= bufferconsumed; | |
414 buffervalid += fread(&buffer[buffervalid], 1, | |
415 BUFFER_SIZE-buffervalid, file); | |
416 bufferconsumed = 0; | |
417 } | |
418 sample_buffer = faacDecDecode(decoder, &finfo, buffer, buffervalid); | |
419 if(finfo.error){ | |
420 config = faacDecGetCurrentConfiguration(decoder); | |
421 if(config->useOldADTSFormat != 1){ | |
422 faacDecClose(decoder); | |
423 decoder = faacDecOpen(); | |
424 config = faacDecGetCurrentConfiguration(decoder); | |
425 config->useOldADTSFormat = 1; | |
426 faacDecSetConfiguration(decoder, config); | |
427 finfo.bytesconsumed=0; | |
428 finfo.samples = 0; | |
429 faacDecInit(decoder, | |
430 buffer, | |
431 buffervalid, | |
432 &samplerate, | |
433 &channels); | |
434 }else{ | |
435 g_print("FAAD2 Warning %s\n", faacDecGetErrorMessage(finfo.error)); | |
436 buffervalid = 0; | |
437 } | |
438 } | |
439 bufferconsumed += finfo.bytesconsumed; | |
440 samplesdecoded = finfo.samples; | |
441 if((samplesdecoded<=0) && !sample_buffer){ | |
442 g_print("AAC: error sample decoding\n"); | |
443 continue; | |
444 } | |
445 while(bPlaying && mp4_ip.output->buffer_free() < (samplesdecoded<<1)){ | |
446 xmms_usleep(10000); | |
447 } | |
448 mp4_ip.add_vis_pcm(mp4_ip.output->written_time(), | |
449 FMT_S16_LE, channels, | |
450 samplesdecoded<<1, sample_buffer); | |
451 mp4_ip.output->write_audio(sample_buffer, samplesdecoded<<1); | |
452 } | |
453 while(bPlaying && mp4_ip.output->buffer_playing()){ | |
454 xmms_usleep(10000); | |
455 } | |
456 mp4_ip.output->buffer_free(); | |
457 mp4_ip.output->close_audio(); | |
458 bPlaying = FALSE; | |
459 g_free(buffer); | |
460 faacDecClose(decoder); | |
461 g_free(xmmstitle); | |
462 fclose(file); | |
463 seekPosition = -1; | |
464 /* | |
465 if(positionTable){ | |
466 g_free(positionTable); positionTable=0; | |
467 } | |
468 */ | |
469 bPlaying = FALSE; | |
200
094ef8a0a9fd
[svn] GThreadify plugin. Adds a return statement and removes a pragma statement to please GCC.
chainsaw
parents:
199
diff
changeset
|
470 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
|
471 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
|
472 return(NULL); |
61 | 473 } |
474 } |