diff options
author | Max Kellermann <max@duempel.org> | 2014-05-11 15:34:48 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-05-11 15:34:48 +0200 |
commit | 6773adc7716eea7656c4590b54f7c99840ff4087 (patch) | |
tree | b71756798018721f3aa472ce1b81aa14e84239b8 /src/input | |
parent | ee2afb35dd715d9f34a938cd54ed02a3c0091a78 (diff) | |
download | mpd-6773adc7716eea7656c4590b54f7c99840ff4087.tar.gz mpd-6773adc7716eea7656c4590b54f7c99840ff4087.tar.xz mpd-6773adc7716eea7656c4590b54f7c99840ff4087.zip |
InputStream: convert to class
Diffstat (limited to 'src/input')
-rw-r--r-- | src/input/InputPlugin.hxx | 2 | ||||
-rw-r--r-- | src/input/InputStream.cxx | 9 | ||||
-rw-r--r-- | src/input/InputStream.hxx | 58 | ||||
-rw-r--r-- | src/input/TextInputStream.hxx | 2 | ||||
-rw-r--r-- | src/input/ThreadInputStream.cxx | 19 | ||||
-rw-r--r-- | src/input/ThreadInputStream.hxx | 8 | ||||
-rw-r--r-- | src/input/plugins/AlsaInputPlugin.cxx | 5 | ||||
-rw-r--r-- | src/input/plugins/CdioParanoiaInputPlugin.cxx | 6 | ||||
-rw-r--r-- | src/input/plugins/CurlInputPlugin.cxx | 11 | ||||
-rw-r--r-- | src/input/plugins/DespotifyInputPlugin.cxx | 4 | ||||
-rw-r--r-- | src/input/plugins/FfmpegInputPlugin.cxx | 2 | ||||
-rw-r--r-- | src/input/plugins/FileInputPlugin.cxx | 4 | ||||
-rw-r--r-- | src/input/plugins/RewindInputPlugin.cxx | 21 | ||||
-rw-r--r-- | src/input/plugins/RewindInputPlugin.hxx | 2 |
14 files changed, 107 insertions, 46 deletions
diff --git a/src/input/InputPlugin.hxx b/src/input/InputPlugin.hxx index 090c73df8..412ca4cf9 100644 --- a/src/input/InputPlugin.hxx +++ b/src/input/InputPlugin.hxx @@ -35,7 +35,7 @@ #endif struct config_param; -struct InputStream; +class InputStream; class Error; struct Tag; diff --git a/src/input/InputStream.cxx b/src/input/InputStream.cxx index 0621437c4..d54eca643 100644 --- a/src/input/InputStream.cxx +++ b/src/input/InputStream.cxx @@ -93,6 +93,15 @@ InputStream::Update() } void +InputStream::SetReady() +{ + assert(!ready); + + ready = true; + cond.broadcast(); +} + +void InputStream::WaitReady() { while (true) { diff --git a/src/input/InputStream.hxx b/src/input/InputStream.hxx index c66091687..65840ba27 100644 --- a/src/input/InputStream.hxx +++ b/src/input/InputStream.hxx @@ -34,9 +34,11 @@ class Error; struct Tag; struct InputPlugin; -struct InputStream { +class InputStream { +public: typedef int64_t offset_type; +private: /** * the plugin which implements this input stream */ @@ -47,6 +49,7 @@ struct InputStream { */ std::string uri; +public: /** * A mutex that protects the mutable attributes of this object * and its implementation. It must be locked before calling @@ -83,16 +86,19 @@ struct InputStream { */ offset_type size; +public: /** * the current offset within the stream */ offset_type offset; +private: /** * the MIME content type of the resource, or empty if unknown. */ std::string mime; +public: InputStream(const InputPlugin &_plugin, const char *_uri, Mutex &_mutex, Cond &_cond) :plugin(_plugin), uri(_uri), @@ -134,6 +140,19 @@ struct InputStream { */ 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() { mutex.lock(); } @@ -155,11 +174,18 @@ struct InputStream { */ 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. */ + bool IsReady() const { + return ready; + } + void WaitReady(); /** @@ -169,6 +195,13 @@ struct InputStream { void LockWaitReady(); gcc_pure + bool HasMimeType() const { + assert(ready); + + return !mime.empty(); + } + + gcc_pure const char *GetMimeType() const { assert(ready); @@ -176,6 +209,19 @@ struct InputStream { } 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 void OverrideMimeType(const char *_mime) { assert(ready); @@ -189,6 +235,14 @@ struct InputStream { return size; } + void AddOffset(offset_type delta) { + assert(ready); + assert(offset >= 0); + assert(delta >= 0); + + offset += delta; + } + gcc_pure offset_type GetOffset() const { assert(ready); diff --git a/src/input/TextInputStream.hxx b/src/input/TextInputStream.hxx index 86ae16e41..c67423da1 100644 --- a/src/input/TextInputStream.hxx +++ b/src/input/TextInputStream.hxx @@ -24,7 +24,7 @@ #include <string> -struct InputStream; +class InputStream; class TextInputStream { InputStream &is; diff --git a/src/input/ThreadInputStream.cxx b/src/input/ThreadInputStream.cxx index 5271171ef..fde9bd08e 100644 --- a/src/input/ThreadInputStream.cxx +++ b/src/input/ThreadInputStream.cxx @@ -58,18 +58,17 @@ ThreadInputStream::Start(Error &error) inline void ThreadInputStream::ThreadFunc() { - FormatThreadName("input:%s", base.plugin.name); + FormatThreadName("input:%s", base.GetPlugin().name); - base.mutex.lock(); + Lock(); if (!Open(postponed_error)) { base.cond.broadcast(); - base.mutex.unlock(); + Unlock(); return; } /* we're ready, tell it to our client */ - base.ready = true; - base.cond.broadcast(); + base.SetReady(); while (!close) { assert(!postponed_error.IsDefined()); @@ -78,12 +77,12 @@ ThreadInputStream::ThreadFunc() if (w.IsEmpty()) { wake_cond.wait(base.mutex); } else { - base.mutex.unlock(); + Unlock(); Error error; size_t nbytes = Read(w.data, w.size, error); - base.mutex.lock(); + Lock(); base.cond.broadcast(); if (nbytes == 0) { @@ -96,7 +95,7 @@ ThreadInputStream::ThreadFunc() } } - base.mutex.unlock(); + Unlock(); Close(); } @@ -173,10 +172,10 @@ ThreadInputStream::Read(InputStream *is, void *ptr, size_t size, inline void ThreadInputStream::Close2() { - base.mutex.lock(); + Lock(); close = true; wake_cond.signal(); - base.mutex.unlock(); + Unlock(); Cancel(); diff --git a/src/input/ThreadInputStream.hxx b/src/input/ThreadInputStream.hxx index 01428d717..8bae93a05 100644 --- a/src/input/ThreadInputStream.hxx +++ b/src/input/ThreadInputStream.hxx @@ -87,23 +87,23 @@ public: protected: void Lock() { - base.mutex.lock(); + base.Lock(); } void Unlock() { - base.mutex.unlock(); + base.Unlock(); } const char *GetURI() const { assert(thread.IsInside()); - return base.uri.c_str(); + return base.GetURI(); } void SetMimeType(const char *mime) { assert(thread.IsInside()); - base.mime = mime; + base.SetMimeType(mime); } /* to be implemented by the plugin */ diff --git a/src/input/plugins/AlsaInputPlugin.cxx b/src/input/plugins/AlsaInputPlugin.cxx index eae06ba6c..129219c01 100644 --- a/src/input/plugins/AlsaInputPlugin.cxx +++ b/src/input/plugins/AlsaInputPlugin.cxx @@ -96,8 +96,9 @@ public: /* this mime type forces use of the PcmDecoderPlugin. Needs to be generalised when/if that decoder is updated to support other audio formats */ - base.mime = "audio/x-mpd-cdda-pcm"; - base.ready = true; + base.SetMimeType("audio/x-mpd-cdda-pcm"); + base.SetReady(); + frames_to_read = read_buffer_size / frame_size; snd_pcm_start(capture_handle); diff --git a/src/input/plugins/CdioParanoiaInputPlugin.cxx b/src/input/plugins/CdioParanoiaInputPlugin.cxx index 767b2600f..5b4ce2ec6 100644 --- a/src/input/plugins/CdioParanoiaInputPlugin.cxx +++ b/src/input/plugins/CdioParanoiaInputPlugin.cxx @@ -269,9 +269,9 @@ input_cdio_open(const char *uri, i->base.size = (i->lsn_to - i->lsn_from + 1) * CDIO_CD_FRAMESIZE_RAW; /* hack to make MPD select the "pcm" decoder plugin */ - i->base.mime = reverse_endian - ? "audio/x-mpd-cdda-pcm-reverse" - : "audio/x-mpd-cdda-pcm"; + i->base.SetMimeType(reverse_endian + ? "audio/x-mpd-cdda-pcm-reverse" + : "audio/x-mpd-cdda-pcm"); return &i->base; } diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx index 37509e998..5f8b9150a 100644 --- a/src/input/plugins/CurlInputPlugin.cxx +++ b/src/input/plugins/CurlInputPlugin.cxx @@ -497,8 +497,7 @@ CurlInputStream::RequestDone(CURLcode result, long status) status); } - base.ready = true; - base.cond.broadcast(); + base.SetReady(); } static void @@ -833,7 +832,7 @@ CurlInputStream::HeaderReceived(const char *name, std::string &&value) } else if (StringEqualsCaseASCII(name, "content-length")) { base.size = base.offset + ParseUint64(value.c_str()); } else if (StringEqualsCaseASCII(name, "content-type")) { - base.mime = std::move(value); + base.SetMimeType(std::move(value)); } else if (StringEqualsCaseASCII(name, "icy-name") || StringEqualsCaseASCII(name, "ice-name") || StringEqualsCaseASCII(name, "x-audiocast-name")) { @@ -987,7 +986,7 @@ CurlInputStream::InitEasy(Error &error) 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) { error.Format(curl_domain, code, "curl_easy_setopt() failed: %s", @@ -1091,9 +1090,7 @@ CurlInputStream::Seek(InputPlugin::offset_type offset, int whence, return false; base.mutex.lock(); - - while (!base.ready) - base.cond.wait(base.mutex); + base.WaitReady(); if (postponed_error.IsDefined()) { error = std::move(postponed_error); diff --git a/src/input/plugins/DespotifyInputPlugin.cxx b/src/input/plugins/DespotifyInputPlugin.cxx index 152fda95f..702ebc132 100644 --- a/src/input/plugins/DespotifyInputPlugin.cxx +++ b/src/input/plugins/DespotifyInputPlugin.cxx @@ -58,8 +58,8 @@ class DespotifyInputStream { memset(&pcm, 0, sizeof(pcm)); /* Despotify outputs pcm data */ - base.mime = "audio/x-mpd-cdda-pcm"; - base.ready = true; + base.SetMimeType("audio/x-mpd-cdda-pcm"); + base.SetReady(); } public: diff --git a/src/input/plugins/FfmpegInputPlugin.cxx b/src/input/plugins/FfmpegInputPlugin.cxx index dab4b59fb..d06d4705a 100644 --- a/src/input/plugins/FfmpegInputPlugin.cxx +++ b/src/input/plugins/FfmpegInputPlugin.cxx @@ -52,7 +52,7 @@ struct FfmpegInputStream { - since avio.h doesn't tell us the MIME type of the resource, we can't select a decoder plugin, but the "ffmpeg" plugin is quite good at auto-detection */ - base.mime = "audio/x-mpd-ffmpeg"; + base.SetMimeType("audio/x-mpd-ffmpeg"); } ~FfmpegInputStream() { diff --git a/src/input/plugins/FileInputPlugin.cxx b/src/input/plugins/FileInputPlugin.cxx index 780e93263..49dc3df7e 100644 --- a/src/input/plugins/FileInputPlugin.cxx +++ b/src/input/plugins/FileInputPlugin.cxx @@ -44,7 +44,7 @@ struct FileInputStream { fd(_fd) { base.size = size; base.seekable = true; - base.ready = true; + base.SetReady(); } ~FileInputStream() { @@ -138,7 +138,7 @@ input_file_close(InputStream *is) static bool input_file_eof(InputStream *is) { - return is->offset >= is->size; + return is->GetOffset() >= is->GetSize(); } const InputPlugin input_plugin_file = { diff --git a/src/input/plugins/RewindInputPlugin.cxx b/src/input/plugins/RewindInputPlugin.cxx index 1a930ac53..1cc146d3f 100644 --- a/src/input/plugins/RewindInputPlugin.cxx +++ b/src/input/plugins/RewindInputPlugin.cxx @@ -55,7 +55,7 @@ struct RewindInputStream { char buffer[64 * 1024]; RewindInputStream(InputStream *_input) - :base(rewind_input_plugin, _input->uri.c_str(), + :base(rewind_input_plugin, _input->GetURI(), _input->mutex, _input->cond), input(_input), tail(0) { } @@ -84,15 +84,16 @@ struct RewindInputStream { assert(dest != src); - bool dest_ready = dest->ready; + if (!dest->IsReady() && src->IsReady()) { + if (src->HasMimeType()) + dest->SetMimeType(src->GetMimeType()); - dest->ready = src->ready; - dest->seekable = src->seekable; - dest->size = src->size; - dest->offset = src->offset; + dest->size = src->GetSize(); + dest->seekable = src->IsSeekable(); + dest->SetReady(); + } - if (!dest_ready && src->ready) - dest->mime = src->mime; + dest->offset = src->offset; } }; @@ -195,7 +196,7 @@ input_rewind_seek(InputStream *is, InputPlugin::offset_type offset, { RewindInputStream *r = (RewindInputStream *)is; - assert(is->ready); + assert(is->IsReady()); if (whence == SEEK_SET && r->tail > 0 && offset <= (InputPlugin::offset_type)r->tail) { @@ -242,7 +243,7 @@ input_rewind_open(InputStream *is) assert(is != nullptr); assert(is->offset == 0); - if (is->seekable) + if (is->IsReady() && is->IsSeekable()) /* seekable resources don't need this plugin */ return is; diff --git a/src/input/plugins/RewindInputPlugin.hxx b/src/input/plugins/RewindInputPlugin.hxx index f19705154..56b01b585 100644 --- a/src/input/plugins/RewindInputPlugin.hxx +++ b/src/input/plugins/RewindInputPlugin.hxx @@ -29,7 +29,7 @@ #include "check.h" -struct InputStream; +class InputStream; InputStream * input_rewind_open(InputStream *is); |