InputStream: convert to class
This commit is contained in:
parent
ee2afb35dd
commit
6773adc771
@ -44,10 +44,10 @@ CheckDecoderPlugin(const DecoderPlugin &plugin,
|
|||||||
bool
|
bool
|
||||||
tag_stream_scan(InputStream &is, const tag_handler &handler, void *ctx)
|
tag_stream_scan(InputStream &is, const tag_handler &handler, void *ctx)
|
||||||
{
|
{
|
||||||
assert(is.ready);
|
assert(is.IsReady());
|
||||||
|
|
||||||
const char *const suffix = uri_get_suffix(is.uri.c_str());
|
const char *const suffix = uri_get_suffix(is.GetURI());
|
||||||
const char *const mime = is.mime.empty() ? nullptr : is.mime.c_str();
|
const char *const mime = is.GetMimeType();
|
||||||
|
|
||||||
if (suffix == nullptr && mime == nullptr)
|
if (suffix == nullptr && mime == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
|
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
struct tag_handler;
|
struct tag_handler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,7 @@ class Cond;
|
|||||||
class Error;
|
class Error;
|
||||||
struct ArchivePlugin;
|
struct ArchivePlugin;
|
||||||
class ArchiveVisitor;
|
class ArchiveVisitor;
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
|
|
||||||
class ArchiveFile {
|
class ArchiveFile {
|
||||||
public:
|
public:
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
struct DecoderBuffer;
|
struct DecoderBuffer;
|
||||||
|
|
||||||
struct Decoder;
|
struct Decoder;
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
|
|
||||||
template<typename T> struct ConstBuffer;
|
template<typename T> struct ConstBuffer;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
struct config_param;
|
struct config_param;
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
struct tag_handler;
|
struct tag_handler;
|
||||||
class Path;
|
class Path;
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ decoder_input_stream_open(DecoderControl &dc, const char *uri)
|
|||||||
dc.Lock();
|
dc.Lock();
|
||||||
|
|
||||||
is->Update();
|
is->Update();
|
||||||
while (!is->ready &&
|
while (!is->IsReady() &&
|
||||||
dc.command != DecoderCommand::STOP) {
|
dc.command != DecoderCommand::STOP) {
|
||||||
dc.Wait();
|
dc.Wait();
|
||||||
|
|
||||||
@ -114,7 +114,7 @@ decoder_stream_decode(const DecoderPlugin &plugin,
|
|||||||
assert(plugin.stream_decode != nullptr);
|
assert(plugin.stream_decode != nullptr);
|
||||||
assert(decoder.stream_tag == nullptr);
|
assert(decoder.stream_tag == nullptr);
|
||||||
assert(decoder.decoder_tag == nullptr);
|
assert(decoder.decoder_tag == nullptr);
|
||||||
assert(input_stream.ready);
|
assert(input_stream.IsReady());
|
||||||
assert(decoder.dc.state == DecoderState::START);
|
assert(decoder.dc.state == DecoderState::START);
|
||||||
|
|
||||||
FormatDebug(decoder_thread_domain, "probing plugin %s", plugin.name);
|
FormatDebug(decoder_thread_domain, "probing plugin %s", plugin.name);
|
||||||
@ -179,7 +179,8 @@ decoder_check_plugin_mime(const DecoderPlugin &plugin, const InputStream &is)
|
|||||||
{
|
{
|
||||||
assert(plugin.stream_decode != nullptr);
|
assert(plugin.stream_decode != nullptr);
|
||||||
|
|
||||||
return !is.mime.empty() && plugin.SupportsMimeType(is.mime.c_str());
|
const char *mime_type = is.GetMimeType();
|
||||||
|
return mime_type != nullptr && plugin.SupportsMimeType(mime_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct Decoder;
|
struct Decoder;
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
|
|
||||||
struct DsdId {
|
struct DsdId {
|
||||||
char value[4];
|
char value[4];
|
||||||
|
@ -385,7 +385,7 @@ ffmpeg_probe(Decoder *decoder, InputStream &is)
|
|||||||
AVProbeData avpd;
|
AVProbeData avpd;
|
||||||
avpd.buf = buffer;
|
avpd.buf = buffer;
|
||||||
avpd.buf_size = nbytes;
|
avpd.buf_size = nbytes;
|
||||||
avpd.filename = is.uri.c_str();
|
avpd.filename = is.GetURI();
|
||||||
|
|
||||||
return av_probe_input_format(&avpd, true);
|
return av_probe_input_format(&avpd, true);
|
||||||
}
|
}
|
||||||
@ -409,7 +409,7 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
|
|||||||
//ffmpeg works with ours "fileops" helper
|
//ffmpeg works with ours "fileops" helper
|
||||||
AVFormatContext *format_context = nullptr;
|
AVFormatContext *format_context = nullptr;
|
||||||
if (mpd_ffmpeg_open_input(&format_context, stream.io,
|
if (mpd_ffmpeg_open_input(&format_context, stream.io,
|
||||||
input.uri.c_str(),
|
input.GetURI(),
|
||||||
input_format) != 0) {
|
input_format) != 0) {
|
||||||
LogError(ffmpeg_domain, "Open failed");
|
LogError(ffmpeg_domain, "Open failed");
|
||||||
return;
|
return;
|
||||||
@ -558,7 +558,7 @@ ffmpeg_scan_stream(InputStream &is,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
AVFormatContext *f = nullptr;
|
AVFormatContext *f = nullptr;
|
||||||
if (mpd_ffmpeg_open_input(&f, stream.io, is.uri.c_str(),
|
if (mpd_ffmpeg_open_input(&f, stream.io, is.GetURI(),
|
||||||
input_format) != 0)
|
input_format) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include <FLAC/stream_decoder.h>
|
#include <FLAC/stream_decoder.h>
|
||||||
|
|
||||||
struct Decoder;
|
struct Decoder;
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class wraps an #InputStream in libFLAC stream decoder
|
* This class wraps an #InputStream in libFLAC stream decoder
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#define MPD_OGG_CODEC_HXX
|
#define MPD_OGG_CODEC_HXX
|
||||||
|
|
||||||
struct Decoder;
|
struct Decoder;
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
|
|
||||||
enum ogg_codec {
|
enum ogg_codec {
|
||||||
OGG_CODEC_UNKNOWN,
|
OGG_CODEC_UNKNOWN,
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
struct Decoder;
|
struct Decoder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -487,7 +487,7 @@ wavpack_streamdecode(Decoder &decoder, InputStream &is)
|
|||||||
bool can_seek = is.seekable;
|
bool can_seek = is.seekable;
|
||||||
|
|
||||||
wavpack_input isp_wvc;
|
wavpack_input isp_wvc;
|
||||||
InputStream *is_wvc = wavpack_open_wvc(decoder, is.uri.c_str(),
|
InputStream *is_wvc = wavpack_open_wvc(decoder, is.GetURI(),
|
||||||
is.mutex, is.cond,
|
is.mutex, is.cond,
|
||||||
&isp_wvc);
|
&isp_wvc);
|
||||||
if (is_wvc != nullptr) {
|
if (is_wvc != nullptr) {
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct config_param;
|
struct config_param;
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
class Error;
|
class Error;
|
||||||
struct Tag;
|
struct Tag;
|
||||||
|
|
||||||
|
@ -92,6 +92,15 @@ InputStream::Update()
|
|||||||
plugin.update(this);
|
plugin.update(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InputStream::SetReady()
|
||||||
|
{
|
||||||
|
assert(!ready);
|
||||||
|
|
||||||
|
ready = true;
|
||||||
|
cond.broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InputStream::WaitReady()
|
InputStream::WaitReady()
|
||||||
{
|
{
|
||||||
|
@ -34,9 +34,11 @@ class Error;
|
|||||||
struct Tag;
|
struct Tag;
|
||||||
struct InputPlugin;
|
struct InputPlugin;
|
||||||
|
|
||||||
struct InputStream {
|
class InputStream {
|
||||||
|
public:
|
||||||
typedef int64_t offset_type;
|
typedef int64_t offset_type;
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
* the plugin which implements this input stream
|
* the plugin which implements this input stream
|
||||||
*/
|
*/
|
||||||
@ -47,6 +49,7 @@ struct InputStream {
|
|||||||
*/
|
*/
|
||||||
std::string uri;
|
std::string uri;
|
||||||
|
|
||||||
|
public:
|
||||||
/**
|
/**
|
||||||
* A mutex that protects the mutable attributes of this object
|
* A mutex that protects the mutable attributes of this object
|
||||||
* and its implementation. It must be locked before calling
|
* and its implementation. It must be locked before calling
|
||||||
@ -83,16 +86,19 @@ struct InputStream {
|
|||||||
*/
|
*/
|
||||||
offset_type size;
|
offset_type size;
|
||||||
|
|
||||||
|
public:
|
||||||
/**
|
/**
|
||||||
* the current offset within the stream
|
* the current offset within the stream
|
||||||
*/
|
*/
|
||||||
offset_type offset;
|
offset_type offset;
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
* the MIME content type of the resource, or empty if unknown.
|
* the MIME content type of the resource, or empty if unknown.
|
||||||
*/
|
*/
|
||||||
std::string mime;
|
std::string mime;
|
||||||
|
|
||||||
|
public:
|
||||||
InputStream(const InputPlugin &_plugin,
|
InputStream(const InputPlugin &_plugin,
|
||||||
const char *_uri, Mutex &_mutex, Cond &_cond)
|
const char *_uri, Mutex &_mutex, Cond &_cond)
|
||||||
:plugin(_plugin), uri(_uri),
|
:plugin(_plugin), uri(_uri),
|
||||||
@ -134,6 +140,19 @@ struct InputStream {
|
|||||||
*/
|
*/
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
|
const InputPlugin &GetPlugin() const {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The absolute URI which was used to open this stream.
|
||||||
|
*
|
||||||
|
* No lock necessary for this method.
|
||||||
|
*/
|
||||||
|
const char *GetURI() const {
|
||||||
|
return uri.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
void Lock() {
|
void Lock() {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
}
|
}
|
||||||
@ -155,11 +174,18 @@ struct InputStream {
|
|||||||
*/
|
*/
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
|
void SetReady();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait until the stream becomes ready.
|
* Return whether the stream is ready for reading and whether
|
||||||
|
* the other attributes in this struct are valid.
|
||||||
*
|
*
|
||||||
* The caller must lock the mutex.
|
* The caller must lock the mutex.
|
||||||
*/
|
*/
|
||||||
|
bool IsReady() const {
|
||||||
|
return ready;
|
||||||
|
}
|
||||||
|
|
||||||
void WaitReady();
|
void WaitReady();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,6 +194,13 @@ struct InputStream {
|
|||||||
*/
|
*/
|
||||||
void LockWaitReady();
|
void LockWaitReady();
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
bool HasMimeType() const {
|
||||||
|
assert(ready);
|
||||||
|
|
||||||
|
return !mime.empty();
|
||||||
|
}
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
const char *GetMimeType() const {
|
const char *GetMimeType() const {
|
||||||
assert(ready);
|
assert(ready);
|
||||||
@ -175,6 +208,19 @@ struct InputStream {
|
|||||||
return mime.empty() ? nullptr : mime.c_str();
|
return mime.empty() ? nullptr : mime.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gcc_nonnull_all
|
||||||
|
void SetMimeType(const char *_mime) {
|
||||||
|
assert(!ready);
|
||||||
|
|
||||||
|
mime = _mime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetMimeType(std::string &&_mime) {
|
||||||
|
assert(!ready);
|
||||||
|
|
||||||
|
mime = std::move(_mime);
|
||||||
|
}
|
||||||
|
|
||||||
gcc_nonnull_all
|
gcc_nonnull_all
|
||||||
void OverrideMimeType(const char *_mime) {
|
void OverrideMimeType(const char *_mime) {
|
||||||
assert(ready);
|
assert(ready);
|
||||||
@ -189,6 +235,14 @@ struct InputStream {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddOffset(offset_type delta) {
|
||||||
|
assert(ready);
|
||||||
|
assert(offset >= 0);
|
||||||
|
assert(delta >= 0);
|
||||||
|
|
||||||
|
offset += delta;
|
||||||
|
}
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
offset_type GetOffset() const {
|
offset_type GetOffset() const {
|
||||||
assert(ready);
|
assert(ready);
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
|
|
||||||
class TextInputStream {
|
class TextInputStream {
|
||||||
InputStream &is;
|
InputStream &is;
|
||||||
|
@ -58,18 +58,17 @@ ThreadInputStream::Start(Error &error)
|
|||||||
inline void
|
inline void
|
||||||
ThreadInputStream::ThreadFunc()
|
ThreadInputStream::ThreadFunc()
|
||||||
{
|
{
|
||||||
FormatThreadName("input:%s", base.plugin.name);
|
FormatThreadName("input:%s", base.GetPlugin().name);
|
||||||
|
|
||||||
base.mutex.lock();
|
Lock();
|
||||||
if (!Open(postponed_error)) {
|
if (!Open(postponed_error)) {
|
||||||
base.cond.broadcast();
|
base.cond.broadcast();
|
||||||
base.mutex.unlock();
|
Unlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we're ready, tell it to our client */
|
/* we're ready, tell it to our client */
|
||||||
base.ready = true;
|
base.SetReady();
|
||||||
base.cond.broadcast();
|
|
||||||
|
|
||||||
while (!close) {
|
while (!close) {
|
||||||
assert(!postponed_error.IsDefined());
|
assert(!postponed_error.IsDefined());
|
||||||
@ -78,12 +77,12 @@ ThreadInputStream::ThreadFunc()
|
|||||||
if (w.IsEmpty()) {
|
if (w.IsEmpty()) {
|
||||||
wake_cond.wait(base.mutex);
|
wake_cond.wait(base.mutex);
|
||||||
} else {
|
} else {
|
||||||
base.mutex.unlock();
|
Unlock();
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
size_t nbytes = Read(w.data, w.size, error);
|
size_t nbytes = Read(w.data, w.size, error);
|
||||||
|
|
||||||
base.mutex.lock();
|
Lock();
|
||||||
base.cond.broadcast();
|
base.cond.broadcast();
|
||||||
|
|
||||||
if (nbytes == 0) {
|
if (nbytes == 0) {
|
||||||
@ -96,7 +95,7 @@ ThreadInputStream::ThreadFunc()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base.mutex.unlock();
|
Unlock();
|
||||||
|
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
@ -173,10 +172,10 @@ ThreadInputStream::Read(InputStream *is, void *ptr, size_t size,
|
|||||||
inline void
|
inline void
|
||||||
ThreadInputStream::Close2()
|
ThreadInputStream::Close2()
|
||||||
{
|
{
|
||||||
base.mutex.lock();
|
Lock();
|
||||||
close = true;
|
close = true;
|
||||||
wake_cond.signal();
|
wake_cond.signal();
|
||||||
base.mutex.unlock();
|
Unlock();
|
||||||
|
|
||||||
Cancel();
|
Cancel();
|
||||||
|
|
||||||
|
@ -87,23 +87,23 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void Lock() {
|
void Lock() {
|
||||||
base.mutex.lock();
|
base.Lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unlock() {
|
void Unlock() {
|
||||||
base.mutex.unlock();
|
base.Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *GetURI() const {
|
const char *GetURI() const {
|
||||||
assert(thread.IsInside());
|
assert(thread.IsInside());
|
||||||
|
|
||||||
return base.uri.c_str();
|
return base.GetURI();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMimeType(const char *mime) {
|
void SetMimeType(const char *mime) {
|
||||||
assert(thread.IsInside());
|
assert(thread.IsInside());
|
||||||
|
|
||||||
base.mime = mime;
|
base.SetMimeType(mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* to be implemented by the plugin */
|
/* to be implemented by the plugin */
|
||||||
|
@ -96,8 +96,9 @@ public:
|
|||||||
/* this mime type forces use of the PcmDecoderPlugin.
|
/* this mime type forces use of the PcmDecoderPlugin.
|
||||||
Needs to be generalised when/if that decoder is
|
Needs to be generalised when/if that decoder is
|
||||||
updated to support other audio formats */
|
updated to support other audio formats */
|
||||||
base.mime = "audio/x-mpd-cdda-pcm";
|
base.SetMimeType("audio/x-mpd-cdda-pcm");
|
||||||
base.ready = true;
|
base.SetReady();
|
||||||
|
|
||||||
frames_to_read = read_buffer_size / frame_size;
|
frames_to_read = read_buffer_size / frame_size;
|
||||||
|
|
||||||
snd_pcm_start(capture_handle);
|
snd_pcm_start(capture_handle);
|
||||||
|
@ -269,9 +269,9 @@ input_cdio_open(const char *uri,
|
|||||||
i->base.size = (i->lsn_to - i->lsn_from + 1) * CDIO_CD_FRAMESIZE_RAW;
|
i->base.size = (i->lsn_to - i->lsn_from + 1) * CDIO_CD_FRAMESIZE_RAW;
|
||||||
|
|
||||||
/* hack to make MPD select the "pcm" decoder plugin */
|
/* hack to make MPD select the "pcm" decoder plugin */
|
||||||
i->base.mime = reverse_endian
|
i->base.SetMimeType(reverse_endian
|
||||||
? "audio/x-mpd-cdda-pcm-reverse"
|
? "audio/x-mpd-cdda-pcm-reverse"
|
||||||
: "audio/x-mpd-cdda-pcm";
|
: "audio/x-mpd-cdda-pcm");
|
||||||
|
|
||||||
return &i->base;
|
return &i->base;
|
||||||
}
|
}
|
||||||
|
@ -497,8 +497,7 @@ CurlInputStream::RequestDone(CURLcode result, long status)
|
|||||||
status);
|
status);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.ready = true;
|
base.SetReady();
|
||||||
base.cond.broadcast();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -833,7 +832,7 @@ CurlInputStream::HeaderReceived(const char *name, std::string &&value)
|
|||||||
} else if (StringEqualsCaseASCII(name, "content-length")) {
|
} else if (StringEqualsCaseASCII(name, "content-length")) {
|
||||||
base.size = base.offset + ParseUint64(value.c_str());
|
base.size = base.offset + ParseUint64(value.c_str());
|
||||||
} else if (StringEqualsCaseASCII(name, "content-type")) {
|
} else if (StringEqualsCaseASCII(name, "content-type")) {
|
||||||
base.mime = std::move(value);
|
base.SetMimeType(std::move(value));
|
||||||
} else if (StringEqualsCaseASCII(name, "icy-name") ||
|
} else if (StringEqualsCaseASCII(name, "icy-name") ||
|
||||||
StringEqualsCaseASCII(name, "ice-name") ||
|
StringEqualsCaseASCII(name, "ice-name") ||
|
||||||
StringEqualsCaseASCII(name, "x-audiocast-name")) {
|
StringEqualsCaseASCII(name, "x-audiocast-name")) {
|
||||||
@ -987,7 +986,7 @@ CurlInputStream::InitEasy(Error &error)
|
|||||||
curl_easy_setopt(easy, CURLOPT_PROXYUSERPWD, proxy_auth_str);
|
curl_easy_setopt(easy, CURLOPT_PROXYUSERPWD, proxy_auth_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode code = curl_easy_setopt(easy, CURLOPT_URL, base.uri.c_str());
|
CURLcode code = curl_easy_setopt(easy, CURLOPT_URL, base.GetURI());
|
||||||
if (code != CURLE_OK) {
|
if (code != CURLE_OK) {
|
||||||
error.Format(curl_domain, code,
|
error.Format(curl_domain, code,
|
||||||
"curl_easy_setopt() failed: %s",
|
"curl_easy_setopt() failed: %s",
|
||||||
@ -1091,9 +1090,7 @@ CurlInputStream::Seek(InputPlugin::offset_type offset, int whence,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
base.mutex.lock();
|
base.mutex.lock();
|
||||||
|
base.WaitReady();
|
||||||
while (!base.ready)
|
|
||||||
base.cond.wait(base.mutex);
|
|
||||||
|
|
||||||
if (postponed_error.IsDefined()) {
|
if (postponed_error.IsDefined()) {
|
||||||
error = std::move(postponed_error);
|
error = std::move(postponed_error);
|
||||||
|
@ -58,8 +58,8 @@ class DespotifyInputStream {
|
|||||||
memset(&pcm, 0, sizeof(pcm));
|
memset(&pcm, 0, sizeof(pcm));
|
||||||
|
|
||||||
/* Despotify outputs pcm data */
|
/* Despotify outputs pcm data */
|
||||||
base.mime = "audio/x-mpd-cdda-pcm";
|
base.SetMimeType("audio/x-mpd-cdda-pcm");
|
||||||
base.ready = true;
|
base.SetReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -52,7 +52,7 @@ struct FfmpegInputStream {
|
|||||||
- since avio.h doesn't tell us the MIME type of the
|
- since avio.h doesn't tell us the MIME type of the
|
||||||
resource, we can't select a decoder plugin, but the
|
resource, we can't select a decoder plugin, but the
|
||||||
"ffmpeg" plugin is quite good at auto-detection */
|
"ffmpeg" plugin is quite good at auto-detection */
|
||||||
base.mime = "audio/x-mpd-ffmpeg";
|
base.SetMimeType("audio/x-mpd-ffmpeg");
|
||||||
}
|
}
|
||||||
|
|
||||||
~FfmpegInputStream() {
|
~FfmpegInputStream() {
|
||||||
|
@ -44,7 +44,7 @@ struct FileInputStream {
|
|||||||
fd(_fd) {
|
fd(_fd) {
|
||||||
base.size = size;
|
base.size = size;
|
||||||
base.seekable = true;
|
base.seekable = true;
|
||||||
base.ready = true;
|
base.SetReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
~FileInputStream() {
|
~FileInputStream() {
|
||||||
@ -138,7 +138,7 @@ input_file_close(InputStream *is)
|
|||||||
static bool
|
static bool
|
||||||
input_file_eof(InputStream *is)
|
input_file_eof(InputStream *is)
|
||||||
{
|
{
|
||||||
return is->offset >= is->size;
|
return is->GetOffset() >= is->GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
const InputPlugin input_plugin_file = {
|
const InputPlugin input_plugin_file = {
|
||||||
|
@ -55,7 +55,7 @@ struct RewindInputStream {
|
|||||||
char buffer[64 * 1024];
|
char buffer[64 * 1024];
|
||||||
|
|
||||||
RewindInputStream(InputStream *_input)
|
RewindInputStream(InputStream *_input)
|
||||||
:base(rewind_input_plugin, _input->uri.c_str(),
|
:base(rewind_input_plugin, _input->GetURI(),
|
||||||
_input->mutex, _input->cond),
|
_input->mutex, _input->cond),
|
||||||
input(_input), tail(0) {
|
input(_input), tail(0) {
|
||||||
}
|
}
|
||||||
@ -84,15 +84,16 @@ struct RewindInputStream {
|
|||||||
|
|
||||||
assert(dest != src);
|
assert(dest != src);
|
||||||
|
|
||||||
bool dest_ready = dest->ready;
|
if (!dest->IsReady() && src->IsReady()) {
|
||||||
|
if (src->HasMimeType())
|
||||||
|
dest->SetMimeType(src->GetMimeType());
|
||||||
|
|
||||||
|
dest->size = src->GetSize();
|
||||||
|
dest->seekable = src->IsSeekable();
|
||||||
|
dest->SetReady();
|
||||||
|
}
|
||||||
|
|
||||||
dest->ready = src->ready;
|
|
||||||
dest->seekable = src->seekable;
|
|
||||||
dest->size = src->size;
|
|
||||||
dest->offset = src->offset;
|
dest->offset = src->offset;
|
||||||
|
|
||||||
if (!dest_ready && src->ready)
|
|
||||||
dest->mime = src->mime;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,7 +196,7 @@ input_rewind_seek(InputStream *is, InputPlugin::offset_type offset,
|
|||||||
{
|
{
|
||||||
RewindInputStream *r = (RewindInputStream *)is;
|
RewindInputStream *r = (RewindInputStream *)is;
|
||||||
|
|
||||||
assert(is->ready);
|
assert(is->IsReady());
|
||||||
|
|
||||||
if (whence == SEEK_SET && r->tail > 0 &&
|
if (whence == SEEK_SET && r->tail > 0 &&
|
||||||
offset <= (InputPlugin::offset_type)r->tail) {
|
offset <= (InputPlugin::offset_type)r->tail) {
|
||||||
@ -242,7 +243,7 @@ input_rewind_open(InputStream *is)
|
|||||||
assert(is != nullptr);
|
assert(is != nullptr);
|
||||||
assert(is->offset == 0);
|
assert(is->offset == 0);
|
||||||
|
|
||||||
if (is->seekable)
|
if (is->IsReady() && is->IsSeekable())
|
||||||
/* seekable resources don't need this plugin */
|
/* seekable resources don't need this plugin */
|
||||||
return is;
|
return is;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
|
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
|
|
||||||
InputStream *
|
InputStream *
|
||||||
input_rewind_open(InputStream *is);
|
input_rewind_open(InputStream *is);
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include <expat.h>
|
#include <expat.h>
|
||||||
|
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
class Error;
|
class Error;
|
||||||
|
|
||||||
class ExpatParser final {
|
class ExpatParser final {
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "SongEnumerator.hxx"
|
#include "SongEnumerator.hxx"
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A #SongEnumerator wrapper that closes an #InputStream automatically
|
* A #SongEnumerator wrapper that closes an #InputStream automatically
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#define MPD_PLAYLIST_PLUGIN_HXX
|
#define MPD_PLAYLIST_PLUGIN_HXX
|
||||||
|
|
||||||
struct config_param;
|
struct config_param;
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
struct Tag;
|
struct Tag;
|
||||||
class Mutex;
|
class Mutex;
|
||||||
class Cond;
|
class Cond;
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
class Mutex;
|
class Mutex;
|
||||||
class Cond;
|
class Cond;
|
||||||
class SongEnumerator;
|
class SongEnumerator;
|
||||||
struct InputStream;
|
class InputStream;
|
||||||
|
|
||||||
extern const struct playlist_plugin *const playlist_plugins[];
|
extern const struct playlist_plugin *const playlist_plugins[];
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ dump_input_stream(InputStream *is)
|
|||||||
|
|
||||||
/* print meta data */
|
/* print meta data */
|
||||||
|
|
||||||
if (!is->mime.empty())
|
if (is->HasMimeType())
|
||||||
fprintf(stderr, "MIME type: %s\n", is->mime.c_str());
|
fprintf(stderr, "MIME type: %s\n", is->GetMimeType());
|
||||||
|
|
||||||
/* read data and tags from the stream */
|
/* read data and tags from the stream */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user