diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2016-10-30 15:29:31 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2016-10-30 15:29:31 +0100 |
commit | 128768f7fd719eb455a946a0f716d7128b4ded63 (patch) | |
tree | dfa03ccfed3f175182b04fd84bd59aacd623ac54 | |
parent | 555121f96e769fdeb9529e7381560d8bbb6e2713 (diff) | |
download | dabmux-128768f7fd719eb455a946a0f716d7128b4ded63.tar.gz dabmux-128768f7fd719eb455a946a0f716d7128b4ded63.tar.bz2 dabmux-128768f7fd719eb455a946a0f716d7128b4ded63.zip |
Start reworking inputs, break all but Prbs and ZMQ
-rw-r--r-- | src/ConfigParser.cpp | 178 | ||||
-rw-r--r-- | src/DabMux.cpp | 18 | ||||
-rw-r--r-- | src/DabMux.h | 7 | ||||
-rw-r--r-- | src/Makefile.am | 20 | ||||
-rw-r--r-- | src/MuxElements.h | 4 | ||||
-rw-r--r-- | src/dabInput.h | 15 | ||||
-rw-r--r-- | src/input/Prbs.cpp (renamed from src/dabInputPrbs.cpp) | 15 | ||||
-rw-r--r-- | src/input/Prbs.h (renamed from src/dabInputPrbs.h) | 8 | ||||
-rw-r--r-- | src/input/Zmq.cpp (renamed from src/dabInputZmq.cpp) | 46 | ||||
-rw-r--r-- | src/input/Zmq.h (renamed from src/dabInputZmq.h) | 39 |
10 files changed, 225 insertions, 125 deletions
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 7e3f855..bdc2099 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -48,27 +48,14 @@ #include <map> #include <cstring> #include "dabOutput/dabOutput.h" -#include "dabInput.h" +#include "input/inputs.h" #include "utils.h" -#include "dabInputFile.h" -#include "dabInputFifo.h" -#include "dabInputMpegFile.h" -#include "dabInputMpegFifo.h" -#include "dabInputDabplusFile.h" -#include "dabInputDabplusFifo.h" -#include "dabInputPacketFile.h" -#include "dabInputEnhancedPacketFile.h" -#include "dabInputEnhancedFifo.h" -#include "dabInputUdp.h" -#include "dabInputPrbs.h" -#include "dabInputRawFile.h" -#include "dabInputRawFifo.h" -#include "dabInputDmbFile.h" -#include "dabInputDmbUdp.h" -#include "dabInputZmq.h" #include "DabMux.h" #include "ManagementServer.h" +#include "input/Prbs.h" +#include "input/Zmq.h" + #ifdef _WIN32 # pragma warning ( disable : 4103 ) @@ -541,13 +528,13 @@ void parse_ptree( } } -static dab_input_zmq_config_t setup_zmq_input( +static Inputs::dab_input_zmq_config_t setup_zmq_input( const boost::property_tree::ptree &pt, const std::string& subchanuid) { using boost::property_tree::ptree_error; - dab_input_zmq_config_t zmqconfig; + Inputs::dab_input_zmq_config_t zmqconfig; try { zmqconfig.buffer_size = pt.get<int>("zmq-buffer"); @@ -621,6 +608,7 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan, subchan->inputUri = inputUri; +#if OLD_INPUTS // {{{ /* The input is of the old_style type, * with the struct of function pointers, * and needs to be a DabInputCompatible @@ -714,7 +702,7 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan, } else if (type == "data" and proto == "prbs") { input_is_old_style = false; - subchan->input = new DabInputPrbs(); + subchan->input = make_shared<Inputs::Prbs>(); subchan->type = subchannel_type_t::DataDmb; subchan->bitrate = DEFAULT_DATA_BITRATE; } else if (type == "data") { @@ -928,5 +916,155 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan, subchan->input = new DabInputCompatible(operations); } // else { it's already been created! } +#endif // 0 }}} + + dabProtection* protection = &subchan->protection; + + const bool nonblock = pt.get("nonblock", false); + + if (type == "dabplus" or type == "audio") { + subchan->type = subchannel_type_t::Audio; + subchan->bitrate = 0; + + if (proto == "file") { + if (nonblock) { + // TODO + } + } + else if (proto == "tcp" || + proto == "epgm" || + proto == "ipc") { + + if (nonblock) { + etiLog.level(warn) << "The nonblock option is meaningless for the zmq input"; + } + + auto zmqconfig = setup_zmq_input(pt, subchanuid); + + if (type == "audio") { + auto inzmq = make_shared<Inputs::ZmqMPEG>(subchanuid, zmqconfig); + rcs.enrol(inzmq.get()); + subchan->input = inzmq; + } + else if (type == "dabplus") { + auto inzmq = make_shared<Inputs::ZmqAAC>(subchanuid, zmqconfig); + rcs.enrol(inzmq.get()); + subchan->input = inzmq; + } + + if (proto == "epgm") { + etiLog.level(warn) << "Using untested epgm:// zeromq input"; + } + else if (proto == "ipc") { + etiLog.level(warn) << "Using untested ipc:// zeromq input"; + } + } + else { + stringstream ss; + ss << "Subchannel with uid " << subchanuid << + ": Invalid protocol for " << type << " input (" << + proto << ")" << endl; + throw runtime_error(ss.str()); + } + } + else if (type == "data" and proto == "prbs") { + subchan->input = make_shared<Inputs::Prbs>(); + subchan->type = subchannel_type_t::DataDmb; + subchan->bitrate = DEFAULT_DATA_BITRATE; + } + else { + stringstream ss; + ss << "Subchannel with uid " << subchanuid << " has unknown type!"; + throw runtime_error(ss.str()); + } + subchan->startAddress = 0; + + if (type == "audio") { + protection->form = UEP; + protection->level = 2; + protection->uep.tableIndex = 0; + } + else { + protection->level = 2; + protection->form = EEP; + protection->eep.profile = EEP_A; + } + + /* Get bitrate */ + try { + subchan->bitrate = pt.get<int>("bitrate"); + if ((subchan->bitrate & 0x7) != 0) { + stringstream ss; + ss << "Subchannel with uid " << subchanuid << + ": Bitrate (" << subchan->bitrate << " not a multiple of 8!"; + throw runtime_error(ss.str()); + } + } + catch (ptree_error &e) { + stringstream ss; + ss << "Error, no bitrate defined for subchannel " << subchanuid; + throw runtime_error(ss.str()); + } + + /* Get id */ + try { + subchan->id = hexparse(pt.get<std::string>("id")); + } + catch (ptree_error &e) { + for (int i = 0; i < 64; ++i) { // Find first free subchannel + vector<DabSubchannel*>::iterator subchannel = getSubchannel(ensemble->subchannels, i); + if (subchannel == ensemble->subchannels.end()) { + subchannel = ensemble->subchannels.end() - 1; + subchan->id = i; + break; + } + } + } + + /* Get optional protection profile */ + string profile = pt.get("protection-profile", ""); + + if (profile == "EEP_A") { + protection->form = EEP; + protection->eep.profile = EEP_A; + } + else if (profile == "EEP_B") { + protection->form = EEP; + protection->eep.profile = EEP_B; + } + else if (profile == "UEP") { + protection->form = UEP; + } + + /* Get protection level */ + try { + int level = pt.get<int>("protection"); + + if (protection->form == UEP) { + if ((level < 1) || (level > 5)) { + stringstream ss; + ss << "Subchannel with uid " << subchanuid << + ": protection level must be between " + "1 to 5 inclusively (current = " << level << " )"; + throw runtime_error(ss.str()); + } + } + else if (protection->form == EEP) { + if ((level < 1) || (level > 4)) { + stringstream ss; + ss << "Subchannel with uid " << subchanuid << + ": protection level must be between " + "1 to 4 inclusively (current = " << level << " )"; + throw runtime_error(ss.str()); + } + } + protection->level = level - 1; + } + catch (ptree_error &e) { + stringstream ss; + ss << "Subchannel with uid " << subchanuid << + ": protection level undefined!"; + throw runtime_error(ss.str()); + } } diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 32ddb39..3927420 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -94,22 +94,8 @@ typedef DWORD32 uint32_t; # include "Eti.h" #endif -#include "dabInputFile.h" -#include "dabInputFifo.h" -#include "dabInputMpegFile.h" -#include "dabInputMpegFifo.h" -#include "dabInputDabplusFile.h" -#include "dabInputDabplusFifo.h" -#include "dabInputPacketFile.h" -#include "dabInputEnhancedPacketFile.h" -#include "dabInputEnhancedFifo.h" -#include "dabInputUdp.h" -#include "dabInputPrbs.h" -#include "dabInputRawFile.h" -#include "dabInputRawFifo.h" -#include "dabInputDmbFile.h" -#include "dabInputDmbUdp.h" - +#include "input/Prbs.h" +#include "input/Zmq.h" #include "dabOutput/dabOutput.h" #include "dabOutput/edi/TagItems.h" diff --git a/src/DabMux.h b/src/DabMux.h index 5dda759..80b4881 100644 --- a/src/DabMux.h +++ b/src/DabMux.h @@ -25,8 +25,7 @@ You should have received a copy of the GNU General Public License along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _DABMUX_H -#define _DABMUX_H +#pragma once #include <stdint.h> #include <string> @@ -34,7 +33,7 @@ #include "DabMultiplexer.h" #include "RemoteControl.h" #include "dabOutput/dabOutput.h" -#include "dabInput.h" +#include "input/inputs.h" #include "Eti.h" #include "MuxElements.h" @@ -44,5 +43,3 @@ # include <sys/time.h> #endif -#endif - diff --git a/src/Makefile.am b/src/Makefile.am index 408c86e..b8de4e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -47,23 +47,9 @@ odr_dabmux_LDADD =$(ZMQ_LIBS) $(CURL_LIBS) \ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \ DabMultiplexer.cpp DabMultiplexer.h \ - dabInput.h dabInput.cpp \ - dabInputDabplusFifo.h dabInputDabplusFifo.cpp \ - dabInputDabplusFile.h dabInputDabplusFile.cpp \ - dabInputDmbFile.h dabInputDmbFile.cpp \ - dabInputDmbUdp.h dabInputDmbUdp.cpp \ - dabInputEnhancedFifo.h dabInputEnhancedFifo.cpp \ - dabInputEnhancedPacketFile.h dabInputEnhancedPacketFile.cpp \ - dabInputFifo.h dabInputFifo.cpp \ - dabInputFile.h dabInputFile.cpp \ - dabInputMpegFifo.h dabInputMpegFifo.cpp \ - dabInputMpegFile.h dabInputMpegFile.cpp \ - dabInputPacketFile.h dabInputPacketFile.cpp \ - dabInputPrbs.h dabInputPrbs.cpp \ - dabInputRawFile.h dabInputRawFile.cpp \ - dabInputRawFifo.h dabInputRawFifo.cpp \ - dabInputUdp.h dabInputUdp.cpp \ - dabInputZmq.h dabInputZmq.cpp \ + input/inputs.h \ + input/Prbs.cpp input/Prbs.h \ + input/Zmq.cpp input/Zmq.h \ dabOutput/dabOutput.h \ dabOutput/dabOutputFile.cpp \ dabOutput/dabOutputFifo.cpp \ diff --git a/src/MuxElements.h b/src/MuxElements.h index 7056121..7324cdc 100644 --- a/src/MuxElements.h +++ b/src/MuxElements.h @@ -40,7 +40,7 @@ #include <boost/optional.hpp> #include <stdint.h> #include "dabOutput/dabOutput.h" -#include "dabInput.h" +#include "input/inputs.h" #include "RemoteControl.h" #include "Eti.h" @@ -295,7 +295,7 @@ public: std::string uid; std::string inputUri; - DabInputBase* input; + std::shared_ptr<Inputs::InputBase> input; unsigned char id; subchannel_type_t type; uint16_t startAddress; diff --git a/src/dabInput.h b/src/dabInput.h index d5444cd..0accddb 100644 --- a/src/dabInput.h +++ b/src/dabInput.h @@ -29,8 +29,6 @@ #include "RemoteControl.h" #include <string> -extern Logger etiLog; - // TODO replace usage of dabInputOperations by a // class hierarchy struct dabInputOperations { @@ -48,19 +46,6 @@ struct dabInputOperations { bool operator==(const dabInputOperations&); }; -/* New input object base */ -class DabInputBase { - public: - virtual int open(const std::string& name) = 0; - virtual int readFrame(void* buffer, int size) = 0; - virtual int setBitrate(int bitrate) = 0; - virtual int close() = 0; - - virtual ~DabInputBase() {} - protected: - DabInputBase() {} -}; - /* Wrapper class for old-style dabInputOperations inputs */ class DabInputCompatible : public DabInputBase { public: diff --git a/src/dabInputPrbs.cpp b/src/input/Prbs.cpp index 2678668..b9e244b 100644 --- a/src/dabInputPrbs.cpp +++ b/src/input/Prbs.cpp @@ -26,7 +26,7 @@ along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. */ -#include "dabInputPrbs.h" +#include "input/Prbs.h" #include <stdexcept> #include <sstream> @@ -38,11 +38,13 @@ using namespace std; +namespace Inputs { + // ETS 300 799 Clause G.2.1 // Preferred polynomial is G(x) = x^20 + x^17 + 1 const uint32_t PRBS_DEFAULT_POLY = (1 << 19) | (1 << 16) | 1; -int DabInputPrbs::open(const string& name) +int Prbs::open(const string& name) { if (name.empty()) { m_prbs.setup(PRBS_DEFAULT_POLY); @@ -69,7 +71,7 @@ int DabInputPrbs::open(const string& name) return 0; } -int DabInputPrbs::readFrame(void* buffer, int size) +int Prbs::readFrame(void* buffer, int size) { unsigned char* cbuffer = reinterpret_cast<unsigned char*>(buffer); @@ -80,19 +82,20 @@ int DabInputPrbs::readFrame(void* buffer, int size) return size; } -int DabInputPrbs::setBitrate(int bitrate) +int Prbs::setBitrate(int bitrate) { return bitrate; } -int DabInputPrbs::close() +int Prbs::close() { return 0; } -int DabInputPrbs::rewind() +int Prbs::rewind() { m_prbs.rewind(); return 0; } +}; diff --git a/src/dabInputPrbs.h b/src/input/Prbs.h index 95c5e25..47b52ad 100644 --- a/src/dabInputPrbs.h +++ b/src/input/Prbs.h @@ -34,10 +34,12 @@ #include <string> -#include "dabInput.h" +#include "input/inputs.h" #include "prbs.h" -class DabInputPrbs : public DabInputBase { +namespace Inputs { + +class Prbs : public InputBase { public: virtual int open(const std::string& name); virtual int readFrame(void* buffer, int size); @@ -50,3 +52,5 @@ class DabInputPrbs : public DabInputBase { PrbsGenerator m_prbs; }; +}; + diff --git a/src/dabInputZmq.cpp b/src/input/Zmq.cpp index 93f1ea3..6ef5fce 100644 --- a/src/dabInputZmq.cpp +++ b/src/input/Zmq.cpp @@ -2,7 +2,7 @@ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2013, 2014 Matthias P. Braendli + Copyright (C) 2016 Matthias P. Braendli http://www.opendigitalradio.org ZeroMQ input. see www.zeromq.org for more info @@ -39,9 +39,7 @@ along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. */ -#include "dabInput.h" -#include "dabInputZmq.h" -#include "PcDebug.h" +#include "input/Zmq.h" #ifdef HAVE_CONFIG_H # include "config.h" @@ -58,22 +56,28 @@ #include <string> #include <sstream> #include <limits.h> +#include "PcDebug.h" +#include "Log.h" #ifdef __MINGW32__ # define bzero(s, n) memset(s, 0, n) #endif +namespace Inputs { + using namespace std; int readkey(string& keyfile, char* key) { - int fd = open(keyfile.c_str(), O_RDONLY); - if (fd < 0) - return fd; - int ret = read(fd, key, CURVE_KEYLEN); - close(fd); - if (ret < 0) { - return ret; + FILE* fd = fopen(keyfile.c_str(), "r"); + if (fd == nullptr) { + return -1; + } + + int ret = fread(key, CURVE_KEYLEN, 1, fd); + fclose(fd); + if (ret == 0) { + return -1; } /* It needs to be zero-terminated */ @@ -89,7 +93,7 @@ int readkey(string& keyfile, char* key) * keys to the socket, and finally bind the socket * to the new address */ -void DabInputZmqBase::rebind() +void ZmqBase::rebind() { if (! m_zmq_sock_bound_to.empty()) { try { @@ -223,7 +227,7 @@ void DabInputZmqBase::rebind() } } -int DabInputZmqBase::open(const std::string& inputUri) +int ZmqBase::open(const std::string& inputUri) { m_inputUri = inputUri; @@ -236,20 +240,20 @@ int DabInputZmqBase::open(const std::string& inputUri) return 0; } -int DabInputZmqBase::close() +int ZmqBase::close() { m_zmq_sock.close(); return 0; } -int DabInputZmqBase::setBitrate(int bitrate) +int ZmqBase::setBitrate(int bitrate) { m_bitrate = bitrate; return bitrate; // TODO do a nice check here } // size corresponds to a frame size. It is constant for a given bitrate -int DabInputZmqBase::readFrame(void* buffer, int size) +int ZmqBase::readFrame(void* buffer, int size) { int rc; @@ -340,7 +344,7 @@ int DabInputZmqBase::readFrame(void* buffer, int size) /******** MPEG input *******/ // Read a MPEG frame from the socket, and push to list -int DabInputZmqMPEG::readFromSocket(size_t framesize) +int ZmqMPEG::readFromSocket(size_t framesize) { bool messageReceived = false; zmq::message_t msg; @@ -410,7 +414,7 @@ int DabInputZmqMPEG::readFromSocket(size_t framesize) // Read a AAC+ superframe from the socket, cut it into five frames, // and push to list -int DabInputZmqAAC::readFromSocket(size_t framesize) +int ZmqAAC::readFromSocket(size_t framesize) { bool messageReceived; zmq::message_t msg; @@ -496,7 +500,7 @@ int DabInputZmqAAC::readFromSocket(size_t framesize) /********* REMOTE CONTROL ***********/ -void DabInputZmqBase::set_parameter(const string& parameter, +void ZmqBase::set_parameter(const string& parameter, const string& value) { if (parameter == "buffer") { @@ -576,7 +580,7 @@ void DabInputZmqBase::set_parameter(const string& parameter, } } -const string DabInputZmqBase::get_parameter(const string& parameter) const +const string ZmqBase::get_parameter(const string& parameter) const { stringstream ss; if (parameter == "buffer") { @@ -615,5 +619,7 @@ const string DabInputZmqBase::get_parameter(const string& parameter) const } +}; + #endif diff --git a/src/dabInputZmq.h b/src/input/Zmq.h index 351fb07..d1dd2d5 100644 --- a/src/dabInputZmq.h +++ b/src/input/Zmq.h @@ -2,7 +2,7 @@ Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) - Copyright (C) 2013, 2014 Matthias P. Braendli + Copyright (C) 2016 Matthias P. Braendli http://www.opendigitalradio.org ZeroMQ input. see www.zeromq.org for more info @@ -41,8 +41,7 @@ along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef DAB_INPUT_ZMQ_H -#define DAB_INPUT_ZMQ_H +#pragma once #ifdef HAVE_CONFIG_H # include "config.h" @@ -54,35 +53,31 @@ #include <string> #include <stdint.h> #include "zmq.hpp" -#include "dabInput.h" +#include "input/inputs.h" #include "ManagementServer.h" +namespace Inputs { + /* The frame_buffer contains DAB logical frames as defined in * TS 102 563, section 6. * Five elements of this buffer make one AAC superframe (120ms audio) */ -// Number of elements to prebuffer before starting the pipeline -#define INPUT_ZMQ_DEF_PREBUFFERING (5*4) // 480ms - -// Default frame_buffer size in number of elements -#define INPUT_ZMQ_DEF_BUFFER_SIZE (5*8) // 960ms - // Minimum frame_buffer size in number of elements // This is one AAC superframe, but you probably don't want to // go that low anyway. -#define INPUT_ZMQ_MIN_BUFFER_SIZE (5*1) // 120ms +const size_t INPUT_ZMQ_MIN_BUFFER_SIZE = 5*1; // 120ms // Maximum frame_buffer size in number of elements // One minute is clearly way over what everybody would // want. -#define INPUT_ZMQ_MAX_BUFFER_SIZE (5*500) // 60s +const size_t INPUT_ZMQ_MAX_BUFFER_SIZE = 5*500; // 60s /* The ZeroMQ Curve key is 40 bytes long in Z85 representation * * But we need to store it as zero-terminated string. */ -#define CURVE_KEYLEN 40 +const size_t CURVE_KEYLEN = 40; /* helper to invalidate a key */ #define INVALIDATE_KEY(k) memset(k, 0, CURVE_KEYLEN+1) @@ -156,9 +151,9 @@ struct zmq_frame_header_t #define ZMQ_FRAME_DATA(f) ( ((uint8_t*)f)+sizeof(zmq_frame_header_t) ) -class DabInputZmqBase : public DabInputBase, public RemoteControllable { +class ZmqBase : public InputBase, public RemoteControllable { public: - DabInputZmqBase(const std::string name, + ZmqBase(const std::string name, dab_input_zmq_config_t config) : RemoteControllable(name), m_zmq_context(1), @@ -238,11 +233,11 @@ class DabInputZmqBase : public DabInputBase, public RemoteControllable { size_t m_prebuf_current; }; -class DabInputZmqMPEG : public DabInputZmqBase { +class ZmqMPEG : public ZmqBase { public: - DabInputZmqMPEG(const std::string name, + ZmqMPEG(const std::string name, dab_input_zmq_config_t config) - : DabInputZmqBase(name, config) { + : ZmqBase(name, config) { RC_ADD_PARAMETER(buffer, "Size of the input buffer [mpeg frames]"); @@ -254,11 +249,11 @@ class DabInputZmqMPEG : public DabInputZmqBase { virtual int readFromSocket(size_t framesize); }; -class DabInputZmqAAC : public DabInputZmqBase { +class ZmqAAC : public ZmqBase { public: - DabInputZmqAAC(const std::string name, + ZmqAAC(const std::string name, dab_input_zmq_config_t config) - : DabInputZmqBase(name, config) { + : ZmqBase(name, config) { RC_ADD_PARAMETER(buffer, "Size of the input buffer [aac superframes]"); @@ -270,7 +265,7 @@ class DabInputZmqAAC : public DabInputZmqBase { virtual int readFromSocket(size_t framesize); }; +}; #endif // HAVE_INPUT_ZMQ -#endif // DAB_INPUT_ZMQ_H |