comparison src/ffmpeg/ffmpeg.c @ 836:7efd0747b362 trunk

[svn] - namespace changes
author nenolod
date Mon, 12 Mar 2007 16:02:59 -0700
parents 485ba2ba5976
children 8561bcf928a3
comparison
equal deleted inserted replaced
835:485ba2ba5976 836:7efd0747b362
61 See the GNU General Public License for more details.\n" 61 See the GNU General Public License for more details.\n"
62 #define PLUGIN_NAME "Audacious-WMA" 62 #define PLUGIN_NAME "Audacious-WMA"
63 #define PLUGIN_VERSION "v.1.0.5" 63 #define PLUGIN_VERSION "v.1.0.5"
64 #define ST_BUFF 1024 64 #define ST_BUFF 1024
65 65
66 static int wma_decode = 0; 66 static int ffmpeg_decode = 0;
67 static gboolean wma_pause = 0; 67 static gboolean ffmpeg_pause = 0;
68 static int wma_seekpos = -1; 68 static int ffmpeg_seekpos = -1;
69 static int wma_st_buff, wma_idx, wma_idx2; 69 static int ffmpeg_st_buff, ffmpeg_idx, ffmpeg_idx2;
70 static GThread *wma_decode_thread; 70 static GThread *ffmpeg_decode_thread;
71 GStaticMutex wma_mutex = G_STATIC_MUTEX_INIT; 71 GStaticMutex ffmpeg_mutex = G_STATIC_MUTEX_INIT;
72 static AVCodecContext *c = NULL; 72 static AVCodecContext *c = NULL;
73 static AVFormatContext *ic = NULL; 73 static AVFormatContext *ic = NULL;
74 static AVCodecContext *c2 = NULL; 74 static AVCodecContext *c2 = NULL;
75 static AVFormatContext *ic2 = NULL; 75 static AVFormatContext *ic2 = NULL;
76 static uint8_t *wma_outbuf, *wma_s_outbuf; 76 static uint8_t *ffmpeg_outbuf, *ffmpeg_s_outbuf;
77 77
78 char description[64]; 78 char description[64];
79 static void wma_about(void); 79 static void ffmpeg_about(void);
80 static void wma_init(void); 80 static void ffmpeg_init(void);
81 static int wma_is_our_file(char *filename); 81 static int ffmpeg_is_our_file(char *filename);
82 static int wma_is_our_fd(char *filename, VFSFile *fd); 82 static int ffmpeg_is_our_fd(char *filename, VFSFile *fd);
83 static void wma_play_file(InputPlayback *data); 83 static void ffmpeg_play_file(InputPlayback *data);
84 static void wma_stop(InputPlayback *data); 84 static void ffmpeg_stop(InputPlayback *data);
85 static void wma_seek(InputPlayback *data, int time); 85 static void ffmpeg_seek(InputPlayback *data, int time);
86 static void wma_do_pause(InputPlayback *data, short p); 86 static void ffmpeg_do_pause(InputPlayback *data, short p);
87 static int wma_get_time(InputPlayback *data); 87 static int ffmpeg_get_time(InputPlayback *data);
88 static void wma_get_song_info(char *filename, char **title, int *length); 88 static void ffmpeg_get_song_info(char *filename, char **title, int *length);
89 static TitleInput *wma_get_song_tuple(char *filename); 89 static TitleInput *ffmpeg_get_song_tuple(char *filename);
90 static char *wsong_title; 90 static char *wsong_title;
91 static int wsong_time; 91 static int wsong_time;
92 92
93 static GtkWidget *dialog1, *button1, *label1; 93 static GtkWidget *dialog1, *button1, *label1;
94 94
95 InputPlugin *get_iplugin_info(void); 95 InputPlugin *get_iplugin_info(void);
96 96
97 gchar *wma_fmts[] = { "wma", NULL }; 97 gchar *ffmpeg_fmts[] = { "wma", NULL };
98 98
99 InputPlugin wma_ip = 99 InputPlugin ffmpeg_ip =
100 { 100 {
101 NULL, // Filled in by xmms 101 NULL, // Filled in by xmms
102 NULL, // Filled in by xmms 102 NULL, // Filled in by xmms
103 description, // The description that is shown in the preferences box 103 description, // The description that is shown in the preferences box
104 wma_init, // Called when the plugin is loaded 104 ffmpeg_init, // Called when the plugin is loaded
105 wma_about, // Show the about box 105 ffmpeg_about, // Show the about box
106 NULL, // Show the configure box 106 NULL, // Show the configure box
107 wma_is_our_file, // Return 1 if the plugin can handle the file 107 ffmpeg_is_our_file, // Return 1 if the plugin can handle the file
108 NULL, // Scan dir 108 NULL, // Scan dir
109 wma_play_file, // Play file 109 ffmpeg_play_file, // Play file
110 wma_stop, // Stop 110 ffmpeg_stop, // Stop
111 wma_do_pause, // Pause 111 ffmpeg_do_pause, // Pause
112 wma_seek, // Seek 112 ffmpeg_seek, // Seek
113 NULL, // Set the equalizer, most plugins won't be able to do this 113 NULL, // Set the equalizer, most plugins won't be able to do this
114 wma_get_time, // Get the time, usually returns the output plugins output time 114 ffmpeg_get_time, // Get the time, usually returns the output plugins output time
115 NULL, // Get volume 115 NULL, // Get volume
116 NULL, // Set volume 116 NULL, // Set volume
117 NULL, // OBSOLETE! 117 NULL, // OBSOLETE!
118 NULL, // OBSOLETE! 118 NULL, // OBSOLETE!
119 NULL, // Send data to the visualization plugins 119 NULL, // Send data to the visualization plugins
120 NULL, // Fill in the stuff that is shown in the player window 120 NULL, // Fill in the stuff that is shown in the player window
121 NULL, // Show some text in the song title box. Filled in by xmms 121 NULL, // Show some text in the song title box. Filled in by xmms
122 wma_get_song_info, // Function to grab the title string 122 ffmpeg_get_song_info, // Function to grab the title string
123 NULL, // Bring up an info window for the filename passed in 123 NULL, // Bring up an info window for the filename passed in
124 NULL, // Handle to the current output plugin. Filled in by xmms 124 NULL, // Handle to the current output plugin. Filled in by xmms
125 wma_get_song_tuple, // Tuple builder 125 ffmpeg_get_song_tuple, // Tuple builder
126 NULL, 126 NULL,
127 NULL, 127 NULL,
128 wma_is_our_fd, // vfs 128 ffmpeg_is_our_fd, // vfs
129 wma_fmts 129 ffmpeg_fmts
130 }; 130 };
131 131
132 InputPlugin *get_iplugin_info(void) 132 InputPlugin *get_iplugin_info(void)
133 { 133 {
134 memset(description, 0, 64); 134 memset(description, 0, 64);
135 wma_ip.description = g_strdup_printf(_("WMA Player %s"), PACKAGE_VERSION); 135 ffmpeg_ip.description = g_strdup_printf(_("WMA Player %s"), PACKAGE_VERSION);
136 return &wma_ip; 136 return &ffmpeg_ip;
137 } 137 }
138 138
139 static gchar *str_twenty_to_space(gchar * str) 139 static gchar *str_twenty_to_space(gchar * str)
140 { 140 {
141 gchar *match, *match_end; 141 gchar *match, *match_end;
151 } 151 }
152 152
153 return str; 153 return str;
154 } 154 }
155 155
156 static void wma_about(void) 156 static void ffmpeg_about(void)
157 { 157 {
158 char *title; 158 char *title;
159 char *message; 159 char *message;
160 160
161 if (dialog1) return; 161 if (dialog1) return;
190 gtk_widget_grab_focus(button1); 190 gtk_widget_grab_focus(button1);
191 g_free(title); 191 g_free(title);
192 g_free(message); 192 g_free(message);
193 } 193 }
194 194
195 static void wma_init(void) 195 static void ffmpeg_init(void)
196 { 196 {
197 avcodec_init(); 197 avcodec_init();
198 avcodec_register_all(); 198 avcodec_register_all();
199 av_register_all(); 199 av_register_all();
200 } 200 }
201 201
202 static int wma_is_our_file(char *filename) 202 static int ffmpeg_is_our_file(char *filename)
203 { 203 {
204 AVCodec *codec2; 204 AVCodec *codec2;
205 205
206 if(av_open_input_file(&ic2, str_twenty_to_space(filename), NULL, 0, NULL) < 0) return 0; 206 if(av_open_input_file(&ic2, str_twenty_to_space(filename), NULL, 0, NULL) < 0) return 0;
207 207
208 for(wma_idx2 = 0; wma_idx2 < ic2->nb_streams; wma_idx2++) { 208 for(ffmpeg_idx2 = 0; ffmpeg_idx2 < ic2->nb_streams; ffmpeg_idx2++) {
209 c2 = ic2->streams[wma_idx2]->codec; 209 c2 = ic2->streams[ffmpeg_idx2]->codec;
210 if(c2->codec_type == CODEC_TYPE_AUDIO) break; 210 if(c2->codec_type == CODEC_TYPE_AUDIO) break;
211 } 211 }
212 212
213 av_find_stream_info(ic2); 213 av_find_stream_info(ic2);
214 214
221 221
222 av_close_input_file(ic2); 222 av_close_input_file(ic2);
223 return 1; 223 return 1;
224 } 224 }
225 225
226 static int wma_is_our_fd(char *filename, VFSFile *fd) 226 static int ffmpeg_is_our_fd(char *filename, VFSFile *fd)
227 { 227 {
228 AVCodec *codec2; 228 AVCodec *codec2;
229 229
230 if(av_open_input_vfsfile(&ic2, filename, fd, NULL, 0, NULL) < 0) return 0; 230 if(av_open_input_vfsfile(&ic2, filename, fd, NULL, 0, NULL) < 0) return 0;
231 231
232 for(wma_idx2 = 0; wma_idx2 < ic2->nb_streams; wma_idx2++) { 232 for(ffmpeg_idx2 = 0; ffmpeg_idx2 < ic2->nb_streams; ffmpeg_idx2++) {
233 c2 = ic2->streams[wma_idx2]->codec; 233 c2 = ic2->streams[ffmpeg_idx2]->codec;
234 if(c2->codec_type == CODEC_TYPE_AUDIO) break; 234 if(c2->codec_type == CODEC_TYPE_AUDIO) break;
235 } 235 }
236 236
237 av_find_stream_info(ic2); 237 av_find_stream_info(ic2);
238 238
239 codec2 = avcodec_find_decoder(c2->codec_id); 239 codec2 = avcodec_find_decoder(c2->codec_id);
240 240
241 return 1; 241 return 1;
242 } 242 }
243 243
244 static void wma_do_pause(InputPlayback *playback, short p) 244 static void ffmpeg_do_pause(InputPlayback *playback, short p)
245 { 245 {
246 wma_pause = p; 246 ffmpeg_pause = p;
247 playback->output->pause(wma_pause); 247 playback->output->pause(ffmpeg_pause);
248 } 248 }
249 249
250 static void wma_seek(InputPlayback *playback, int time) 250 static void ffmpeg_seek(InputPlayback *playback, int time)
251 { 251 {
252 wma_seekpos = time; 252 ffmpeg_seekpos = time;
253 if(wma_pause) playback->output->pause(0); 253 if(ffmpeg_pause) playback->output->pause(0);
254 while(wma_decode && wma_seekpos!=-1) xmms_usleep(10000); 254 while(ffmpeg_decode && ffmpeg_seekpos!=-1) xmms_usleep(10000);
255 if(wma_pause) playback->output->pause(1); 255 if(ffmpeg_pause) playback->output->pause(1);
256 } 256 }
257 257
258 static int wma_get_time(InputPlayback *playback) 258 static int ffmpeg_get_time(InputPlayback *playback)
259 { 259 {
260 playback->output->buffer_free(); 260 playback->output->buffer_free();
261 if(wma_decode) return playback->output->output_time(); 261 if(ffmpeg_decode) return playback->output->output_time();
262 return -1; 262 return -1;
263 } 263 }
264 264
265 static gchar *extname(const char *filename) 265 static gchar *extname(const char *filename)
266 { 266 {
273 { 273 {
274 if(str && strlen(str) > 0) return g_strdup(str); 274 if(str && strlen(str) > 0) return g_strdup(str);
275 return NULL; 275 return NULL;
276 } 276 }
277 277
278 static TitleInput *wma_get_song_tuple(gchar * filename) 278 static TitleInput *ffmpeg_get_song_tuple(gchar * filename)
279 { 279 {
280 TitleInput *tuple = NULL; 280 TitleInput *tuple = NULL;
281 AVFormatContext *in = NULL; 281 AVFormatContext *in = NULL;
282 gchar *filename_proxy = g_strdup(filename); 282 gchar *filename_proxy = g_strdup(filename);
283 283
351 return in->duration/1000; 351 return in->duration/1000;
352 else 352 else
353 return 0; 353 return 0;
354 } 354 }
355 355
356 static void wma_get_song_info(char *filename, char **title_real, int *len_real) 356 static void ffmpeg_get_song_info(char *filename, char **title_real, int *len_real)
357 { 357 {
358 TitleInput *tuple = wma_get_song_tuple(filename); 358 TitleInput *tuple = ffmpeg_get_song_tuple(filename);
359 359
360 if (tuple == NULL) 360 if (tuple == NULL)
361 return; 361 return;
362 362
363 (*len_real) = tuple->length; 363 (*len_real) = tuple->length;
364 (*title_real) = xmms_get_titlestring(xmms_get_gentitle_format(), tuple); 364 (*title_real) = xmms_get_titlestring(xmms_get_gentitle_format(), tuple);
365 } 365 }
366 366
367 static void wma_playbuff(InputPlayback *playback, int out_size) 367 static void ffmpeg_playbuff(InputPlayback *playback, int out_size)
368 { 368 {
369 AVFifoBuffer f; 369 AVFifoBuffer f;
370 int sst_buff; 370 int sst_buff;
371 371
372 av_fifo_init(&f, out_size*2); 372 av_fifo_init(&f, out_size*2);
373 av_fifo_write(&f, wma_outbuf, out_size); 373 av_fifo_write(&f, ffmpeg_outbuf, out_size);
374 while(!av_fifo_read(&f, wma_s_outbuf, wma_st_buff) && wma_decode) 374 while(!av_fifo_read(&f, ffmpeg_s_outbuf, ffmpeg_st_buff) && ffmpeg_decode)
375 { 375 {
376 sst_buff = wma_st_buff; 376 sst_buff = ffmpeg_st_buff;
377 if(wma_pause) memset(wma_s_outbuf, 0, sst_buff); 377 if(ffmpeg_pause) memset(ffmpeg_s_outbuf, 0, sst_buff);
378 while(playback->output->buffer_free() < wma_st_buff) xmms_usleep(20000); 378 while(playback->output->buffer_free() < ffmpeg_st_buff) xmms_usleep(20000);
379 produce_audio(playback->output->written_time(), FMT_S16_NE, 379 produce_audio(playback->output->written_time(), FMT_S16_NE,
380 c->channels, sst_buff, (short *)wma_s_outbuf, NULL); 380 c->channels, sst_buff, (short *)ffmpeg_s_outbuf, NULL);
381 memset(wma_s_outbuf, 0, sst_buff); 381 memset(ffmpeg_s_outbuf, 0, sst_buff);
382 } 382 }
383 av_fifo_free(&f); 383 av_fifo_free(&f);
384 return; 384 return;
385 } 385 }
386 386
387 static void *wma_play_loop(void *arg) 387 static void *ffmpeg_play_loop(void *arg)
388 { 388 {
389 InputPlayback *playback = arg; 389 InputPlayback *playback = arg;
390 uint8_t *inbuf_ptr; 390 uint8_t *inbuf_ptr;
391 int out_size, size, len; 391 int out_size, size, len;
392 AVPacket pkt; 392 AVPacket pkt;
393 393
394 g_static_mutex_lock(&wma_mutex); 394 g_static_mutex_lock(&ffmpeg_mutex);
395 while(wma_decode){ 395 while(ffmpeg_decode){
396 396
397 if(wma_seekpos != -1) 397 if(ffmpeg_seekpos != -1)
398 { 398 {
399 av_seek_frame(ic, wma_idx, wma_seekpos * 1000000LL, 0); 399 av_seek_frame(ic, ffmpeg_idx, ffmpeg_seekpos * 1000000LL, 0);
400 playback->output->flush(wma_seekpos * 1000); 400 playback->output->flush(ffmpeg_seekpos * 1000);
401 wma_seekpos = -1; 401 ffmpeg_seekpos = -1;
402 } 402 }
403 403
404 if(av_read_frame(ic, &pkt) < 0) break; 404 if(av_read_frame(ic, &pkt) < 0) break;
405 405
406 size = pkt.size; 406 size = pkt.size;
407 inbuf_ptr = pkt.data; 407 inbuf_ptr = pkt.data;
408 408
409 if(size == 0) break; 409 if(size == 0) break;
410 410
411 while(size > 0){ 411 while(size > 0){
412 len = avcodec_decode_audio(c, (short *)wma_outbuf, &out_size, 412 len = avcodec_decode_audio(c, (short *)ffmpeg_outbuf, &out_size,
413 inbuf_ptr, size); 413 inbuf_ptr, size);
414 if(len < 0) break; 414 if(len < 0) break;
415 415
416 if(out_size <= 0) continue; 416 if(out_size <= 0) continue;
417 417
418 wma_playbuff(playback, out_size); 418 ffmpeg_playbuff(playback, out_size);
419 419
420 size -= len; 420 size -= len;
421 inbuf_ptr += len; 421 inbuf_ptr += len;
422 if(pkt.data) av_free_packet(&pkt); 422 if(pkt.data) av_free_packet(&pkt);
423 } 423 }
424 } 424 }
425 while(wma_decode && playback->output->buffer_playing()) xmms_usleep(30000); 425 while(ffmpeg_decode && playback->output->buffer_playing()) xmms_usleep(30000);
426 wma_decode = 0; 426 ffmpeg_decode = 0;
427 if(wma_s_outbuf) g_free(wma_s_outbuf); 427 if(ffmpeg_s_outbuf) g_free(ffmpeg_s_outbuf);
428 if(wma_outbuf) g_free(wma_outbuf); 428 if(ffmpeg_outbuf) g_free(ffmpeg_outbuf);
429 if(pkt.data) av_free_packet(&pkt); 429 if(pkt.data) av_free_packet(&pkt);
430 if(c) avcodec_close(c); 430 if(c) avcodec_close(c);
431 if(ic) av_close_input_file(ic); 431 if(ic) av_close_input_file(ic);
432 g_static_mutex_unlock(&wma_mutex); 432 g_static_mutex_unlock(&ffmpeg_mutex);
433 g_thread_exit(NULL); 433 g_thread_exit(NULL);
434 return(NULL); 434 return(NULL);
435 } 435 }
436 436
437 static void wma_play_file(InputPlayback *playback) 437 static void ffmpeg_play_file(InputPlayback *playback)
438 { 438 {
439 char *filename = playback->filename; 439 char *filename = playback->filename;
440 AVCodec *codec; 440 AVCodec *codec;
441 441
442 if(av_open_input_file(&ic, str_twenty_to_space(filename), NULL, 0, NULL) < 0) return; 442 if(av_open_input_file(&ic, str_twenty_to_space(filename), NULL, 0, NULL) < 0) return;
443 443
444 for(wma_idx = 0; wma_idx < ic->nb_streams; wma_idx++) { 444 for(ffmpeg_idx = 0; ffmpeg_idx < ic->nb_streams; ffmpeg_idx++) {
445 c = ic->streams[wma_idx]->codec; 445 c = ic->streams[ffmpeg_idx]->codec;
446 if(c->codec_type == CODEC_TYPE_AUDIO) break; 446 if(c->codec_type == CODEC_TYPE_AUDIO) break;
447 } 447 }
448 448
449 av_find_stream_info(ic); 449 av_find_stream_info(ic);
450 450
457 wsong_title = get_song_title(ic, filename); 457 wsong_title = get_song_title(ic, filename);
458 wsong_time = get_song_time(ic); 458 wsong_time = get_song_time(ic);
459 459
460 if(playback->output->open_audio(FMT_S16_NE, c->sample_rate, c->channels) <= 0) return; 460 if(playback->output->open_audio(FMT_S16_NE, c->sample_rate, c->channels) <= 0) return;
461 461
462 wma_st_buff = ST_BUFF; 462 ffmpeg_st_buff = ST_BUFF;
463 463
464 wma_ip.set_info(wsong_title, wsong_time, c->bit_rate, c->sample_rate, c->channels); 464 ffmpeg_ip.set_info(wsong_title, wsong_time, c->bit_rate, c->sample_rate, c->channels);
465 465
466 /* av_malloc() will wrap posix_memalign() if necessary -nenolod */ 466 /* av_malloc() will wrap posix_memalign() if necessary -nenolod */
467 wma_s_outbuf = av_malloc(wma_st_buff); 467 ffmpeg_s_outbuf = av_malloc(ffmpeg_st_buff);
468 wma_outbuf = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); 468 ffmpeg_outbuf = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
469 469
470 wma_seekpos = -1; 470 ffmpeg_seekpos = -1;
471 wma_decode = 1; 471 ffmpeg_decode = 1;
472 wma_decode_thread = g_thread_create((GThreadFunc)wma_play_loop, playback, TRUE, NULL); 472 ffmpeg_decode_thread = g_thread_create((GThreadFunc)ffmpeg_play_loop, playback, TRUE, NULL);
473 } 473 }
474 474
475 static void wma_stop(InputPlayback *playback) 475 static void ffmpeg_stop(InputPlayback *playback)
476 { 476 {
477 wma_decode = 0; 477 ffmpeg_decode = 0;
478 if(wma_pause) wma_do_pause(playback, 0); 478 if(ffmpeg_pause) ffmpeg_do_pause(playback, 0);
479 g_thread_join(wma_decode_thread); 479 g_thread_join(ffmpeg_decode_thread);
480 playback->output->close_audio(); 480 playback->output->close_audio();
481 } 481 }