renamed Reader => Stream

This commit is contained in:
badaix 2016-03-22 23:14:19 +01:00
parent 1f177e5119
commit 0eaa616ab6
15 changed files with 114 additions and 114 deletions

View file

@ -13,7 +13,7 @@ CXX = /usr/bin/g++
CFLAGS = -std=c++0x -static-libgcc -static-libstdc++ -Wall -Wno-unused-function -O3 -pthread -DASIO_STANDALONE -DVERSION=\"$(VERSION)\" -I.. -I../externals/asio/asio/include -I../externals/popl/include
LDFLAGS = -lrt -lvorbis -lvorbisenc -logg -lFLAC -lavahi-client -lavahi-common
OBJ = snapServer.o config.o controlServer.o controlSession.o streamServer.o streamSession.o json/jsonrpc.o pcmreader/readerUri.o pcmreader/streamManager.o pcmreader/pcmReader.o pcmreader/pipeReader.o pcmreader/fileReader.o encoder/encoderFactory.o encoder/flacEncoder.o encoder/pcmEncoder.o encoder/oggEncoder.o publishAvahi.o ../common/log.o ../message/pcmChunk.o ../message/sampleFormat.o
OBJ = snapServer.o config.o controlServer.o controlSession.o streamServer.o streamSession.o json/jsonrpc.o streamreader/streamUri.o streamreader/streamManager.o streamreader/pcmStream.o streamreader/pipeStream.o streamreader/fileStream.o encoder/encoderFactory.o encoder/flacEncoder.o encoder/pcmEncoder.o encoder/oggEncoder.o publishAvahi.o ../common/log.o ../message/pcmChunk.o ../message/sampleFormat.o
BIN = snapserver
all: $(TARGET)

View file

