added decoder_read()

On our way to stabilize the decoder API, we will one day remove the
input stream functions.  The most basic function, read() will be
provided by decoder_api.h with this patch.  It already contains a loop
(still with manual polling), error/eof handling and decoder command
checks.  This kind of code used to be duplicated in all decoder
plugins.
This commit is contained in:
Max Kellermann 2008-08-26 08:27:14 +02:00
parent d80260ab4e
commit 940ecf5345
10 changed files with 50 additions and 66 deletions

View File

@ -89,6 +89,30 @@ void decoder_seek_error(struct decoder * decoder)
decoder_command_finished(decoder);
}
size_t decoder_read(struct decoder *decoder,
InputStream *inStream,
void *buffer, size_t length)
{
size_t nbytes;
assert(inStream != NULL);
assert(buffer != NULL);
while (1) {
/* XXX don't allow decoder==NULL */
if (decoder != NULL && dc.command != DECODE_COMMAND_NONE)
return 0;
nbytes = readFromInputStream(inStream, buffer, 1, length);
if (nbytes > 0 || inputStreamAtEOF(inStream))
return nbytes;
/* sleep for a fraction of a second! */
/* XXX don't sleep, wait for an event instead */
my_usleep(10000);
}
}
/**
* All chunks are full of decoded data; wait for the player to free
* one.

View File

@ -121,6 +121,15 @@ double decoder_seek_where(struct decoder * decoder);
void decoder_seek_error(struct decoder * decoder);
/**
* Blocking read from the input stream. Returns the number of bytes
* read, or 0 if one of the following occurs: end of file; error;
* command (like SEEK or STOP).
*/
size_t decoder_read(struct decoder *decoder,
InputStream *inStream,
void *buffer, size_t length);
/**
* This function is called by the decoder plugin when it has
* successfully decoded block of input data.

View File

@ -37,15 +37,7 @@ ogg_stream_type ogg_stream_type_detect(InputStream * inStream)
seekInputStream(inStream, 0, SEEK_SET);
while (1) {
r = readFromInputStream(inStream, buf, 1, sizeof(buf));
if (inStream->error)
break;
if (!r && !inputStreamAtEOF(inStream))
my_usleep(10000);
else
break;
}
r = decoder_read(NULL, inStream, buf, sizeof(buf));
if (r > 0)
seekInputStream(inStream, 0, SEEK_SET);

View File

@ -65,11 +65,9 @@ static void fillAacBuffer(AacBuffer * b)
size_t rest = FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS -
b->bytesIntoBuffer;
bread = readFromInputStream(b->inStream,
(void *)(b->buffer +
b->
bytesIntoBuffer),
1, rest);
bread = decoder_read(b->decoder, b->inStream,
(void *)(b->buffer + b->bytesIntoBuffer),
rest);
if (bread == 0 && inputStreamAtEOF(b->inStream))
b->atEof = 1;
b->bytesIntoBuffer += bread;

View File

@ -33,14 +33,7 @@ static flac_read_status flacRead(mpd_unused const flac_decoder * flacDec,
FlacData *data = (FlacData *) fdata;
size_t r;
while (1) {
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
if (r == 0 && !inputStreamAtEOF(data->inStream) &&
decoder_get_command(data->decoder) != DECODE_COMMAND_STOP)
my_usleep(10000);
else
break;
}
r = decoder_read(data->decoder, data->inStream, (void *)buf, *bytes);
*bytes = r;
if (r == 0 && decoder_get_command(data->decoder) != DECODE_COMMAND_STOP) {

View File

@ -233,15 +233,10 @@ static int fillMp3InputBuffer(mp3DecodeData * data)
if (readSize == 0)
return -1;
readed = readFromInputStream(data->inStream, readStart, (size_t) 1,
readSize);
if (readed <= 0 && inputStreamAtEOF(data->inStream))
readed = decoder_read(data->decoder, data->inStream,
readStart, readSize);
if (readed == 0)
return -1;
/* sleep for a fraction of a second! */
else if (readed <= 0) {
readed = 0;
my_usleep(10000);
}
mad_stream_buffer(&data->stream, data->readBuffer, readed + remaining);
(data->stream).error = 0;
@ -324,13 +319,10 @@ static void mp3_parseId3Tag(mp3DecodeData * data, size_t tagsize,
while (count < tagsize) {
size_t len;
len = readFromInputStream(data->inStream,
allocated + count, (size_t) 1,
tagsize - count);
if (len <= 0 && inputStreamAtEOF(data->inStream)) {
len = decoder_read(data->decoder, data->inStream,
allocated + count, tagsize - count);
if (len == 0)
break;
} else if (len <= 0)
my_usleep(10000);
else
count += len;
}

View File

@ -32,20 +32,9 @@ typedef struct _MpcCallbackData {
static mpc_int32_t mpc_read_cb(void *vdata, void *ptr, mpc_int32_t size)
{
mpc_int32_t ret = 0;
MpcCallbackData *data = (MpcCallbackData *) vdata;
while (1) {
ret = readFromInputStream(data->inStream, ptr, 1, size);
if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
(data->decoder &&
decoder_get_command(data->decoder) != DECODE_COMMAND_STOP))
my_usleep(10000);
else
break;
}
return ret;
return decoder_read(data->decoder, data->inStream, ptr, size);
}
static mpc_bool_t mpc_seek_cb(void *vdata, mpc_int32_t offset)

View File

@ -47,14 +47,7 @@ static OggFLAC__SeekableStreamDecoderReadStatus of_read_cb(const
FlacData *data = (FlacData *) fdata;
size_t r;
while (1) {
r = readFromInputStream(data->inStream, (void *)buf, 1, *bytes);
if (r == 0 && !inputStreamAtEOF(data->inStream) &&
decoder_get_command(data->decoder) != DECODE_COMMAND_STOP)
my_usleep(10000);
else
break;
}
r = decoder_read(data->decoder, data->inStream, (void *)buf, *bytes);
*bytes = r;
if (r == 0 && !inputStreamAtEOF(data->inStream) &&

View File

@ -58,18 +58,12 @@ static size_t ogg_read_cb(void *ptr, size_t size, size_t nmemb, void *vdata)
size_t ret;
OggCallbackData *data = (OggCallbackData *) vdata;
while (1) {
ret = readFromInputStream(data->inStream, ptr, size, nmemb);
if (ret == 0 && !inputStreamAtEOF(data->inStream) &&
decoder_get_command(data->decoder) != DECODE_COMMAND_STOP) {
my_usleep(10000);
} else
break;
}
ret = decoder_read(data->decoder, data->inStream, ptr, size * nmemb);
errno = 0;
/*if(ret<0) errno = ((InputStream *)inStream)->error; */
return ret;
return ret / size;
}
static int ogg_seek_cb(void *vdata, ogg_int64_t offset, int whence)

View File

@ -358,7 +358,7 @@ static int32_t read_bytes(void *id, void *data, int32_t bcount)
--bcount;
++i;
}
return i + readFromInputStream(isp->is, buf, 1, bcount);
return i + decoder_read(isp->decoder, isp->is, buf, bcount);
}
static uint32_t get_pos(void *id)