Mercurial > audlegacy-plugins
diff src/madplug/decoder.c @ 611:3f7a52adfe0e trunk
[svn] merge recent changes from yaz's branch.
- stable shoutcast playback.
- tag handling improvement.
- view track detail on streaming won't crash. (disabled.)
- filepopup for streaming is partially supported. filepopup displays track name and stream name, but not updated automatically.
| author | yaz |
|---|---|
| date | Tue, 06 Feb 2007 12:11:42 -0800 |
| parents | 862190d39e00 |
| children | ca4cd00ca0c8 |
line wrap: on
line diff
--- a/src/madplug/decoder.c Mon Feb 05 12:28:01 2007 -0800 +++ b/src/madplug/decoder.c Tue Feb 06 12:11:42 2007 -0800 @@ -27,6 +27,7 @@ #include <audacious/plugin.h> #include <audacious/output.h> #include <audacious/util.h> +#include <sys/time.h> #include "plugin.h" #include "input.h" @@ -152,11 +153,11 @@ } } assert(pos == olen); - if (info->playback->playing == 0) + if (!info->playback->playing) return; - produce_audio(mad_plugin->output->written_time(), - FMT_S16_LE, MAD_NCHANNELS(header), olen, output, NULL); - if (info->playback->playing == 0) + produce_audio(info->playback->output->written_time(), + FMT_S16_LE, MAD_NCHANNELS(header), olen, output, &(info->playback->playing)); + if (!info->playback->playing) return; g_free(output); } @@ -245,11 +246,13 @@ } info->frames++; #ifdef DEBUG +#ifdef DEBUG_INTENSIVELY g_message("duration = %lu", mad_timer_count(header.duration, MAD_UNITS_MILLISECONDS)); g_message("size = %d", stream.next_frame - stream.this_frame); #endif +#endif mad_timer_add(&info->duration, header.duration); data_used += stream.next_frame - stream.this_frame; if (info->frames == 1) { @@ -301,7 +304,6 @@ if (fast && info->frames >= N_AVERAGE_FRAMES) { float frame_size = ((double) data_used) / N_AVERAGE_FRAMES; info->frames = (info->size - tagsize) / frame_size; - //int frame_frac = (info->size - tagsize) % frame_size; info->duration.seconds /= N_AVERAGE_FRAMES; info->duration.fraction /= N_AVERAGE_FRAMES; mad_timer_multiply(&info->duration, info->frames); @@ -309,7 +311,6 @@ g_message("using fast playtime calculation"); g_message("data used = %d [tagsize=%d framesize=%f]", data_used, tagsize, frame_size); - //g_message ("frame_size = %f [frac=%d]", frame_size, frame_frac); g_message("frames = %d, frequecy = %d, channels = %d", info->frames, info->freq, info->channels); long millis = mad_timer_count(info->duration, @@ -335,14 +336,15 @@ #ifdef DEBUG g_message("e: scan_file"); #endif /* DEBUG */ - return (info->frames != 0 || info->remote == TRUE); +// return info->frames != 0; + return (info->frames != 0 || info->remote == TRUE); // suspicious } gpointer decode_loop(gpointer arg) { unsigned char buffer[BUFFER_SIZE]; int len; - int seek_skip = 0; + gboolean seek_skip = FALSE; int remainder = 0; gint tlen; @@ -363,12 +365,20 @@ mad_stream_init(&stream); mad_synth_init(&synth); - if (!mad_plugin->output-> - open_audio(info->fmt, info->freq, info->channels)) { + if(!info->playback){ + g_print("decode: playback == NULL\n"); + return NULL; + } + + if (!info->playback->output->open_audio(info->fmt, info->freq, info->channels)) { + g_mutex_lock(pb_mutex); + info->playback->error = TRUE; + info->playback->eof = 1; + g_mutex_unlock(pb_mutex); audmad_error("failed to open audio output: %s", - mad_plugin->output->description); + info->playback->output->description); g_message("failed to open audio output: %s", - mad_plugin->output->description); + info->playback->output->description); return NULL; } @@ -378,6 +388,7 @@ info->title = xmms_get_titlestring(xmms_get_gentitle_format(), info->tuple); + tlen = (gint) mad_timer_count(info->duration, MAD_UNITS_MILLISECONDS), mad_plugin->set_info(info->title, @@ -386,7 +397,7 @@ /* main loop */ do { - if (info->playback->playing == 0) { + if (!info->playback->playing) { #ifdef DEBUG g_message("decode: stop signaled"); #endif /* DEBUG */ @@ -427,14 +438,19 @@ if (--skip == 0) mad_synth_frame(&synth, &frame); } - else if (!MAD_RECOVERABLE(stream.error)) + else if (!MAD_RECOVERABLE(stream.error)) { + g_mutex_lock(pb_mutex); + info->playback->error = TRUE; + info->playback->eof = 1; + g_mutex_unlock(pb_mutex); break; + } } while (skip); - seek_skip = 0; + seek_skip = FALSE; } - while (!info->playback->playing == 0) { + while (info->playback->playing) { if (info->seek != -1 && !info->remote) { #ifdef DEBUG g_message("seeking: %d", info->seek); @@ -448,6 +464,9 @@ mad_timer_set(&info->pos, info->seek, 0, 0); new_position = ((double) info->seek / (double) seconds) * info->size; + + if(new_position < 0) + new_position = 0; #ifdef DEBUG g_message("seeking to: %d bytes", new_position); #endif @@ -456,18 +475,17 @@ mad_frame_mute(&frame); mad_synth_mute(&synth); stream.error = MAD_ERROR_BUFLEN; - mad_plugin->output->flush(mad_timer_count - (info->pos, - MAD_UNITS_MILLISECONDS)); + info->playback->output->flush(mad_timer_count(info->pos, MAD_UNITS_MILLISECONDS)); stream.sync = 0; info->seek = -1; - seek_skip = 1; + seek_skip = TRUE; break; } if (mad_header_decode(&frame.header, &stream) == -1) { - if (!MAD_RECOVERABLE(stream.error)) + if (!MAD_RECOVERABLE(stream.error)) { break; + } if (stream.error == MAD_ERROR_LOSTSYNC) { /* ignore LOSTSYNC due to ID3 tags */ int tagsize = id3_tag_query(stream.this_frame, @@ -500,9 +518,7 @@ if (info->freq != frame.header.samplerate || info->channels != - (guint) MAD_NCHANNELS(&frame.header)) - { - tlen = mad_timer_count(info->duration, MAD_UNITS_MILLISECONDS); + (guint) MAD_NCHANNELS(&frame.header)) { #ifdef DEBUG g_message("re-opening audio due to change in audio type"); g_message("old: frequency = %d, channels = %d", info->freq, @@ -511,24 +527,24 @@ frame.header.samplerate, (guint) MAD_NCHANNELS(&frame.header)); #endif /* DEBUG */ - info->freq = frame.header.samplerate; info->channels = MAD_NCHANNELS(&frame.header); - mad_plugin->output->close_audio(); - if (!mad_plugin->output->open_audio(info->fmt, info->freq, + info->playback->output->close_audio(); + if (!info->playback->output->open_audio(info->fmt, info->freq, info->channels)) { + g_mutex_lock(pb_mutex); + info->playback->error = TRUE; + info->playback->eof = 1; + g_mutex_unlock(pb_mutex); audmad_error("failed to re-open audio output: %s", - mad_plugin->output->description); + info->playback->output->description); } - - mad_plugin->set_info(info->title, - tlen != 0 ? tlen : -1, - info->bitrate, info->freq, info->channels); } - if (info->playback->playing == 0) + if (!info->playback->playing) break; mad_synth_frame(&synth, &frame); mad_stream_sync(&stream); + write_output(info, &synth.pcm, &frame.header); mad_timer_add(&info->pos, frame.header.duration); } @@ -540,17 +556,30 @@ mad_stream_finish(&stream); mad_synth_finish(&synth); - if (!info->playback->playing == 0) { - mad_plugin->output->buffer_free(); - mad_plugin->output->buffer_free(); - while (mad_plugin->output->buffer_playing()) { + if (info->playback->playing) { + GTimeVal sleeptime; + + info->playback->output->buffer_free(); + info->playback->output->buffer_free(); + while (info->playback->output->buffer_playing()) { #ifdef DEBUG g_message("f: buffer_playing=%d", - mad_plugin->output->buffer_playing()); + info->playback->output->buffer_playing()); #endif - xmms_usleep(10000); - if (info->playback->playing == 0) + g_get_current_time(&sleeptime); + sleeptime.tv_usec += 500000; + if(sleeptime.tv_usec >= 1000000) { + sleeptime.tv_sec += 1; + sleeptime.tv_usec -= 1000000; + } + + g_mutex_lock(mad_mutex); + g_cond_timed_wait(mad_cond, mad_mutex, &sleeptime); + if (!info->playback->playing) { + g_mutex_unlock(mad_mutex); break; + } + g_mutex_unlock(mad_mutex); } } #ifdef DEBUG @@ -560,8 +589,10 @@ bmp_title_input_free(info->tuple); info->tuple = NULL; - mad_plugin->output->close_audio(); + info->playback->output->close_audio(); + g_mutex_lock(mad_mutex); info->playback->playing = 0; + g_mutex_unlock(mad_mutex); g_thread_exit(0); return NULL; /* dummy */ }