@ -40,35 +40,35 @@ StreamServer::~StreamServer()
}
void StreamServer::onStateChanged(const PcmReader* pcmReader, const ReaderState& state)
void StreamServer::onStateChanged(const PcmStream* pcmStream, const ReaderState& state)
{
logO << "onStateChanged (" << pcmReader->getName() << "): " << state << "\n";
// logO << pcmReader->toJson().dump(4);
json notification = JsonNotification::getJson("Stream.OnUpdate", pcmReader->toJson());
logO << "onStateChanged (" << pcmStream->getName() << "): " << state << "\n";
// logO << pcmStream->toJson().dump(4);
json notification = JsonNotification::getJson("Stream.OnUpdate", pcmStream->toJson());
controlServer_->send(notification.dump(), NULL);
}
void StreamServer::onChunkRead(const PcmReader* pcmReader, const msg::PcmChunk* chunk, double duration)
void StreamServer::onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk* chunk, double duration)
{
// logO << "onChunkRead (" << pcmReader->getName() << "): " << duration << "ms\n";
bool isDefaultStream(pcmReader == streamManager_->getDefaultStream().get());
// logO << "onChunkRead (" << pcmStream->getName() << "): " << duration << "ms\n";
bool isDefaultStream(pcmStream == streamManager_->getDefaultStream().get());
std::shared_ptr<const msg::BaseMessage> shared_message(chunk);
std::lock_guard<std::mutex> mlock(sessionsMutex_);
for (auto s : sessions_)
{
if (!s->pcmReader() && isDefaultStream)//->getName() == "default")
if (!s->pcmStream() && isDefaultStream)//->getName() == "default")
s->add(shared_message);
else if (s->pcmReader().get() == pcmReader)
else if (s->pcmStream().get() == pcmStream)
s->add(shared_message);
}
}
void StreamServer::onResync(const PcmReader* pcmReader, double ms)
void StreamServer::onResync(const PcmStream* pcmStream, double ms)
{
logO << "onResync (" << pcmReader->getName() << "): " << ms << "ms\n";
logO << "onResync (" << pcmStream->getName() << "): " << ms << "ms\n";
}
@ -182,7 +182,7 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
else if (request.method == "Client.SetStream")
{
string streamId = request.getParam("id").get<string>();
PcmReaderPtr stream = streamManager_->getStream(streamId);
PcmStreamPtr stream = streamManager_->getStream(streamId);
if (stream == nullptr)
throw JsonInternalErrorException("Stream not found", request.id);
@ -193,7 +193,7 @@ void StreamServer::onMessageReceived(ControlSession* controlSession, const std::
if (session != NULL)
{
session->add(stream->getHeader());
session->setPcmReader(stream);
session->setPcmStream(stream);
}
}
else if (request.method == "Client.SetLatency")
@ -303,7 +303,7 @@ void StreamServer::onMessageReceived(StreamSession* connection, const msg::BaseM
gettimeofday(&client->lastSeen, NULL);
// Assign and update stream
PcmReaderPtr stream = streamManager_->getStream(client->config.streamId);
PcmStreamPtr stream = streamManager_->getStream(client->config.streamId);
if (stream == nullptr)
{
stream = streamManager_->getDefaultStream();
@ -311,8 +311,8 @@ void StreamServer::onMessageReceived(StreamSession* connection, const msg::BaseM
}
Config::instance().save();
//TODO: wording pcmReader vs stream
connection->setPcmReader(stream);
//TODO: wording pcmStream vs stream
connection->setPcmStream(stream);
auto headerChunk = stream->getHeader();
connection->send(headerChunk.get());

View file

@ -28,7 +28,7 @@
#include <mutex>
#include "streamSession.h"
#include "pcmreader/streamManager.h"
#include "streamreader/streamManager.h"
#include "common/queue.h"
#include "message/message.h"
#include "message/header.h"
@ -64,7 +64,7 @@ struct StreamServerSettings
/// Forwars PCM data to the connected clients
/**
* Reads PCM data using PipeReader, implements PcmListener to get the (encoded) PCM stream.
* Reads PCM data using PipeStream, implements PcmListener to get the (encoded) PCM stream.
* Accepts and holds client connections (StreamSession)
* Receives (via the MessageReceiver interface) and answers messages from the clients
* Forwards PCM data to the clients
@ -89,9 +89,9 @@ public:
virtual void onMessageReceived(ControlSession* connection, const std::string& message);
/// Implementation of PcmListener
virtual void onStateChanged(const PcmReader* pcmReader, const ReaderState& state);
virtual void onChunkRead(const PcmReader* pcmReader, const msg::PcmChunk* chunk, double duration);
virtual void onResync(const PcmReader* pcmReader, double ms);
virtual void onStateChanged(const PcmStream* pcmStream, const ReaderState& state);
virtual void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk* chunk, double duration);
virtual void onResync(const PcmStream* pcmStream, double ms);
private:
void startAccept();

View file

@ -28,7 +28,7 @@ using namespace std;
StreamSession::StreamSession(MessageReceiver* receiver, std::shared_ptr<tcp::socket> socket) :
active_(true), messageReceiver_(receiver), pcmReader_(nullptr)
active_(true), messageReceiver_(receiver), pcmStream_(nullptr)
{
socket_ = socket;
}
@ -40,15 +40,15 @@ StreamSession::~StreamSession()
}
void StreamSession::setPcmReader(PcmReaderPtr pcmReader)
void StreamSession::setPcmStream(PcmStreamPtr pcmStream)
{
pcmReader_ = pcmReader;
pcmStream_ = pcmStream;
}
const PcmReaderPtr StreamSession::pcmReader() const
const PcmStreamPtr StreamSession::pcmStream() const
{
return pcmReader_;
return pcmStream_;
}

View file

@ -29,7 +29,7 @@
#include <set>
#include "message/message.h"
#include "common/queue.h"
#include "pcmreader/streamManager.h"
#include "streamreader/streamManager.h"
using asio::ip::tcp;
@ -80,8 +80,8 @@ public:
return socket_->remote_endpoint().address().to_string();
}
void setPcmReader(PcmReaderPtr pcmReader);
const PcmReaderPtr pcmReader() const;
void setPcmStream(PcmStreamPtr pcmStream);
const PcmStreamPtr pcmStream() const;
protected:
void socketRead(void* _to, size_t _bytes);
@ -100,7 +100,7 @@ protected:
MessageReceiver* messageReceiver_;
Queue<std::shared_ptr<const msg::BaseMessage>> messages_;
size_t bufferMs_;
PcmReaderPtr pcmReader_;
PcmStreamPtr pcmStream_;
};

View file

@ -21,7 +21,7 @@
#include <fcntl.h>
#include <unistd.h>
#include "fileReader.h"
#include "fileStream.h"
#include "../encoder/encoderFactory.h"
#include "common/log.h"
#include "common/snapException.h"
@ -32,7 +32,7 @@ using namespace std;
FileReader::FileReader(PcmListener* pcmListener, const ReaderUri& uri) : PcmReader(pcmListener, uri)
FileStream::FileStream(PcmListener* pcmListener, const StreamUri& uri) : PcmStream(pcmListener, uri)
{
ifs.open(uri_.path.c_str(), std::ifstream::in|std::ifstream::binary);
if (!ifs.good())
@ -43,13 +43,13 @@ FileReader::FileReader(PcmListener* pcmListener, const ReaderUri& uri) : PcmRead
}
FileReader::~FileReader()
FileStream::~FileStream()
{
ifs.close();
}
void FileReader::worker()
void FileStream::worker()
{
timeval tvChunk;
std::unique_ptr<msg::PcmChunk> chunk(new msg::PcmChunk(sampleFormat_, pcmReadMs_));

View file

@ -19,7 +19,7 @@
#ifndef FILE_READER_H
#define FILE_READER_H
#include "pcmReader.h"
#include "pcmStream.h"
#include <fstream>
@ -29,12 +29,12 @@
* Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener
*/
class FileReader : public PcmReader
class FileStream : public PcmStream
{
public:
/// ctor. Encoded PCM data is passed to the PipeListener
FileReader(PcmListener* pcmListener, const ReaderUri& uri);
virtual ~FileReader();
FileStream(PcmListener* pcmListener, const StreamUri& uri);
virtual ~FileStream();
protected:
void worker();

View file

@ -24,7 +24,7 @@
#include "../encoder/encoderFactory.h"
#include "common/snapException.h"
#include "common/compat.h"
#include "pcmReader.h"
#include "pcmStream.h"
#include "common/log.h"
@ -32,7 +32,7 @@ using namespace std;
PcmReader::PcmReader(PcmListener* pcmListener, const ReaderUri& uri) : pcmListener_(pcmListener), uri_(uri), pcmReadMs_(20), state_(kIdle)
PcmStream::PcmStream(PcmListener* pcmListener, const StreamUri& uri) : pcmListener_(pcmListener), uri_(uri), pcmReadMs_(20), state_(kIdle)
{
EncoderFactory encoderFactory;
if (uri_.query.find("codec") == uri_.query.end())
@ -46,55 +46,55 @@ PcmReader::PcmReader(PcmListener* pcmListener, const ReaderUri& uri) : pcmListen
if (uri_.query.find("sampleformat") == uri_.query.end())
throw SnapException("Stream URI must have a sampleformat");
sampleFormat_ = SampleFormat(uri_.query["sampleformat"]);
logE << "PcmReader sampleFormat: " << sampleFormat_.getFormat() << "\n";
logE << "PcmStream sampleFormat: " << sampleFormat_.getFormat() << "\n";
if (uri_.query.find("buffer_ms") != uri_.query.end())
pcmReadMs_ = cpt::stoul(uri_.query["buffer_ms"]);
}
PcmReader::~PcmReader()
PcmStream::~PcmStream()
{
stop();
}
std::shared_ptr<msg::Header> PcmReader::getHeader()
std::shared_ptr<msg::Header> PcmStream::getHeader()
{
return encoder_->getHeader();
}
const ReaderUri& PcmReader::getUri() const
const StreamUri& PcmStream::getUri() const
{
return uri_;
}
const std::string& PcmReader::getName() const
const std::string& PcmStream::getName() const
{
return name_;
}
const SampleFormat& PcmReader::getSampleFormat() const
const SampleFormat& PcmStream::getSampleFormat() const
{
return sampleFormat_;
}
void PcmReader::start()
void PcmStream::start()
{
logE << "PcmReader start: " << sampleFormat_.getFormat() << "\n";
logE << "PcmStream start: " << sampleFormat_.getFormat() << "\n";
//TODO: wrong encoder settings leads to: terminate called after throwing an instance of 'std::system_error' what(): Invalid argument
encoder_->init(this, sampleFormat_);
active_ = true;
readerThread_ = thread(&PcmReader::worker, this);
readerThread_ = thread(&PcmStream::worker, this);
}
void PcmReader::stop()
void PcmStream::stop()
{
if (active_)
{
@ -104,13 +104,13 @@ void PcmReader::stop()
}
ReaderState PcmReader::getState() const
ReaderState PcmStream::getState() const
{
return state_;
}
void PcmReader::setState(const ReaderState& newState)
void PcmStream::setState(const ReaderState& newState)
{
if (newState != state_)
{
@ -120,7 +120,7 @@ void PcmReader::setState(const ReaderState& newState)
}
void PcmReader::onChunkEncoded(const Encoder* encoder, msg::PcmChunk* chunk, double duration)
void PcmStream::onChunkEncoded(const Encoder* encoder, msg::PcmChunk* chunk, double duration)
{
// logO << "onChunkEncoded: " << duration << " us\n";
if (duration <= 0)
@ -133,7 +133,7 @@ void PcmReader::onChunkEncoded(const Encoder* encoder, msg::PcmChunk* chunk, dou
}
json PcmReader::toJson() const
json PcmStream::toJson() const
{
string state("unknown");
if (state_ == kIdle)

View file

@ -23,14 +23,14 @@
#include <atomic>
#include <string>
#include <map>
#include "readerUri.h"
#include "streamUri.h"
#include "../encoder/encoder.h"
#include "../json/json.hpp"
#include "message/sampleFormat.h"
#include "message/header.h"
class PcmReader;
class PcmStream;
enum ReaderState
{
@ -41,16 +41,16 @@ enum ReaderState
};
/// Callback interface for users of PcmReader
/// Callback interface for users of PcmStream
/**
* Users of PcmReader should implement this to get the data
* Users of PcmStream should implement this to get the data
*/
class PcmListener
{
public:
virtual void onStateChanged(const PcmReader* pcmReader, const ReaderState& state) = 0;
virtual void onChunkRead(const PcmReader* pcmReader, const msg::PcmChunk* chunk, double duration) = 0;
virtual void onResync(const PcmReader* pcmReader, double ms) = 0;
virtual void onStateChanged(const PcmStream* pcmStream, const ReaderState& state) = 0;
virtual void onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk* chunk, double duration) = 0;
virtual void onResync(const PcmStream* pcmStream, double ms) = 0;
};
@ -60,12 +60,12 @@ public:
* Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener
*/
class PcmReader : public EncoderListener
class PcmStream : public EncoderListener
{
public:
/// ctor. Encoded PCM data is passed to the PcmListener
PcmReader(PcmListener* pcmListener, const ReaderUri& uri);
virtual ~PcmReader();
PcmStream(PcmListener* pcmListener, const StreamUri& uri);
virtual ~PcmStream();
virtual void start();
virtual void stop();
@ -74,7 +74,7 @@ public:
virtual void onChunkEncoded(const Encoder* encoder, msg::PcmChunk* chunk, double duration);
virtual std::shared_ptr<msg::Header> getHeader();
virtual const ReaderUri& getUri() const;
virtual const StreamUri& getUri() const;
virtual const std::string& getName() const;
virtual const SampleFormat& getSampleFormat() const;
@ -90,7 +90,7 @@ protected:
std::atomic<bool> active_;
std::thread readerThread_;
PcmListener* pcmListener_;
ReaderUri uri_;
StreamUri uri_;
SampleFormat sampleFormat_;
size_t pcmReadMs_;
std::unique_ptr<Encoder> encoder_;

View file

@ -21,7 +21,7 @@
#include <fcntl.h>
#include <unistd.h>
#include "pipeReader.h"
#include "pipeStream.h"
#include "../encoder/encoderFactory.h"
#include "common/log.h"
#include "common/snapException.h"
@ -33,7 +33,7 @@ using namespace std;
PipeReader::PipeReader(PcmListener* pcmListener, const ReaderUri& uri) : PcmReader(pcmListener, uri), fd_(-1)
PipeStream::PipeStream(PcmListener* pcmListener, const StreamUri& uri) : PcmStream(pcmListener, uri), fd_(-1)
{
umask(0);
if ((mkfifo(uri_.path.c_str(), 0666) != 0) && (errno != EEXIST))
@ -41,14 +41,14 @@ PipeReader::PipeReader(PcmListener* pcmListener, const ReaderUri& uri) : PcmRead
}
PipeReader::~PipeReader()
PipeStream::~PipeStream()
{
if (fd_ != -1)
close(fd_);
}
void PipeReader::worker()
void PipeStream::worker()
{
timeval tvChunk;
std::unique_ptr<msg::PcmChunk> chunk(new msg::PcmChunk(sampleFormat_, pcmReadMs_));

View file

@ -16,10 +16,10 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef PIPE_READER_H
#define PIPE_READER_H
#ifndef PIPE_STREAM_H
#define PIPE_STREAM_H
#include "pcmReader.h"
#include "pcmStream.h"
@ -29,12 +29,12 @@
* Implements EncoderListener to get the encoded data.
* Data is passed to the PcmListener
*/
class PipeReader : public PcmReader
class PipeStream : public PcmStream
{
public:
/// ctor. Encoded PCM data is passed to the PipeListener
PipeReader(PcmListener* pcmListener, const ReaderUri& uri);
virtual ~PipeReader();
PipeStream(PcmListener* pcmListener, const StreamUri& uri);
virtual ~PipeStream();
protected:
void worker();

View file

@ -18,8 +18,8 @@
#include "common/utils.h"
#include "streamManager.h"
#include "pipeReader.h"
#include "fileReader.h"
#include "pipeStream.h"
#include "fileStream.h"
#include "common/log.h"
#include "common/snapException.h"
@ -32,51 +32,51 @@ StreamManager::StreamManager(PcmListener* pcmListener, const std::string& defaul
}
PcmReader* StreamManager::addStream(const std::string& uri)
PcmStream* StreamManager::addStream(const std::string& uri)
{
ReaderUri readerUri(uri);
StreamUri streamUri(uri);
if (readerUri.query.find("sampleformat") == readerUri.query.end())
readerUri.query["sampleformat"] = sampleFormat_;
if (streamUri.query.find("sampleformat") == streamUri.query.end())
streamUri.query["sampleformat"] = sampleFormat_;
if (readerUri.query.find("codec") == readerUri.query.end())
readerUri.query["codec"] = codec_;
if (streamUri.query.find("codec") == streamUri.query.end())
streamUri.query["codec"] = codec_;
if (readerUri.query.find("buffer_ms") == readerUri.query.end())
readerUri.query["buffer_ms"] = to_string(readBufferMs_);
if (streamUri.query.find("buffer_ms") == streamUri.query.end())
streamUri.query["buffer_ms"] = to_string(readBufferMs_);
// logE << "\nURI: " << readerUri.uri << "\nscheme: " << readerUri.scheme << "\nhost: "
// << readerUri.host << "\npath: " << readerUri.path << "\nfragment: " << readerUri.fragment << "\n";
// logE << "\nURI: " << streamUri.uri << "\nscheme: " << streamUri.scheme << "\nhost: "
// << streamUri.host << "\npath: " << streamUri.path << "\nfragment: " << streamUri.fragment << "\n";
// for (auto kv: readerUri.query)
// for (auto kv: streamUri.query)
// logE << "key: '" << kv.first << "' value: '" << kv.second << "'\n";
if (readerUri.scheme == "pipe")
if (streamUri.scheme == "pipe")
{
streams_.push_back(make_shared<PipeReader>(pcmListener_, readerUri));
streams_.push_back(make_shared<PipeStream>(pcmListener_, streamUri));
return streams_.back().get();
}
else if (readerUri.scheme == "file")
else if (streamUri.scheme == "file")
{
streams_.push_back(make_shared<FileReader>(pcmListener_, readerUri));
streams_.push_back(make_shared<FileStream>(pcmListener_, streamUri));
return streams_.back().get();
}
else
{
throw SnapException("Unknown stream type: " + readerUri.scheme);
throw SnapException("Unknown stream type: " + streamUri.scheme);
}
return NULL;
}
const std::vector<PcmReaderPtr>& StreamManager::getStreams()
const std::vector<PcmStreamPtr>& StreamManager::getStreams()
{
return streams_;
}
const PcmReaderPtr StreamManager::getDefaultStream()
const PcmStreamPtr StreamManager::getDefaultStream()
{
if (streams_.empty())
return nullptr;
@ -85,7 +85,7 @@ const PcmReaderPtr StreamManager::getDefaultStream()
}
const PcmReaderPtr StreamManager::getStream(const std::string& id)
const PcmStreamPtr StreamManager::getStream(const std::string& id)
{
for (auto stream: streams_)
{

View file

@ -4,25 +4,25 @@
#include <string>
#include <vector>
#include <memory>
#include "pcmReader.h"
#include "pcmStream.h"
typedef std::shared_ptr<PcmReader> PcmReaderPtr;
typedef std::shared_ptr<PcmStream> PcmStreamPtr;
class StreamManager
{
public:
StreamManager(PcmListener* pcmListener, const std::string& defaultSampleFormat, const std::string& defaultCodec, size_t defaultReadBufferMs = 20);
PcmReader* addStream(const std::string& uri);
PcmStream* addStream(const std::string& uri);
void start();
void stop();
const std::vector<PcmReaderPtr>& getStreams();
const PcmReaderPtr getDefaultStream();
const PcmReaderPtr getStream(const std::string& id);
const std::vector<PcmStreamPtr>& getStreams();
const PcmStreamPtr getDefaultStream();
const PcmStreamPtr getStream(const std::string& id);
json toJson() const;
private:
std::vector<PcmReaderPtr> streams_;
std::vector<PcmStreamPtr> streams_;
PcmListener* pcmListener_;
std::string sampleFormat_;
std::string codec_;

View file

@ -20,27 +20,27 @@
#include <common/utils.h>
#include <common/compat.h>
#include <common/log.h>
#include "readerUri.h"
#include "streamUri.h"
using namespace std;
ReaderUri::ReaderUri(const std::string& readerUri)
StreamUri::StreamUri(const std::string& streamUri)
{
// https://en.wikipedia.org/wiki/Uniform_Resource_Identifier
// scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]
// would be more elegant with regex. Not yet supported on my dev machine's gcc 4.8 :(
logE << "ReaderUri: " << readerUri << "\n";
logE << "StreamUri: " << streamUri << "\n";
size_t pos;
uri = trim_copy(readerUri);
uri = trim_copy(streamUri);
while (!uri.empty() && ((uri[0] == '\'') || (uri[0] == '"')))
uri = uri.substr(1);
while (!uri.empty() && ((uri[uri.length()-1] == '\'') || (uri[uri.length()-1] == '"')))
uri = uri.substr(0, this->uri.length()-1);
string decodedUri = uriDecode(uri);
logD << "ReaderUri: " << decodedUri << "\n";
logD << "StreamUri: " << decodedUri << "\n";
id_ = decodedUri;
pos = id_.find('?');
@ -106,7 +106,7 @@ ReaderUri::ReaderUri(const std::string& readerUri)
}
json ReaderUri::toJson() const
json StreamUri::toJson() const
{
json j = {
{"raw", uri},
@ -120,7 +120,7 @@ json ReaderUri::toJson() const
}
std::string ReaderUri::id() const
std::string StreamUri::id() const
{
return id_;
}

View file

@ -26,9 +26,9 @@
using json = nlohmann::json;
struct ReaderUri
struct StreamUri
{
ReaderUri(const std::string& uri);
StreamUri(const std::string& uri);
std::string uri;
std::string scheme;
/* struct Authority