aboutsummaryrefslogtreecommitdiffstats
path: root/src/inputPlugins
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2008-08-16 09:28:15 -0700
committerEric Wong <normalperson@yhbt.net>2008-08-16 09:39:32 -0700
commit44d9f62f34e0561d83ea32941f0ea1b529b1490d (patch)
tree5345eba046b6e3bcf8c063e7bae8b501b7a99f4a /src/inputPlugins
parentf9f70860622613686e6ac0bf7ebd448f437d92a7 (diff)
downloadmpd-44d9f62f34e0561d83ea32941f0ea1b529b1490d.tar.gz
mpd-44d9f62f34e0561d83ea32941f0ea1b529b1490d.tar.xz
mpd-44d9f62f34e0561d83ea32941f0ea1b529b1490d.zip
core rewrite (decode,player,outputBuffer,playlist)
This is a huge refactoring of the core mpd process. The queueing/buffering mechanism is heavily reworked. The player.c code has been merged into outputBuffer (the actual ring buffering logic is handled by ringbuf.c); and decode.c actually handles decoding stuff. The end result is several hundreds of lines shorter, even though we still have a lot of DEBUG statements left in there for tracing and a lot of assertions, too.
Diffstat (limited to 'src/inputPlugins')
-rw-r--r--src/inputPlugins/_flac_common.c11
-rw-r--r--src/inputPlugins/_flac_common.h16
-rw-r--r--src/inputPlugins/aac_plugin.c44
-rw-r--r--src/inputPlugins/audiofile_plugin.c46
-rw-r--r--src/inputPlugins/flac_plugin.c53
-rw-r--r--src/inputPlugins/mod_plugin.c30
-rw-r--r--src/inputPlugins/mp3_plugin.c146
-rw-r--r--src/inputPlugins/mp4_plugin.c55
-rw-r--r--src/inputPlugins/mpc_plugin.c59
-rw-r--r--src/inputPlugins/oggflac_plugin.c55
-rw-r--r--src/inputPlugins/oggvorbis_plugin.c59
-rw-r--r--src/inputPlugins/wavpack_plugin.c83
12 files changed, 275 insertions, 382 deletions
diff --git a/src/inputPlugins/_flac_common.c b/src/inputPlugins/_flac_common.c
index cf23a5e8c..3401a8b4f 100644
--- a/src/inputPlugins/_flac_common.c
+++ b/src/inputPlugins/_flac_common.c
@@ -166,11 +166,10 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
switch (block->type) {
case FLAC__METADATA_TYPE_STREAMINFO:
- dc.audioFormat.bits = (mpd_sint8)si->bits_per_sample;
- dc.audioFormat.sampleRate = si->sample_rate;
- dc.audioFormat.channels = (mpd_sint8)si->channels;
- dc.totalTime = ((float)si->total_samples) / (si->sample_rate);
- getOutputAudioFormat(&(dc.audioFormat), &(ob.audioFormat));
+ dc.audio_format.bits = (mpd_sint8)si->bits_per_sample;
+ dc.audio_format.sampleRate = si->sample_rate;
+ dc.audio_format.channels = (mpd_sint8)si->channels;
+ dc.total_time = ((float)si->total_samples) / (si->sample_rate);
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
flacParseReplayGain(block, data);
@@ -183,7 +182,7 @@ void flac_error_common_cb(const char *plugin,
const FLAC__StreamDecoderErrorStatus status,
FlacData * data)
{
- if (dc.stop)
+ if (dc_intr())
return;
switch (status) {
diff --git a/src/inputPlugins/_flac_common.h b/src/inputPlugins/_flac_common.h
index 10c2f3d38..5c147a064 100644
--- a/src/inputPlugins/_flac_common.h
+++ b/src/inputPlugins/_flac_common.h
@@ -165,17 +165,13 @@ MpdTag *copyVorbisCommentBlockToMpdTag(const FLAC__StreamMetadata * block,
MpdTag * tag);
/* keep this inlined, this is just macro but prettier :) */
-static inline int flacSendChunk(FlacData * data)
+static inline enum dc_action flacSendChunk(FlacData * data)
{
- if (ob_send(data->inStream,
- 1, data->chunk,
- data->chunk_length, data->time,
- data->bitRate,
- data->replayGainInfo) ==
- OUTPUT_BUFFER_DC_STOP)
- return -1;
-
- return 0;
+ enum dc_action ret = ob_send(data->chunk, data->chunk_length,
+ data->time, data->bitRate,
+ data->replayGainInfo);
+ data->chunk_length = 0;
+ return ret;
}
#endif /* HAVE_FLAC || HAVE_OGGFLAC */
diff --git a/src/inputPlugins/aac_plugin.c b/src/inputPlugins/aac_plugin.c
index 6e53c6420..98329a4b3 100644
--- a/src/inputPlugins/aac_plugin.c
+++ b/src/inputPlugins/aac_plugin.c
@@ -339,9 +339,8 @@ static int aac_decode(char *path)
return -1;
}
- dc.audioFormat.bits = 16;
-
- dc.totalTime = totalTime;
+ dc.audio_format.bits = 16;
+ dc.total_time = totalTime;
file_time = 0.0;
@@ -372,13 +371,8 @@ static int aac_decode(char *path)
sampleRate = frameInfo.samplerate;
#endif
- if (dc.state != DECODE_STATE_DECODE) {
- dc.audioFormat.channels = frameInfo.channels;
- dc.audioFormat.sampleRate = sampleRate;
- getOutputAudioFormat(&(dc.audioFormat),
- &(ob.audioFormat));
- dc.state = DECODE_STATE_DECODE;
- }
+ dc.audio_format.channels = frameInfo.channels;
+ dc.audio_format.sampleRate = sampleRate;
advanceAacBuffer(&b, frameInfo.bytesconsumed);
@@ -395,34 +389,24 @@ static int aac_decode(char *path)
sampleBufferLen = sampleCount * 2;
- ob_send(NULL, 0, sampleBuffer,
- sampleBufferLen, file_time,
- bitRate, NULL);
- if (dc.seek) {
- dc.seekError = 1;
- dc.seek = 0;
- decoder_wakeup_player();
- } else if (dc.stop) {
- eof = 1;
+ switch (ob_send(sampleBuffer, sampleBufferLen,
+ file_time, bitRate, NULL)) {
+ case DC_ACTION_NONE: break;
+ case DC_ACTION_SEEK:
+ /*
+ * this plugin doesn't support seek because nobody
+ * has bothered, yet...
+ */
+ dc_action_seek_fail(DC_SEEK_ERROR);
break;
+ default: eof = 1;
}
}
- ob_flush();
-
faacDecClose(decoder);
if (b.buffer)
free(b.buffer);
- if (dc.state != DECODE_STATE_DECODE)
- return -1;
-
- if (dc.seek) {
- dc.seekError = 1;
- dc.seek = 0;
- decoder_wakeup_player();
- }
-
return 0;
}
diff --git a/src/inputPlugins/audiofile_plugin.c b/src/inputPlugins/audiofile_plugin.c
index 558731dd3..8178972ff 100644
--- a/src/inputPlugins/audiofile_plugin.c
+++ b/src/inputPlugins/audiofile_plugin.c
@@ -67,42 +67,39 @@ static int audiofile_decode(char *path)
afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK,
AF_SAMPFMT_TWOSCOMP, 16);
afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
- dc.audioFormat.bits = (mpd_uint8)bits;
- dc.audioFormat.sampleRate =
+ dc.audio_format.bits = (mpd_uint8)bits;
+ dc.audio_format.sampleRate =
(unsigned int)afGetRate(af_fp, AF_DEFAULT_TRACK);
- dc.audioFormat.channels =
+ dc.audio_format.channels =
(mpd_uint8)afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK);
- getOutputAudioFormat(&(dc.audioFormat), &(ob.audioFormat));
frame_count = afGetFrameCount(af_fp, AF_DEFAULT_TRACK);
- dc.totalTime =
- ((float)frame_count / (float)dc.audioFormat.sampleRate);
+ dc.total_time = ((float)frame_count /
+ (float)dc.audio_format.sampleRate);
- bitRate = (mpd_uint16)(st.st_size * 8.0 / dc.totalTime / 1000.0 + 0.5);
+ bitRate = (mpd_uint16)(st.st_size * 8.0 / dc.total_time / 1000.0 + 0.5);
- if (dc.audioFormat.bits != 8 && dc.audioFormat.bits != 16) {
+ if (dc.audio_format.bits != 8 && dc.audio_format.bits != 16) {
ERROR("Only 8 and 16-bit files are supported. %s is %i-bit\n",
- path, dc.audioFormat.bits);
+ path, dc.audio_format.bits);
afCloseFile(af_fp);
return -1;
}
fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
- dc.state = DECODE_STATE_DECODE;
{
int ret, eof = 0, current = 0;
char chunk[CHUNK_SIZE];
while (!eof) {
- if (dc.seek) {
- ob_clear();
- current = dc.seekWhere *
- dc.audioFormat.sampleRate;
+ if (dc_seek()) {
+ dc_action_begin();
+ current = dc.seek_where *
+ dc.audio_format.sampleRate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
- dc.seek = 0;
- decoder_wakeup_player();
+ dc_action_end();
}
ret =
@@ -112,20 +109,15 @@ static int audiofile_decode(char *path)
eof = 1;
else {
current += ret;
- ob_send(NULL,
- 1,
- chunk,
- ret * fs,
- (float)current /
- (float)dc.audioFormat.
- sampleRate, bitRate,
- NULL);
- if (dc.stop)
+ ob_send(chunk, ret * fs,
+ (float)current /
+ (float)dc.audio_format.sampleRate,
+ bitRate,
+ NULL);
+ if (dc_intr())
break;
}
}
-
- ob_flush();
}
afCloseFile(af_fp);
diff --git a/src/inputPlugins/flac_plugin.c b/src/inputPlugins/flac_plugin.c
index 38131bac9..4a4ac627c 100644
--- a/src/inputPlugins/flac_plugin.c
+++ b/src/inputPlugins/flac_plugin.c
@@ -41,14 +41,14 @@ static flac_read_status flacRead(const flac_decoder * flacDec,
while (1) {
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
- if (r == 0 && !inputStreamAtEOF(data->inStream) && !dc.stop)
- my_usleep(10000);
+ if (r == 0 && !inputStreamAtEOF(data->inStream) && !dc_intr())
+ my_usleep(10000); /* FIXME */
else
break;
}
*bytes = r;
- if (r == 0 && !dc.stop) {
+ if (r == 0 && !dc_intr()) {
if (inputStreamAtEOF(data->inStream))
return flac_read_status_eof;
else
@@ -247,7 +247,7 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
FLAC__uint32 samples = frame->header.blocksize;
unsigned int c_samp;
const unsigned int num_channels = frame->header.channels;
- const unsigned int bytes_per_sample = (dc.audioFormat.bits / 8);
+ const unsigned int bytes_per_sample = (dc.audio_format.bits / 8);
const unsigned int bytes_per_channel =
bytes_per_sample * frame->header.channels;
const unsigned int max_samples = FLAC_CHUNK_SIZE / bytes_per_channel;
@@ -255,7 +255,7 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
float timeChange;
FLAC__uint64 newPosition = 0;
- assert(dc.audioFormat.bits > 0);
+ assert(dc.audio_format.bits > 0);
timeChange = ((float)samples) / frame->header.sample_rate;
data->time += timeChange;
@@ -286,14 +286,12 @@ static FLAC__StreamDecoderWriteStatus flacWrite(const flac_decoder *dec,
c_samp, c_samp + num_samples);
data->chunk_length = num_samples * bytes_per_channel;
- if (flacSendChunk(data) < 0) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- data->chunk_length = 0;
- if (dc.seek) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ switch (flacSendChunk(data)) {
+ case DC_ACTION_STOP:
+ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+ case DC_ACTION_SEEK:
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ default: break; /* compilers are complainers */
}
}
@@ -419,36 +417,35 @@ static int flac_decode_internal(InputStream * inStream, int is_ogg)
}
}
- dc.state = DECODE_STATE_DECODE;
-
while (1) {
if (!flac_process_single(flacDec))
break;
if (flac_get_state(flacDec) == flac_decoder_eof)
break;
- if (dc.seek) {
- FLAC__uint64 sampleToSeek = dc.seekWhere *
- dc.audioFormat.sampleRate + 0.5;
+ if (dc_seek()) {
+ FLAC__uint64 sampleToSeek;
+ dc_action_begin();
+ assert(dc.action == DC_ACTION_SEEK);
+ sampleToSeek = dc.seek_where *
+ dc.audio_format.sampleRate + 0.5;
if (flac_seek_absolute(flacDec, sampleToSeek)) {
- ob_clear();
data.time = ((float)sampleToSeek) /
- dc.audioFormat.sampleRate;
+ dc.audio_format.sampleRate;
data.position = 0;
- } else
- dc.seekError = 1;
- dc.seek = 0;
- decoder_wakeup_player();
+ data.chunk_length = 0;
+ } else {
+ dc.seek_where = DC_SEEK_ERROR;
+ }
+ dc_action_end();
}
}
- if (!dc.stop) {
+ if (!dc_intr()) {
flacPrintErroredState(flac_get_state(flacDec));
flac_finish(flacDec);
}
/* send last little bit */
- if (data.chunk_length > 0 && !dc.stop) {
+ if (data.chunk_length > 0 && !dc_intr())
flacSendChunk(&data);
- ob_flush();
- }
fail:
if (data.replayGainInfo)
diff --git a/src/inputPlugins/mod_plugin.c b/src/inputPlugins/mod_plugin.c
index 23b16fa23..cfa7d6e3d 100644
--- a/src/inputPlugins/mod_plugin.c
+++ b/src/inputPlugins/mod_plugin.c
@@ -179,25 +179,20 @@ static int mod_decode(char *path)
return -1;
}
- dc.totalTime = 0;
- dc.audioFormat.bits = 16;
- dc.audioFormat.sampleRate = 44100;
- dc.audioFormat.channels = 2;
- getOutputAudioFormat(&(dc.audioFormat), &(ob.audioFormat));
+ dc.total_time = 0;
+ dc.audio_format.bits = 16;
+ dc.audio_format.sampleRate = 44100;
+ dc.audio_format.channels = 2;
secPerByte =
- 1.0 / ((dc.audioFormat.bits * dc.audioFormat.channels / 8.0) *
- (float)dc.audioFormat.sampleRate);
+ 1.0 / ((dc.audio_format.bits * dc.audio_format.channels / 8.0) *
+ (float)dc.audio_format.sampleRate);
- dc.state = DECODE_STATE_DECODE;
while (1) {
- if (dc.seek) {
- dc.seekError = 1;
- dc.seek = 0;
- decoder_wakeup_player();
- }
+ if (dc_seek())
+ dc_action_seek_fail(DC_SEEK_ERROR);
- if (dc.stop)
+ if (dc_intr())
break;
if (!Player_Active())
@@ -205,13 +200,8 @@ static int mod_decode(char *path)
ret = VC_WriteBytes(data->audio_buffer, MIKMOD_FRAME_SIZE);
total_time += ret * secPerByte;
- ob_send(NULL, 0,
- (char *)data->audio_buffer, ret,
- total_time, 0, NULL);
+ ob_send((char *)data->audio_buffer, ret, total_time, 0, NULL);
}
-
- ob_flush();
-
mod_close(data);
MikMod_Exit();
diff --git a/src/inputPlugins/mp3_plugin.c b/src/inputPlugins/mp3_plugin.c
index dcfc25cdc..10a914a91 100644
--- a/src/inputPlugins/mp3_plugin.c
+++ b/src/inputPlugins/mp3_plugin.c
@@ -314,10 +314,8 @@ static void mp3_parseId3Tag(mp3DecodeData * data, size_t tagsize,
len = readFromInputStream(data->inStream,
allocated + count, (size_t) 1,
tagsize - count);
- if (len <= 0 && inputStreamAtEOF(data->inStream)) {
+ if (len <= 0 && inputStreamAtEOF(data->inStream))
break;
- } else if (len <= 0)
- my_usleep(10000);
else
count += len;
}
@@ -689,13 +687,13 @@ static int decodeFirstFrame(mp3DecodeData * data,
while (1) {
while ((ret = decodeNextFrameHeader(data, tag, replayGainInfo)) == DECODE_CONT &&
- !dc.stop);
- if (ret == DECODE_BREAK || dc.stop) return -1;
+ !dc_intr());
+ if (ret == DECODE_BREAK || dc_intr()) return -1;
if (ret == DECODE_SKIP) continue;
while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
- !dc.stop);
- if (ret == DECODE_BREAK || dc.stop) return -1;
+ !dc_intr());
+ if (ret == DECODE_BREAK || dc_intr()) return -1;
if (ret == DECODE_OK) break;
}
@@ -813,6 +811,35 @@ static int openMp3FromInputStream(InputStream * inStream, mp3DecodeData * data,
return 0;
}
+static float frame_time(mp3DecodeData * data, long j)
+{
+ return (((float)mad_timer_count(data->times[j],
+ MAD_UNITS_MILLISECONDS)) / 1000);
+}
+
+static void mp3Read_seek(mp3DecodeData * data)
+{
+ long j = 0;
+ data->muteFrame = MUTEFRAME_SEEK;
+
+ assert(pthread_equal(pthread_self(), dc.thread));
+ assert(dc.action == DC_ACTION_SEEK);
+
+ while (j < data->highestFrame && dc.seek_where > frame_time(data, j))
+ j++;
+ if (j < data->highestFrame) {
+ dc_action_begin();
+ if (seekMp3InputBuffer(data, data->frameOffset[j]) < 0) {
+ dc.seek_where = DC_SEEK_ERROR;
+ } else {
+ data->outputPtr = data->outputBuffer;
+ data->currentFrame = j;
+ }
+ data->muteFrame = 0;
+ dc_action_end();
+ }
+}
+
static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
{
int samplesPerFrame;
@@ -821,6 +848,8 @@ static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
int ret;
int skip;
+ assert(pthread_equal(pthread_self(), dc.thread));
+
if (data->currentFrame >= data->highestFrame) {
mad_timer_add(&data->timer, (data->frame).header.duration);
data->bitRate = (data->frame).header.bitrate;
@@ -851,13 +880,13 @@ static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
data->muteFrame = 0;
break;
case MUTEFRAME_SEEK:
- if (dc.seekWhere <= data->elapsedTime) {
+ dc_action_begin();
+ assert(dc.action == DC_ACTION_SEEK);
+ if (dc.seek_where <= data->elapsedTime) {
data->outputPtr = data->outputBuffer;
- ob_clear();
data->muteFrame = 0;
- dc.seek = 0;
- decoder_wakeup_player();
}
+ dc_action_end();
break;
default:
mad_synth_frame(&data->synth, &data->frame);
@@ -928,53 +957,33 @@ static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
}
if (data->outputPtr >= data->outputBufferEnd) {
- ret = ob_send(data->inStream,
- data->inStream->seekable,
- data->outputBuffer,
- data->outputPtr - data->outputBuffer,
- data->elapsedTime,
- data->bitRate / 1000,
- (replayGainInfo != NULL) ? *replayGainInfo : NULL);
- if (ret == OUTPUT_BUFFER_DC_STOP) {
+ enum dc_action action = ob_send(
+ data->outputBuffer,
+ data->outputPtr -
+ data->outputBuffer,
+ data->elapsedTime,
+ data->bitRate / 1000,
+ replayGainInfo ? *replayGainInfo
+ : NULL);
+
+ if (action == DC_ACTION_STOP) {
data->flush = 0;
return DECODE_BREAK;
}
-
data->outputPtr = data->outputBuffer;
- if (ret == OUTPUT_BUFFER_DC_SEEK)
+ if (action == DC_ACTION_SEEK)
break;
}
}
data->decodedFirstFrame = 1;
- if (dc.seek && data->inStream->seekable) {
- long j = 0;
- data->muteFrame = MUTEFRAME_SEEK;
- while (j < data->highestFrame && dc.seekWhere >
- ((float)mad_timer_count(data->times[j],
- MAD_UNITS_MILLISECONDS))
- / 1000) {
- j++;
- }
- if (j < data->highestFrame) {
- if (seekMp3InputBuffer(data,
- data->frameOffset[j]) ==
- 0) {
- data->outputPtr = data->outputBuffer;
- ob_clear();
- data->currentFrame = j;
- } else
- dc.seekError = 1;
- data->muteFrame = 0;
- dc.seek = 0;
- decoder_wakeup_player();
- }
- } else if (dc.seek && !data->inStream->seekable) {
- dc.seek = 0;
- dc.seekError = 1;
- decoder_wakeup_player();
+ if (dc_seek()) {
+ if (data->inStream->seekable)
+ mp3Read_seek(data);
+ else
+ dc_action_seek_fail(DC_SEEK_ERROR);
}
}
@@ -983,22 +992,22 @@ static int mp3Read(mp3DecodeData * data, ReplayGainInfo ** replayGainInfo)
while ((ret =
decodeNextFrameHeader(data, NULL,
replayGainInfo)) == DECODE_CONT
- && !dc.stop) ;
- if (ret == DECODE_BREAK || dc.stop || dc.seek)
+ && dc_intr()) ;
+ if (ret == DECODE_BREAK || dc_intr() || dc_seek())
break;
else if (ret == DECODE_SKIP)
skip = 1;
if (!data->muteFrame) {
while ((ret = decodeNextFrame(data)) == DECODE_CONT &&
- !dc.stop && !dc.seek) ;
- if (ret == DECODE_BREAK || dc.stop || dc.seek)
+ !dc_intr() && dc_seek()) ;
+ if (ret == DECODE_BREAK || dc_intr() || dc_seek())
break;
}
if (!skip && ret == DECODE_OK)
break;
}
- if (dc.stop)
+ if (dc_intr())
return DECODE_BREAK;
return ret;
@@ -1018,9 +1027,8 @@ static int mp3_decode(InputStream * inStream)
MpdTag *tag = NULL;
ReplayGainInfo *replayGainInfo = NULL;
- if (openMp3FromInputStream(inStream, &data, &tag, &replayGainInfo) <
- 0) {
- if (!dc.stop) {
+ if (openMp3FromInputStream(inStream, &data, &tag, &replayGainInfo) < 0) {
+ if (!dc_intr()) {
ERROR
("Input does not appear to be a mp3 bit stream.\n");
return -1;
@@ -1028,10 +1036,9 @@ static int mp3_decode(InputStream * inStream)
return 0;
}
- initAudioFormatFromMp3DecodeData(&data, &(dc.audioFormat));
- getOutputAudioFormat(&(dc.audioFormat), &(ob.audioFormat));
+ initAudioFormatFromMp3DecodeData(&data, &(dc.audio_format));
- dc.totalTime = data.totalTime;
+ dc.total_time = data.totalTime;
if (inStream->metaTitle) {
if (tag)
@@ -1058,31 +1065,16 @@ static int mp3_decode(InputStream * inStream)
freeMpdTag(tag);
}
- dc.state = DECODE_STATE_DECODE;
-
while (mp3Read(&data, &replayGainInfo) != DECODE_BREAK) ;
- /* send last little bit if not dc.stop */
- if (!dc.stop && data.outputPtr != data.outputBuffer && data.flush) {
- ob_send(NULL,
- data.inStream->seekable,
- data.outputBuffer,
- data.outputPtr - data.outputBuffer,
- data.elapsedTime, data.bitRate / 1000,
- replayGainInfo);
+ /* send last little bit if not dc_intr() */
+ if (!dc_intr() && data.outputPtr != data.outputBuffer && data.flush) {
+ ob_send(data.outputBuffer, data.outputPtr - data.outputBuffer,
+ data.elapsedTime, data.bitRate / 1000, replayGainInfo);
}
if (replayGainInfo)
freeReplayGainInfo(replayGainInfo);
-
- if (dc.seek && data.muteFrame == MUTEFRAME_SEEK) {
- ob_clear();
- dc.seek = 0;
- decoder_wakeup_player();
- }
-
- ob_flush();
mp3DecodeDataFinalize(&data);
-
return 0;
}
diff --git a/src/inputPlugins/mp4_plugin.c b/src/inputPlugins/mp4_plugin.c
index 7f13ca344..bf200c534 100644
--- a/src/inputPlugins/mp4_plugin.c
+++ b/src/inputPlugins/mp4_plugin.c
@@ -145,7 +145,7 @@ static int mp4_decode(InputStream * inStream)
#endif
faacDecSetConfiguration(decoder, config);
- dc.audioFormat.bits = 16;
+ dc.audio_format.bits = 16;
mp4Buffer = NULL;
mp4BufferSize = 0;
@@ -160,8 +160,8 @@ static int mp4_decode(InputStream * inStream)
return -1;
}
- dc.audioFormat.sampleRate = sampleRate;
- dc.audioFormat.channels = channels;
+ dc.audio_format.sampleRate = sampleRate;
+ dc.audio_format.channels = channels;
file_time = mp4ff_get_track_duration_use_offsets(mp4fh, track);
scale = mp4ff_time_scale(mp4fh, track);
@@ -175,7 +175,7 @@ static int mp4_decode(InputStream * inStream)
free(mp4cb);
return -1;
}
- dc.totalTime = ((float)file_time) / scale;
+ dc.total_time = ((float)file_time) / scale;
numSamples = mp4ff_num_samples(mp4fh, track);
@@ -184,13 +184,16 @@ static int mp4_decode(InputStream * inStream)
seekTable = xmalloc(sizeof(float) * numSamples);
for (sampleId = 0; sampleId < numSamples && !eof; sampleId++) {
- if (dc.seek)
+ if (!seeking && dc_seek()) {
+ dc_action_begin();
+ assert(dc.action == DC_ACTION_SEEK);
seeking = 1;
+ }
if (seeking && seekTableEnd > 1 &&
- seekTable[seekTableEnd] >= dc.seekWhere) {
+ seekTable[seekTableEnd] >= dc.seek_where) {
int i = 2;
- while (seekTable[i] < dc.seekWhere)
+ while (seekTable[i] < dc.seek_where)
i++;
sampleId = i - 1;
file_time = seekTable[sampleId];
@@ -212,15 +215,14 @@ static int mp4_decode(InputStream * inStream)
dur -= offset;
file_time += ((float)dur) / scale;
- if (seeking && file_time > dc.seekWhere)
+ if (seeking && file_time > dc.seek_where)
seekPositionFound = 1;
if (seeking && seekPositionFound) {
seekPositionFound = 0;
- ob_clear();
seeking = 0;
- dc.seek = 0;
- decoder_wakeup_player();
+ assert(dc.action == DC_ACTION_SEEK);
+ dc_action_end();
}
if (seeking)
@@ -247,17 +249,12 @@ static int mp4_decode(InputStream * inStream)
break;
}
- if (dc.state != DECODE_STATE_DECODE) {
- channels = frameInfo.channels;
+ channels = frameInfo.channels;
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
- scale = frameInfo.samplerate;
+ scale = frameInfo.samplerate;
#endif
- dc.audioFormat.sampleRate = scale;
- dc.audioFormat.channels = frameInfo.channels;
- getOutputAudioFormat(&(dc.audioFormat),
- &(ob.audioFormat));
- dc.state = DECODE_STATE_DECODE;
- }
+ dc.audio_format.sampleRate = scale;
+ dc.audio_format.channels = frameInfo.channels;
if (channels * (unsigned long)(dur + offset) > frameInfo.samples) {
dur = frameInfo.samples / channels;
@@ -277,10 +274,9 @@ static int mp4_decode(InputStream * inStream)
sampleBuffer += offset * channels * 2;
- ob_send(inStream, 1, sampleBuffer,
- sampleBufferLen, file_time,
- bitRate, NULL);
- if (dc.stop) {
+ ob_send(sampleBuffer, sampleBufferLen, file_time,
+ bitRate, NULL);
+ if (dc_intr()) {
eof = 1;
break;
}
@@ -291,15 +287,10 @@ static int mp4_decode(InputStream * inStream)
mp4ff_close(mp4fh);
free(mp4cb);
- if (dc.state != DECODE_STATE_DECODE)
- return -1;
-
- if (dc.seek && seeking) {
- ob_clear();
- dc.seek = 0;
- decoder_wakeup_player();
+ if (seeking) {
+ dc.seek_where = DC_SEEK_ERROR;
+ dc_action_end();
}
- ob_flush();
return 0;
}
diff --git a/src/inputPlugins/mpc_plugin.c b/src/inputPlugins/mpc_plugin.c
index 1003f15d5..116e471ff 100644
--- a/src/inputPlugins/mpc_plugin.c
+++ b/src/inputPlugins/mpc_plugin.c
@@ -42,8 +42,8 @@ static mpc_int32_t mpc_read_cb(void *vdata, void *ptr, mpc_int32_t size)
while (1) {
ret = readFromInputStream(data->inStream, ptr, 1, size);
- if (ret == 0 && !inputStreamAtEOF(data->inStream) && !dc.stop)
- my_usleep(10000);
+ if (ret == 0 && !inputStreamAtEOF(data->inStream) && !dc_intr())
+ my_usleep(10000); /* FIXME */
else
break;
}
@@ -147,7 +147,7 @@ static int mpc_decode(InputStream * inStream)
mpc_streaminfo_init(&info);
if ((ret = mpc_streaminfo_read(&info, &reader)) != ERROR_CODE_OK) {
- if (!dc.stop) {
+ if (!dc_intr()) {
ERROR("Not a valid musepack stream\n");
return -1;
}
@@ -157,20 +157,18 @@ static int mpc_decode(InputStream * inStream)
mpc_decoder_setup(&decoder, &reader);
if (!mpc_decoder_initialize(&decoder, &info)) {
- if (!dc.stop) {
+ if (!dc_intr()) {
ERROR("Not a valid musepack stream\n");
return -1;
}
return 0;
}
- dc.totalTime = mpc_streaminfo_get_length(&info);
+ dc.total_time = mpc_streaminfo_get_length(&info);
- dc.audioFormat.bits = 16;
- dc.audioFormat.channels = info.channels;
- dc.audioFormat.sampleRate = info.sample_freq;
-
- getOutputAudioFormat(&(dc.audioFormat), &(ob.audioFormat));
+ dc.audio_format.bits = 16;
+ dc.audio_format.channels = info.channels;
+ dc.audio_format.sampleRate = info.sample_freq;
replayGainInfo = newReplayGainInfo();
replayGainInfo->albumGain = info.gain_album * 0.01;
@@ -178,19 +176,16 @@ static int mpc_decode(InputStream * inStream)
replayGainInfo->trackGain = info.gain_title * 0.01;
replayGainInfo->trackPeak = info.peak_title / 32767.0;
- dc.state = DECODE_STATE_DECODE;
-
while (!eof) {
- if (dc.seek) {
- samplePos = dc.seekWhere * dc.audioFormat.sampleRate;
+ if (dc_seek()) {
+ dc_action_begin();
+ samplePos = dc.seek_where * dc.audio_format.sampleRate;
if (mpc_decoder_seek_sample(&decoder, samplePos)) {
- ob_clear();
s16 = (mpd_sint16 *) chunk;
chunkpos = 0;
} else
- dc.seekError = 1;
- dc.seek = 0;
- decoder_wakeup_player();
+ dc.seek_where = DC_SEEK_ERROR;
+ dc_action_end();
}
vbrUpdateAcc = 0;
@@ -198,7 +193,7 @@ static int mpc_decode(InputStream * inStream)
ret = mpc_decoder_decode(&decoder, sample_buffer,
&vbrUpdateAcc, &vbrUpdateBits);
- if (ret <= 0 || dc.stop) {
+ if (ret <= 0 || dc_intr()) {
eof = 1;
break;
}
@@ -216,20 +211,17 @@ static int mpc_decode(InputStream * inStream)
if (chunkpos >= MPC_CHUNK_SIZE) {
total_time = ((float)samplePos) /
- dc.audioFormat.sampleRate;
+ dc.audio_format.sampleRate;
bitRate = vbrUpdateBits *
- dc.audioFormat.sampleRate / 1152 / 1000;
+ dc.audio_format.sampleRate / 1152 / 1000;
- ob_send(inStream,
- inStream->seekable,
- chunk, chunkpos,
- total_time,
- bitRate, replayGainInfo);
+ ob_send(chunk, chunkpos, total_time,
+ bitRate, replayGainInfo);
chunkpos = 0;
s16 = (mpd_sint16 *) chunk;
- if (dc.stop) {
+ if (dc_intr()) {
eof = 1;
break;
}
@@ -237,19 +229,14 @@ static int mpc_decode(InputStream * inStream)
}
}
- if (!dc.stop && chunkpos > 0) {
- total_time = ((float)samplePos) / dc.audioFormat.sampleRate;
+ if (!dc_intr() && chunkpos > 0) {
+ total_time = ((float)samplePos) / dc.audio_format.sampleRate;
bitRate =
- vbrUpdateBits * dc.audioFormat.sampleRate / 1152 / 1000;
+ vbrUpdateBits * dc.audio_format.sampleRate / 1152 / 1000;
- ob_send(NULL, inStream->seekable,
- chunk, chunkpos, total_time, bitRate,
- replayGainInfo);
+ ob_send(chunk, chunkpos, total_time, bitRate, replayGainInfo);
}
-
- ob_flush();
-
freeReplayGainInfo(replayGainInfo);
return 0;
diff --git a/src/inputPlugins/oggflac_plugin.c b/src/inputPlugins/oggflac_plugin.c
index 379ff6466..6c5998afe 100644
--- a/src/inputPlugins/oggflac_plugin.c
+++ b/src/inputPlugins/oggflac_plugin.c
@@ -55,15 +55,14 @@ static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(const
while (1) {
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
- if (r == 0 && !inputStreamAtEOF(data->inStream) &&
- !dc.stop)
- my_usleep(10000);
+ if (r == 0 && !inputStreamAtEOF(data->inStream) && !dc_intr())
+ my_usleep(10000); /* FIXME */
else
break;
}
*bytes = r;
- if (r == 0 && !inputStreamAtEOF(data->inStream) && !dc.stop)
+ if (r == 0 && !inputStreamAtEOF(data->inStream) && !dc_intr())
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
return OggFLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
@@ -193,16 +192,17 @@ static FLAC__StreamDecoderWriteStatus oggflacWrite(const
c_chan++) {
u16 = buf[c_chan][c_samp];
uc = (unsigned char *)&u16;
- for (i = 0; i < (dc.audioFormat.bits / 8); i++) {
+ for (i = 0; i < (dc.audio_format.bits / 8); i++) {
if (data->chunk_length >= FLAC_CHUNK_SIZE) {
- if (flacSendChunk(data) < 0) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
- }
- data->chunk_length = 0;
- if (dc.seek) {
- return
- FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ /* FIXME: line wrapping */
+ switch (flacSendChunk(data)) {
+ case DC_ACTION_STOP:
+ return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
+ case DC_ACTION_SEEK:
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ default:
+ /* compilers are complainers */
+ break;
}
}
data->chunk[data->chunk_length++] = *(uc++);
@@ -349,40 +349,39 @@ static int oggflac_decode(InputStream * inStream)
goto fail;
}
- dc.state = DECODE_STATE_DECODE;
-
while (1) {
OggFLAC__seekable_stream_decoder_process_single(decoder);
if (OggFLAC__seekable_stream_decoder_get_state(decoder) !=
OggFLAC__SEEKABLE_STREAM_DECODER_OK) {
break;
}
- if (dc.seek) {
- FLAC__uint64 sampleToSeek = dc.seekWhere *
- dc.audioFormat.sampleRate + 0.5;
+ if (dc_seek()) {
+ FLAC__uint64 sampleToSeek;
+ dc_action_begin();
+ assert(dc.action == DC_ACTION_SEEK);
+ sampleToSeek = dc.seek_where *
+ dc.audio_format.sampleRate + 0.5;
if (OggFLAC__seekable_stream_decoder_seek_absolute
(decoder, sampleToSeek)) {
- ob_clear();
data.time = ((float)sampleToSeek) /
- dc.audioFormat.sampleRate;
+ dc.audio_format.sampleRate;
data.position = 0;
- } else
- dc.seekError = 1;
- dc.seek = 0;
- decoder_wakeup_player();
+ data.chunk_length = 0;
+ } else {
+ dc.seek_where = DC_SEEK_ERROR;
+ }
+ dc_action_end();
}
}
- if (!dc.stop) {
+ if (!dc_intr()) {
oggflacPrintErroredState
(OggFLAC__seekable_stream_decoder_get_state(decoder));
OggFLAC__seekable_stream_decoder_finish(decoder);
}
/* send last little bit */
- if (data.chunk_length > 0 && !dc.stop) {
+ if (data.chunk_length > 0 && !dc_intr())
flacSendChunk(&data);
- ob_flush();
- }
fail:
oggflac_cleanup(&data, decoder);
diff --git a/src/inputPlugins/oggvorbis_plugin.c b/src/inputPlugins/oggvorbis_plugin.c
index 16040b388..fcedda54a 100644
--- a/src/inputPlugins/oggvorbis_plugin.c
+++ b/src/inputPlugins/oggvorbis_plugin.c
@@ -66,8 +66,8 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
while (1) {
ret = readFromInputStream(data->inStream, ptr, size, nmemb);
if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
- !dc.stop) {
- my_usleep(10000);
+ !dc_intr()) {
+ my_usleep(10000); /* FIXME */
} else
break;
}
@@ -80,7 +80,7 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
static int ogg_seek_cb(void *vdata, ogg_int64_t offset, int whence)
{
const OggCallbackData *data = (const OggCallbackData *) vdata;
- if (dc.stop)
+ if (dc_intr())
return -1;
return seekInputStream(data->inStream, offset, whence);
}
@@ -240,7 +240,7 @@ static int oggvorbis_decode(InputStream * inStream)
callbacks.close_func = ogg_close_cb;
callbacks.tell_func = ogg_tell_cb;
if ((ret = ov_open_callbacks(&data, &vf, NULL, 0, callbacks)) < 0) {
- if (!dc.stop) {
+ if (!dc_intr()) {
switch (ret) {
case OV_EREAD:
errorStr = "read error";
@@ -267,20 +267,19 @@ static int oggvorbis_decode(InputStream * inStream)
}
return 0;
}
- dc.totalTime = ov_time_total(&vf, -1);
- if (dc.totalTime < 0)
- dc.totalTime = 0;
- dc.audioFormat.bits = 16;
+ dc.total_time = ov_time_total(&vf, -1);
+ if (dc.total_time < 0)
+ dc.total_time = 0;
+ dc.audio_format.bits = 16;
while (1) {
- if (dc.seek) {
- if (0 == ov_time_seek_page(&vf, dc.seekWhere)) {
- ob_clear();
+ if (dc_seek()) {
+ dc_action_begin();
+ if (0 == ov_time_seek_page(&vf, dc.seek_where))
chunkpos = 0;
- } else
- dc.seekError = 1;
- dc.seek = 0;
- decoder_wakeup_player();
+ else
+ dc.seek_where = DC_SEEK_ERROR;
+ dc_action_end();
}
ret = ov_read(&vf, chunk + chunkpos,
OGG_CHUNK_SIZE - chunkpos,
@@ -288,13 +287,8 @@ static int oggvorbis_decode(InputStream * inStream)
if (current_section != prev_section) {
/*printf("new song!\n"); */
vorbis_info *vi = ov_info(&vf, -1);
- dc.audioFormat.channels = vi->channels;
- dc.audioFormat.sampleRate = vi->rate;
- if (dc.state == DECODE_STATE_START) {
- getOutputAudioFormat(&(dc.audioFormat),
- &(ob.audioFormat));
- dc.state = DECODE_STATE_DECODE;
- }
+ dc.audio_format.channels = vi->channels;
+ dc.audio_format.sampleRate = vi->rate;
comments = ov_comment(&vf, -1)->user_comments;
putOggCommentsIntoOutputBuffer(inStream->metaName,
comments);
@@ -316,23 +310,18 @@ static int oggvorbis_decode(InputStream * inStream)
if ((test = ov_bitrate_instant(&vf)) > 0) {
bitRate = test / 1000;
}
- ob_send(inStream,
- inStream->seekable,
- chunk, chunkpos,
- ov_pcm_tell(&vf) /
- dc.audioFormat.sampleRate,
- bitRate, replayGainInfo);
+ ob_send(chunk, chunkpos,
+ ov_pcm_tell(&vf) / dc.audio_format.sampleRate,
+ bitRate, replayGainInfo);
chunkpos = 0;
- if (dc.stop)
+ if (dc_intr())
break;
}
}
- if (!dc.stop && chunkpos > 0) {
- ob_send(NULL, inStream->seekable,
- chunk, chunkpos,
- ov_time_tell(&vf), bitRate,
- replayGainInfo);
+ if (!dc_intr() && chunkpos > 0) {
+ ob_send(chunk, chunkpos, ov_time_tell(&vf), bitRate,
+ replayGainInfo);
}
if (replayGainInfo)
@@ -340,8 +329,6 @@ static int oggvorbis_decode(InputStream * inStream)
ov_clear(&vf);
- ob_flush();
-
return 0;
}
diff --git a/src/inputPlugins/wavpack_plugin.c b/src/inputPlugins/wavpack_plugin.c
index 7a7145141..ef02712d7 100644
--- a/src/inputPlugins/wavpack_plugin.c
+++ b/src/inputPlugins/wavpack_plugin.c
@@ -139,12 +139,12 @@ static void wavpack_decode(WavpackContext *wpc, int canseek,
int position, outsamplesize;
int Bps;
- dc.audioFormat.sampleRate = WavpackGetSampleRate(wpc);
- dc.audioFormat.channels = WavpackGetReducedChannels(wpc);
- dc.audioFormat.bits = WavpackGetBitsPerSample(wpc);
+ dc.audio_format.sampleRate = WavpackGetSampleRate(wpc);
+ dc.audio_format.channels = WavpackGetReducedChannels(wpc);
+ dc.audio_format.bits = WavpackGetBitsPerSample(wpc);
- if (dc.audioFormat.bits > 16)
- dc.audioFormat.bits = 16;
+ if (dc.audio_format.bits > 16)
+ dc.audio_format.bits = 16;
if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT)
format_samples = format_samples_float;
@@ -162,40 +162,33 @@ static void wavpack_decode(WavpackContext *wpc, int canseek,
outsamplesize = Bps;
if (outsamplesize > 2)
outsamplesize = 2;
- outsamplesize *= dc.audioFormat.channels;
+ outsamplesize *= dc.audio_format.channels;
- samplesreq = sizeof(chunk) / (4 * dc.audioFormat.channels);
+ samplesreq = sizeof(chunk) / (4 * dc.audio_format.channels);
- getOutputAudioFormat(&(dc.audioFormat), &(ob.audioFormat));
-
- dc.totalTime = (float)allsamples / dc.audioFormat.sampleRate;
- dc.state = DECODE_STATE_DECODE;
- dc.seekable = canseek;
+ dc.total_time = (float)allsamples / dc.audio_format.sampleRate;
position = 0;
do {
- if (dc.seek) {
+ if (dc_seek()) {
+ dc_action_begin();
+ assert(dc.action == DC_ACTION_SEEK);
if (canseek) {
int where;
-
- ob_clear();
-
- where = dc.seekWhere *
- dc.audioFormat.sampleRate;
+ where = dc.seek_where *
+ dc.audio_format.sampleRate;
if (WavpackSeekSample(wpc, where))
position = where;
else
- dc.seekError = 1;
+ dc.seek_where = DC_SEEK_ERROR;
} else {
- dc.seekError = 1;
+ dc.seek_where = DC_SEEK_ERROR;
}
-
- dc.seek = 0;
- decoder_wakeup_player();
+ dc_action_end();
}
- if (dc.stop)
+ if (dc_intr())
break;
samplesgot = WavpackUnpackSamples(wpc,
@@ -205,19 +198,15 @@ static void wavpack_decode(WavpackContext *wpc, int canseek,
1000 + 0.5);
position += samplesgot;
file_time = (float)position /
- dc.audioFormat.sampleRate;
+ dc.audio_format.sampleRate;
format_samples(Bps, chunk,
- samplesgot * dc.audioFormat.channels);
+ samplesgot * dc.audio_format.channels);
- ob_send(NULL, 0, chunk,
- samplesgot * outsamplesize,
- file_time, bitrate,
- replayGainInfo);
+ ob_send(chunk, samplesgot * outsamplesize,
+ file_time, bitrate, replayGainInfo);
}
} while (samplesgot == samplesreq);
-
- ob_flush();
}
static char *wavpack_tag(WavpackContext *wpc, char *key)
@@ -398,6 +387,7 @@ static int can_seek(void *id)
return ((InputStreamPlus *)id)->is->seekable;
}
+/* FIXME: remove C99 initializers */
static WavpackStreamReader mpd_is_reader = {
.read_bytes = read_bytes,
.get_pos = get_pos,
@@ -453,38 +443,27 @@ static int wavpack_streamdecode(InputStream *is)
int canseek;
/* Try to find wvc */
+ /* wvc being the "correction" file to supplement the original .wv */
do {
char tmp[MPD_PATH_MAX];
const char *utf8url;
size_t len;
err = 1;
- /*
- * As we use dc.utf8url, this function will be bad for
- * single files. utf8url is not absolute file path :/
- */
- utf8url = get_song_url(tmp, dc.current_song);
- if (utf8url == NULL) {
- break;
- }
-
- len = strlen(utf8url);
- if (!len) {
+ /* This is the only reader of dc.current_song */
+ if (!(utf8url = get_song_url(tmp, dc.current_song)))
break;
- }
- wvc_url = (char *)xmalloc(len + 2); /* +2: 'c' and EOS */
- if (wvc_url == NULL) {
+ if (!(len = strlen(utf8url)))
break;
- }
+ wvc_url = (char *)xmalloc(len + sizeof("c"));
memcpy(wvc_url, utf8url, len);
wvc_url[len] = 'c';
wvc_url[len + 1] = '\0';
- if (openInputStream(&is_wvc, wvc_url)) {
+ if (openInputStream(&is_wvc, wvc_url))
break;
- }
/*
* And we try to buffer in order to get know
@@ -500,17 +479,17 @@ static int wavpack_streamdecode(InputStream *is)
break;
}
+ /* FIXME: replace with future "peek" function */
if (bufferInputStream(&is_wvc) >= 0) {
err = 0;
break;
}
- if (dc.stop) {
+ if (dc_intr())
break;
- }
/* Save some CPU */
- my_usleep(1000);
+ my_usleep(1000); /* FIXME: remove */
}
if (err) {
closeInputStream(&is_wvc);