decoder/Client: add virtual method Read()

This commit is contained in:
Max Kellermann 2016-11-17 22:21:36 +01:00
parent b488204093
commit 114fcee2ae
6 changed files with 54 additions and 73 deletions

View File

@ -401,6 +401,37 @@ DecoderBridge::OpenUri(const char *uri)
}
}
size_t
DecoderBridge::Read(InputStream &is, void *buffer, size_t length)
try {
assert(buffer != nullptr);
assert(dc.state == DecoderState::START ||
dc.state == DecoderState::DECODE);
if (length == 0)
return 0;
ScopeLock lock(is.mutex);
while (true) {
if (CheckCancelRead())
return 0;
if (is.IsAvailable())
break;
is.cond.wait(is.mutex);
}
size_t nbytes = is.Read(buffer, length);
assert(nbytes > 0 || is.IsEOF());
return nbytes;
} catch (const std::runtime_error &e) {
error = std::current_exception();
return 0;
}
void
DecoderBridge::SubmitTimestamp(double t)
{

View File

@ -140,6 +140,7 @@ public:
uint64_t GetSeekFrame() override;
void SeekError() override;
InputStreamPtr OpenUri(const char *uri) override;
size_t Read(InputStream &is, void *buffer, size_t length) override;
void SubmitTimestamp(double t) override;
DecoderCommand SubmitData(InputStream *is,
const void *data, size_t length,

View File

@ -98,6 +98,17 @@ public:
*/
virtual InputStreamPtr OpenUri(const char *uri) = 0;
/**
* Blocking read from the input stream.
*
* @param is the input stream to read from
* @param buffer the destination buffer
* @param length the maximum number of bytes to read
* @return the number of bytes read, or 0 if one of the following
* occurs: end of file; error; command (like SEEK or STOP).
*/
virtual size_t Read(InputStream &is, void *buffer, size_t length) = 0;
/**
* Sets the time stamp for the next data chunk [seconds]. The MPD
* core automatically counts it up, and a decoder plugin only needs to

View File

@ -19,8 +19,6 @@
#include "config.h"
#include "DecoderAPI.hxx"
#include "DecoderControl.hxx"
#include "Bridge.hxx"
#include "input/InputStream.hxx"
#include "Log.hxx"
@ -30,44 +28,19 @@ size_t
decoder_read(DecoderClient *client,
InputStream &is,
void *buffer, size_t length)
try {
{
assert(buffer != nullptr);
/* XXX don't allow client==nullptr */
if (client == nullptr)
if (client != nullptr)
return client->Read(is, buffer, length);
try {
return is.LockRead(buffer, length);
auto &bridge = *(DecoderBridge *)client;
assert(bridge.dc.state == DecoderState::START ||
bridge.dc.state == DecoderState::DECODE);
if (length == 0)
return 0;
ScopeLock lock(is.mutex);
while (true) {
if (bridge.CheckCancelRead())
return 0;
if (is.IsAvailable())
break;
is.cond.wait(is.mutex);
}
size_t nbytes = is.Read(buffer, length);
assert(nbytes > 0 || is.IsEOF());
return nbytes;
} catch (const std::runtime_error &e) {
auto *bridge = (DecoderBridge *)client;
if (bridge != nullptr)
bridge->error = std::current_exception();
else
} catch (const std::runtime_error &e) {
LogError(e);
return 0;
return 0;
}
}
bool

View File

@ -80,51 +80,15 @@ FakeDecoder::OpenUri(const char *uri)
}
size_t
decoder_read(gcc_unused DecoderClient *client,
InputStream &is,
void *buffer, size_t length)
FakeDecoder::Read(InputStream &is, void *buffer, size_t length)
{
try {
return is.LockRead(buffer, length);
} catch (const std::runtime_error &) {
} catch (const std::runtime_error &e) {
return 0;
}
}
bool
decoder_read_full(DecoderClient *client, InputStream &is,
void *_buffer, size_t size)
{
uint8_t *buffer = (uint8_t *)_buffer;
while (size > 0) {
size_t nbytes = decoder_read(client, is, buffer, size);
if (nbytes == 0)
return false;
buffer += nbytes;
size -= nbytes;
}
return true;
}
bool
decoder_skip(DecoderClient *client, InputStream &is, size_t size)
{
while (size > 0) {
char buffer[1024];
size_t nbytes = decoder_read(client, is, buffer,
std::min(sizeof(buffer), size));
if (nbytes == 0)
return false;
size -= nbytes;
}
return true;
}
void
FakeDecoder::SubmitTimestamp(gcc_unused double t)
{

View File

@ -40,6 +40,7 @@ struct FakeDecoder final : DecoderClient {
uint64_t GetSeekFrame() override;
void SeekError() override;
InputStreamPtr OpenUri(const char *uri) override;
size_t Read(InputStream &is, void *buffer, size_t length) override;
void SubmitTimestamp(double t) override;
DecoderCommand SubmitData(InputStream *is,
const void *data, size_t length,