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); 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 * All chunks are full of decoded data; wait for the player to free
* one. * one.

View File

@ -121,6 +121,15 @@ double decoder_seek_where(struct decoder * decoder);
void decoder_seek_error(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 * This function is called by the decoder plugin when it has
* successfully decoded block of input data. * 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); seekInputStream(inStream, 0, SEEK_SET);
while (1) { r = decoder_read(NULL, inStream, buf, sizeof(buf));
r = readFromInputStream(inStream, buf, 1, sizeof(buf));
if (inStream->error)
break;
if (!r && !inputStreamAtEOF(inStream))
my_usleep(10000);
else
break;
}
if (r > 0) if (r > 0)
seekInputStream(inStream, 0, SEEK_SET); 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 - size_t rest = FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS -
b->bytesIntoBuffer; b->bytesIntoBuffer;
bread = readFromInputStream(b->inStream, bread = decoder_read(b->decoder, b->inStream,
(void *)(b->buffer + (void *)(b->buffer + b->bytesIntoBuffer),
b-> rest);
bytesIntoBuffer),
1, rest);
if (bread == 0 && inputStreamAtEOF(b->inStream)) if (bread == 0 && inputStreamAtEOF(b->inStream))
b->atEof = 1; b->atEof = 1;
b->bytesIntoBuffer += bread; b->bytesIntoBuffer += bread;

View File

@ -33,14 +33,7 @@ static flac_read_status flacRead(mpd_unused const flac_decoder * flacDec,
FlacData *data = (FlacData *) fdata; FlacData *data = (FlacData *) fdata;
size_t r; size_t r;
while (1) { r = decoder_read(data->decoder, data->inStream, (void *)buf, *bytes);
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;
}
*bytes = r; *bytes = r;
if (r == 0 && decoder_get_command(data->decoder) != DECODE_COMMAND_STOP) { 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) if (readSize == 0)
return -1; return -1;
readed = readFromInputStream(data->inStream, readStart, (size_t) 1, readed = decoder_read(data->decoder, data->inStream,
readSize); readStart, readSize);
if (readed <= 0 && inputStreamAtEOF(data->inStream)) if (readed == 0)
return -1; 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); mad_stream_buffer(&data->stream, data->readBuffer, readed + remaining);
(data->stream).error = 0; (data->stream).error = 0;
@ -324,13 +319,10 @@ static void mp3_parseId3Tag(mp3DecodeData * data, size_t tagsize,
while (count < tagsize) { while (count < tagsize) {
size_t len; size_t len;
len = readFromInputStream(data->inStream, len = decoder_read(data->decoder, data->inStream,
allocated + count, (size_t) 1, allocated + count, tagsize - count);
tagsize - count); if (len == 0)
if (len <= 0 && inputStreamAtEOF(data->inStream)) {
break; break;
} else if (len <= 0)
my_usleep(10000);
else else
count += len; 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) static mpc_int32_t mpc_read_cb(void *vdata, void *ptr, mpc_int32_t size)
{ {
mpc_int32_t ret = 0;
MpcCallbackData *data = (MpcCallbackData *) vdata; MpcCallbackData *data = (MpcCallbackData *) vdata;
while (1) { return decoder_read(data->decoder, data->inStream, ptr, size);
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;
} }
static mpc_bool_t mpc_seek_cb(void *vdata, mpc_int32_t offset) 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; FlacData *data = (FlacData *) fdata;
size_t r; size_t r;
while (1) { r = decoder_read(data->decoder, data->inStream, (void *)buf, *bytes);
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;
}
*bytes = r; *bytes = r;
if (r == 0 && !inputStreamAtEOF(data->inStream) && 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; size_t ret;
OggCallbackData *data = (OggCallbackData *) vdata; OggCallbackData *data = (OggCallbackData *) vdata;
while (1) { ret = decoder_read(data->decoder, data->inStream, ptr, size * nmemb);
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;
}
errno = 0; errno = 0;
/*if(ret<0) errno = ((InputStream *)inStream)->error; */ /*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) 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; --bcount;
++i; ++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) static uint32_t get_pos(void *id)