From d0d31db28c81559e0c4c0f93fafc9b6e762eb817 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 30 Oct 2016 11:59:36 +0100 Subject: Make DabInputBase::open take a reference --- src/dabInput.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/dabInput.h') diff --git a/src/dabInput.h b/src/dabInput.h index f1b4348..d5444cd 100644 --- a/src/dabInput.h +++ b/src/dabInput.h @@ -51,7 +51,7 @@ struct dabInputOperations { /* New input object base */ class DabInputBase { public: - virtual int open(const std::string name) = 0; + 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; @@ -71,7 +71,7 @@ class DabInputCompatible : public DabInputBase { virtual ~DabInputCompatible() { m_ops.clean(&args); } - virtual int open(const std::string name) + virtual int open(const std::string& name) { return m_ops.open(args, name.c_str()); } virtual int setbuf(int size) -- cgit v1.2.3 From 128768f7fd719eb455a946a0f716d7128b4ded63 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Sun, 30 Oct 2016 15:29:31 +0100 Subject: Start reworking inputs, break all but Prbs and ZMQ --- src/ConfigParser.cpp | 178 +++++++++++++-- src/DabMux.cpp | 18 +- src/DabMux.h | 7 +- src/Makefile.am | 20 +- src/MuxElements.h | 4 +- src/dabInput.h | 15 -- src/dabInputPrbs.cpp | 98 -------- src/dabInputPrbs.h | 52 ----- src/dabInputZmq.cpp | 619 -------------------------------------------------- src/dabInputZmq.h | 276 ----------------------- src/input/Prbs.cpp | 101 +++++++++ src/input/Prbs.h | 56 +++++ src/input/Zmq.cpp | 625 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/input/Zmq.h | 271 ++++++++++++++++++++++ 14 files changed, 1220 insertions(+), 1120 deletions(-) delete mode 100644 src/dabInputPrbs.cpp delete mode 100644 src/dabInputPrbs.h delete mode 100644 src/dabInputZmq.cpp delete mode 100644 src/dabInputZmq.h create mode 100644 src/input/Prbs.cpp create mode 100644 src/input/Prbs.h create mode 100644 src/input/Zmq.cpp create mode 100644 src/input/Zmq.h (limited to 'src/dabInput.h') 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 #include #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("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(); 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(subchanuid, zmqconfig); + rcs.enrol(inzmq.get()); + subchan->input = inzmq; + } + else if (type == "dabplus") { + auto inzmq = make_shared(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(); + 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("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("id")); + } + catch (ptree_error &e) { + for (int i = 0; i < 64; ++i) { // Find first free subchannel + vector::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("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 . */ -#ifndef _DABMUX_H -#define _DABMUX_H +#pragma once #include #include @@ -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 #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 #include #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 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 -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/dabInputPrbs.cpp deleted file mode 100644 index 2678668..0000000 --- a/src/dabInputPrbs.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Copyright (C) 2016 - Matthias P. Braendli, matthias.braendli@mpb.li - - http://www.opendigitalradio.org - - Pseudo-Random Bit Sequence generator for test purposes. - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputPrbs.h" - -#include -#include -#include -#include -#include -#include -#include "utils.h" - -using namespace std; - -// 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) -{ - if (name.empty()) { - m_prbs.setup(PRBS_DEFAULT_POLY); - } - else { - if (name[0] != ':') { - throw invalid_argument( - "Invalid PRBS address format. " - "Must be prbs://:polynomial."); - } - - const string poly_str = name.substr(1); - - long polynomial = hexparse(poly_str); - - if (polynomial == 0) { - throw invalid_argument("No polynomial given for PRBS input"); - } - - m_prbs.setup(polynomial); - } - rewind(); - - return 0; -} - -int DabInputPrbs::readFrame(void* buffer, int size) -{ - unsigned char* cbuffer = reinterpret_cast(buffer); - - for (int i = 0; i < size; ++i) { - cbuffer[i] = m_prbs.step(); - } - - return size; -} - -int DabInputPrbs::setBitrate(int bitrate) -{ - return bitrate; -} - -int DabInputPrbs::close() -{ - return 0; -} - -int DabInputPrbs::rewind() -{ - m_prbs.rewind(); - return 0; -} - diff --git a/src/dabInputPrbs.h b/src/dabInputPrbs.h deleted file mode 100644 index 95c5e25..0000000 --- a/src/dabInputPrbs.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Copyright (C) 2016 - Matthias P. Braendli, matthias.braendli@mpb.li - - http://www.opendigitalradio.org - - Pseudo-Random Bit Sequence generator for test purposes. - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#pragma once - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include "dabInput.h" -#include "prbs.h" - -class DabInputPrbs : public DabInputBase { - public: - virtual int open(const std::string& name); - virtual int readFrame(void* buffer, int size); - virtual int setBitrate(int bitrate); - virtual int close(); - - private: - virtual int rewind(); - - PrbsGenerator m_prbs; -}; - diff --git a/src/dabInputZmq.cpp b/src/dabInputZmq.cpp deleted file mode 100644 index 93f1ea3..0000000 --- a/src/dabInputZmq.cpp +++ /dev/null @@ -1,619 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Copyright (C) 2013, 2014 Matthias P. Braendli - http://www.opendigitalradio.org - - ZeroMQ input. see www.zeromq.org for more info - - For the AAC+ input, each zeromq message must contain one superframe - or one zmq_frame_header_t followed by a superframe. - - For the MPEG input, each zeromq message must contain one frame. - - Encryption is provided by zmq_curve, see the corresponding manpage. - - From the ZeroMQ manpage 'zmq': - - The 0MQ lightweight messaging kernel is a library which extends the standard - socket interfaces with features traditionally provided by specialised - messaging middleware products. 0MQ sockets provide an abstraction of - asynchronous message queues, multiple messaging patterns, message filtering - (subscriptions), seamless access to multiple transport protocols and more. - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInput.h" -#include "dabInputZmq.h" -#include "PcDebug.h" - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_INPUT_ZEROMQ - -#include "zmq.hpp" -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __MINGW32__ -# define bzero(s, n) memset(s, 0, n) -#endif - -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; - } - - /* It needs to be zero-terminated */ - key[CURVE_KEYLEN] = '\0'; - - return 0; -} - -/***** Common functions (MPEG and AAC) ******/ - -/* If necessary, unbind the socket, then check the keys, - * if they are ok and encryption is required, set the - * keys to the socket, and finally bind the socket - * to the new address - */ -void DabInputZmqBase::rebind() -{ - if (! m_zmq_sock_bound_to.empty()) { - try { - m_zmq_sock.unbind(m_zmq_sock_bound_to.c_str()); - } - catch (zmq::error_t& err) { - etiLog.level(warn) << "ZMQ unbind for input " << m_name << " failed"; - } - } - - m_zmq_sock_bound_to = ""; - - /* Load each key independently */ - if (! m_config.curve_public_keyfile.empty()) { - int rc = readkey(m_config.curve_public_keyfile, m_curve_public_key); - - if (rc < 0) { - etiLog.level(warn) << "Invalid public key for input " << - m_name; - - INVALIDATE_KEY(m_curve_public_key); - } - } - - if (! m_config.curve_secret_keyfile.empty()) { - int rc = readkey(m_config.curve_secret_keyfile, m_curve_secret_key); - - if (rc < 0) { - etiLog.level(warn) << "Invalid secret key for input " << - m_name; - - INVALIDATE_KEY(m_curve_secret_key); - } - } - - if (! m_config.curve_encoder_keyfile.empty()) { - int rc = readkey(m_config.curve_encoder_keyfile, m_curve_encoder_key); - - if (rc < 0) { - etiLog.level(warn) << "Invalid encoder key for input " << - m_name; - - INVALIDATE_KEY(m_curve_encoder_key); - } - } - - /* If you want encryption, you need to have defined all - * key files - */ - if ( m_config.enable_encryption && - ( ! (KEY_VALID(m_curve_public_key) && - KEY_VALID(m_curve_secret_key) && - KEY_VALID(m_curve_encoder_key) ) ) ) { - throw std::runtime_error("When enabling encryption, all three " - "keyfiles must be valid!"); - } - - if (m_config.enable_encryption) { - try { - /* We want to check that the encoder is the right one, - * so the encoder is the CURVE server. - */ - m_zmq_sock.setsockopt(ZMQ_CURVE_SERVERKEY, - m_curve_encoder_key, CURVE_KEYLEN); - } - catch (zmq::error_t& err) { - std::ostringstream os; - os << "ZMQ set encoder key for input " << m_name << " failed" << - err.what(); - throw std::runtime_error(os.str()); - } - - try { - m_zmq_sock.setsockopt(ZMQ_CURVE_PUBLICKEY, - m_curve_public_key, CURVE_KEYLEN); - } - catch (zmq::error_t& err) { - std::ostringstream os; - os << "ZMQ set public key for input " << m_name << " failed" << - err.what(); - throw std::runtime_error(os.str()); - } - - try { - m_zmq_sock.setsockopt(ZMQ_CURVE_SECRETKEY, - m_curve_secret_key, CURVE_KEYLEN); - } - catch (zmq::error_t& err) { - std::ostringstream os; - os << "ZMQ set secret key for input " << m_name << " failed" << - err.what(); - throw std::runtime_error(os.str()); - } - } - else { - try { - /* This forces the socket to go to the ZMQ_NULL auth - * mechanism - */ - const int no = 0; - m_zmq_sock.setsockopt(ZMQ_CURVE_SERVER, &no, sizeof(no)); - } - catch (zmq::error_t& err) { - etiLog.level(warn) << "ZMQ disable encryption keys for input " << - m_name << " failed: " << err.what(); - } - - } - - // Prepare the ZMQ socket to accept connections - try { - m_zmq_sock.bind(m_inputUri.c_str()); - } - catch (zmq::error_t& err) { - std::ostringstream os; - os << "ZMQ bind for input " << m_name << " failed" << - err.what(); - throw std::runtime_error(os.str()); - } - - m_zmq_sock_bound_to = m_inputUri; - - try { - m_zmq_sock.setsockopt(ZMQ_SUBSCRIBE, nullptr, 0); - } - catch (zmq::error_t& err) { - std::ostringstream os; - os << "ZMQ set socket options for input " << m_name << " failed" << - err.what(); - throw std::runtime_error(os.str()); - } -} - -int DabInputZmqBase::open(const std::string& inputUri) -{ - m_inputUri = inputUri; - - /* Let caller handle exceptions when we open() */ - rebind(); - - // We want to appear in the statistics ! - m_stats.registerAtServer(); - - return 0; -} - -int DabInputZmqBase::close() -{ - m_zmq_sock.close(); - return 0; -} - -int DabInputZmqBase::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 rc; - - /* We must *always* read data from the ZMQ socket, - * to make sure that ZMQ internal buffers are emptied - * quickly. It's the only way to control the buffers - * of the whole path from encoder to our frame_buffer. - */ - rc = readFromSocket(size); - - /* Notify of a buffer overrun, and drop some frames */ - if (m_frame_buffer.size() >= m_config.buffer_size) { - m_stats.notifyOverrun(); - - /* If the buffer is really too full, we drop as many frames as needed - * to get down to the prebuffering size. We would like to have our buffer - * filled to the prebuffering length. - */ - if (m_frame_buffer.size() >= 1.5*m_config.buffer_size) { - size_t over_max = m_frame_buffer.size() - m_config.prebuffering; - - while (over_max--) { - delete[] m_frame_buffer.front(); - m_frame_buffer.pop_front(); - } - } - else { - /* Our frame_buffer contains DAB logical frames. Five of these make one - * AAC superframe. - * - * Dropping this superframe amounts to dropping 120ms of audio. - * - * We're actually not sure to drop five DAB logical frames - * belonging to the same AAC superframe. It is assumed that no - * receiver will crash because of this. At least, the DAB logical frame - * vs. AAC superframe alignment is preserved. - * - * TODO: of course this assumption probably doesn't hold. Fix this ! - * TODO: also, with MPEG, the above doesn't hold, so we drop five - * frames even though we could drop less. - * */ - for (int frame_del_count = 0; frame_del_count < 5; frame_del_count++) { - delete[] m_frame_buffer.front(); - m_frame_buffer.pop_front(); - } - } - } - - if (m_prebuf_current > 0) { - if (rc > 0) - m_prebuf_current--; - if (m_prebuf_current == 0) - etiLog.log(info, "inputZMQ %s input pre-buffering complete\n", - m_name.c_str()); - - /* During prebuffering, give a zeroed frame to the mux */ - m_stats.notifyUnderrun(); - memset(buffer, 0, size); - return size; - } - - // Save stats data in bytes, not in frames - m_stats.notifyBuffer(m_frame_buffer.size() * size); - - if (m_frame_buffer.empty()) { - etiLog.log(warn, "inputZMQ %s input empty, re-enabling pre-buffering\n", - m_name.c_str()); - // reset prebuffering - m_prebuf_current = m_config.prebuffering; - - /* We have no data to give, we give a zeroed frame */ - m_stats.notifyUnderrun(); - memset(buffer, 0, size); - return size; - } - else - { - /* Normal situation, give a frame from the frame_buffer */ - uint8_t* newframe = m_frame_buffer.front(); - memcpy(buffer, newframe, size); - delete[] newframe; - m_frame_buffer.pop_front(); - return size; - } -} - - -/******** MPEG input *******/ - -// Read a MPEG frame from the socket, and push to list -int DabInputZmqMPEG::readFromSocket(size_t framesize) -{ - bool messageReceived = false; - zmq::message_t msg; - - try { - messageReceived = m_zmq_sock.recv(&msg, ZMQ_DONTWAIT); - if (!messageReceived) { - return 0; - } - - } - catch (zmq::error_t& err) - { - etiLog.level(error) << "Failed to receive MPEG frame from zmq socket " << - m_name << ": " << err.what(); - } - - /* This is the old 'one superframe per ZMQ message' format */ - uint8_t* data = (uint8_t*)msg.data(); - size_t datalen = msg.size(); - - /* Look for the new zmq_frame_header_t format */ - zmq_frame_header_t* frame = (zmq_frame_header_t*)msg.data(); - - if (msg.size() == ZMQ_FRAME_SIZE(frame) && - frame->version == 1 && - frame->encoder == ZMQ_ENCODER_TOOLAME) { - datalen = frame->datasize; - data = ZMQ_FRAME_DATA(frame); - - m_stats.notifyPeakLevels(frame->audiolevel_left, - frame->audiolevel_right); - } - - - if (datalen == framesize) - { - if (m_frame_buffer.size() > m_config.buffer_size) { - etiLog.level(warn) << - "inputZMQ " << m_name << - " buffer full (" << m_frame_buffer.size() << ")," - " dropping incoming frame !"; - messageReceived = false; - } - else if (m_enable_input) { - // copy the input frame blockwise into the frame_buffer - auto framedata = new uint8_t[framesize]; - memcpy(framedata, data, framesize); - m_frame_buffer.push_back(framedata); - } - else { - return 0; - } - } - else { - etiLog.level(error) << - "inputZMQ " << m_name << - " verify bitrate: recv'd " << msg.size() << " B" << - ", need " << framesize << "."; - messageReceived = false; - } - - return messageReceived ? msg.size() : 0; -} - -/******** AAC+ input *******/ - -// Read a AAC+ superframe from the socket, cut it into five frames, -// and push to list -int DabInputZmqAAC::readFromSocket(size_t framesize) -{ - bool messageReceived; - zmq::message_t msg; - - try { - messageReceived = m_zmq_sock.recv(&msg, ZMQ_DONTWAIT); - if (!messageReceived) { - return 0; - } - - } - catch (zmq::error_t& err) - { - etiLog.level(error) << - "Failed to receive AAC superframe from zmq socket " << - m_name << ": " << err.what(); - } - - /* This is the old 'one superframe per ZMQ message' format */ - uint8_t* data = (uint8_t*)msg.data(); - size_t datalen = msg.size(); - - /* Look for the new zmq_frame_header_t format */ - zmq_frame_header_t* frame = (zmq_frame_header_t*)msg.data(); - - if (msg.size() == ZMQ_FRAME_SIZE(frame) && - frame->version == 1 && - frame->encoder == ZMQ_ENCODER_FDK) { - datalen = frame->datasize; - data = ZMQ_FRAME_DATA(frame); - - m_stats.notifyPeakLevels(frame->audiolevel_left, - frame->audiolevel_right); - } - - - /* TS 102 563, Section 6: - * Audio super frames are transported in five successive DAB logical frames - * with additional error protection. - */ - if (datalen) - { - if (datalen == 5*framesize) - { - if (m_frame_buffer.size() > m_config.buffer_size) { - etiLog.level(warn) << - "inputZMQ " << m_name << - " buffer full (" << m_frame_buffer.size() << ")," - " dropping incoming superframe !"; - datalen = 0; - } - else if (m_enable_input) { - // copy the input frame blockwise into the frame_buffer - for (uint8_t* framestart = data; - framestart < &data[5*framesize]; - framestart += framesize) { - auto audioframe = new uint8_t[framesize]; - memcpy(audioframe, framestart, framesize); - m_frame_buffer.push_back(audioframe); - } - } - else { - datalen = 0; - } - } - else { - etiLog.level(error) << - "inputZMQ " << m_name << - " verify bitrate: recv'd " << msg.size() << " B" << - ", need " << 5*framesize << "."; - - datalen = 0; - } - } - else { - etiLog.level(error) << - "inputZMQ " << m_name << - " invalid frame received"; - } - - return datalen; -} - -/********* REMOTE CONTROL ***********/ - -void DabInputZmqBase::set_parameter(const string& parameter, - const string& value) -{ - if (parameter == "buffer") { - size_t new_limit = atol(value.c_str()); - - if (new_limit < INPUT_ZMQ_MIN_BUFFER_SIZE) { - throw ParameterError("Desired buffer size too small." - " Minimum " STRINGIFY(INPUT_ZMQ_MIN_BUFFER_SIZE) ); - } - else if (new_limit > INPUT_ZMQ_MAX_BUFFER_SIZE) { - throw ParameterError("Desired buffer size too large." - " Maximum " STRINGIFY(INPUT_ZMQ_MAX_BUFFER_SIZE) ); - } - - m_config.buffer_size = new_limit; - } - else if (parameter == "prebuffering") { - size_t new_prebuf = atol(value.c_str()); - - if (new_prebuf < INPUT_ZMQ_MIN_BUFFER_SIZE) { - throw ParameterError("Desired prebuffering too small." - " Minimum " STRINGIFY(INPUT_ZMQ_MIN_BUFFER_SIZE) ); - } - else if (new_prebuf > INPUT_ZMQ_MAX_BUFFER_SIZE) { - throw ParameterError("Desired prebuffering too large." - " Maximum " STRINGIFY(INPUT_ZMQ_MAX_BUFFER_SIZE) ); - } - - m_config.prebuffering = new_prebuf; - } - else if (parameter == "enable") { - if (value == "1") { - m_enable_input = true; - } - else if (value == "0") { - m_enable_input = false; - } - else { - throw ParameterError("Value not understood, specify 0 or 1."); - } - } - else if (parameter == "encryption") { - if (value == "1") { - m_config.enable_encryption = true; - } - else if (value == "0") { - m_config.enable_encryption = false; - } - else { - throw ParameterError("Value not understood, specify 0 or 1."); - } - - try { - rebind(); - } - catch (std::runtime_error &e) { - stringstream ss; - ss << "Could not bind socket again with new keys." << - e.what(); - throw ParameterError(ss.str()); - } - } - else if (parameter == "secretkey") { - m_config.curve_secret_keyfile = value; - } - else if (parameter == "publickey") { - m_config.curve_public_keyfile = value; - } - else if (parameter == "encoderkey") { - m_config.curve_encoder_keyfile = value; - } - else { - stringstream ss; - ss << "Parameter '" << parameter << - "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); - } -} - -const string DabInputZmqBase::get_parameter(const string& parameter) const -{ - stringstream ss; - if (parameter == "buffer") { - ss << m_config.buffer_size; - } - else if (parameter == "prebuffering") { - ss << m_config.prebuffering; - } - else if (parameter == "enable") { - if (m_enable_input) - ss << "true"; - else - ss << "false"; - } - else if (parameter == "encryption") { - if (m_config.enable_encryption) - ss << "true"; - else - ss << "false"; - } - else if (parameter == "secretkey") { - ss << m_config.curve_secret_keyfile; - } - else if (parameter == "publickey") { - ss << m_config.curve_public_keyfile; - } - else if (parameter == "encoderkey") { - ss << m_config.curve_encoder_keyfile; - } - else { - ss << "Parameter '" << parameter << - "' is not exported by controllable " << get_rc_name(); - throw ParameterError(ss.str()); - } - return ss.str(); - -} - -#endif - diff --git a/src/dabInputZmq.h b/src/dabInputZmq.h deleted file mode 100644 index 351fb07..0000000 --- a/src/dabInputZmq.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Copyright (C) 2013, 2014 Matthias P. Braendli - http://www.opendigitalradio.org - - ZeroMQ input. see www.zeromq.org for more info - - For the AAC+ input, each zeromq message must contain one superframe, - or one zmq_frame_header_t followed by a superframe. - - For the MPEG input, each zeromq message must contain one frame. - - Encryption is provided by zmq_curve, see the corresponding manpage. - - From the ZeroMQ manpage 'zmq': - - The 0MQ lightweight messaging kernel is a library which extends the standard - socket interfaces with features traditionally provided by specialised - messaging middleware products. 0MQ sockets provide an abstraction of - asynchronous message queues, multiple messaging patterns, message filtering - (subscriptions), seamless access to multiple transport protocols and more. - */ -/* - This file is part of ODR-DabMux. - - It defines a ZeroMQ input for dabplus data. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_ZMQ_H -#define DAB_INPUT_ZMQ_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_INPUT_ZEROMQ - -#include -#include -#include -#include "zmq.hpp" -#include "dabInput.h" -#include "ManagementServer.h" - -/* 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 - -// 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 - -/* 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 - -/* helper to invalidate a key */ -#define INVALIDATE_KEY(k) memset(k, 0, CURVE_KEYLEN+1) - -/* Verification for key validity */ -#define KEY_VALID(k) (k[0] != '\0') - -/* Read a key from file into key - * - * Returns 0 on success, negative value on failure - */ -int readkey(std::string& keyfile, char* key); - -struct dab_input_zmq_config_t -{ - /* The size of the internal buffer, measured in number - * of elements. - * - * Each element corresponds to five frames, - * or one AAC superframe. - */ - size_t buffer_size; - - /* The amount of prebuffering to do before we start streaming - * - * Same units as buffer_size - */ - size_t prebuffering; - - /* Whether to enforce encryption or not - */ - bool enable_encryption; - - /* Full path to file containing public key. - */ - std::string curve_public_keyfile; - - /* Full path to file containing secret key. - */ - std::string curve_secret_keyfile; - - /* Full path to file containing encoder public key. - */ - std::string curve_encoder_keyfile; -}; - -#define ZMQ_ENCODER_FDK 1 -#define ZMQ_ENCODER_TOOLAME 2 - -/* This defines the on-wire representation of a ZMQ message header. - * - * The data follows right after this header */ -struct zmq_frame_header_t -{ - uint16_t version; // we support version=1 now - uint16_t encoder; // see ZMQ_ENCODER_XYZ - - /* length of the 'data' field */ - uint32_t datasize; - - /* Audio level, peak, linear PCM */ - int16_t audiolevel_left; - int16_t audiolevel_right; - - /* Data follows this header */ -} __attribute__ ((packed)); - -/* The expected frame size incl data of the given frame */ -#define ZMQ_FRAME_SIZE(f) (sizeof(zmq_frame_header_t) + f->datasize) - -#define ZMQ_FRAME_DATA(f) ( ((uint8_t*)f)+sizeof(zmq_frame_header_t) ) - - -class DabInputZmqBase : public DabInputBase, public RemoteControllable { - public: - DabInputZmqBase(const std::string name, - dab_input_zmq_config_t config) - : RemoteControllable(name), - m_zmq_context(1), - m_zmq_sock(m_zmq_context, ZMQ_SUB), - m_zmq_sock_bound_to(""), - m_bitrate(0), - m_enable_input(true), - m_config(config), - m_stats(m_name), - m_prebuf_current(config.prebuffering) { - RC_ADD_PARAMETER(enable, - "If the input is enabled. Set to zero to empty the buffer."); - - RC_ADD_PARAMETER(encryption, - "If encryption is enabled or disabled [1 or 0]." - " If 1 is written, the keys are reloaded."); - - RC_ADD_PARAMETER(publickey, - "The multiplexer's public key file."); - - RC_ADD_PARAMETER(secretkey, - "The multiplexer's secret key file."); - - RC_ADD_PARAMETER(encoderkey, - "The encoder's public key file."); - - /* Set all keys to zero */ - INVALIDATE_KEY(m_curve_public_key); - INVALIDATE_KEY(m_curve_secret_key); - INVALIDATE_KEY(m_curve_encoder_key); - } - - virtual int open(const std::string& inputUri); - virtual int readFrame(void* buffer, int size); - virtual int setBitrate(int bitrate); - virtual int close(); - - /* Remote control */ - virtual void set_parameter(const std::string& parameter, - const std::string& value); - - /* Getting a parameter always returns a string. */ - virtual const std::string get_parameter(const std::string& parameter) const; - - protected: - virtual int readFromSocket(size_t framesize) = 0; - - virtual void rebind(); - - zmq::context_t m_zmq_context; - zmq::socket_t m_zmq_sock; // handle for the zmq socket - - /* If the socket is bound, this saves the endpoint, - * otherwise, it's an empty string - */ - std::string m_zmq_sock_bound_to; - int m_bitrate; - - /* set this to zero to empty the input buffer */ - bool m_enable_input; - - /* stores elements of type char[] */ - std::list m_frame_buffer; - - dab_input_zmq_config_t m_config; - - /* Key management, keys need to be zero-terminated */ - char m_curve_public_key[CURVE_KEYLEN+1]; - char m_curve_secret_key[CURVE_KEYLEN+1]; - char m_curve_encoder_key[CURVE_KEYLEN+1]; - - std::string m_inputUri; - - InputStat m_stats; - - private: - size_t m_prebuf_current; -}; - -class DabInputZmqMPEG : public DabInputZmqBase { - public: - DabInputZmqMPEG(const std::string name, - dab_input_zmq_config_t config) - : DabInputZmqBase(name, config) { - RC_ADD_PARAMETER(buffer, - "Size of the input buffer [mpeg frames]"); - - RC_ADD_PARAMETER(prebuffering, - "Min buffer level before streaming starts [mpeg frames]"); - } - - private: - virtual int readFromSocket(size_t framesize); -}; - -class DabInputZmqAAC : public DabInputZmqBase { - public: - DabInputZmqAAC(const std::string name, - dab_input_zmq_config_t config) - : DabInputZmqBase(name, config) { - RC_ADD_PARAMETER(buffer, - "Size of the input buffer [aac superframes]"); - - RC_ADD_PARAMETER(prebuffering, - "Min buffer level before streaming starts [aac superframes]"); - } - - private: - virtual int readFromSocket(size_t framesize); -}; - -#endif // HAVE_INPUT_ZMQ - -#endif // DAB_INPUT_ZMQ_H - diff --git a/src/input/Prbs.cpp b/src/input/Prbs.cpp new file mode 100644 index 0000000..b9e244b --- /dev/null +++ b/src/input/Prbs.cpp @@ -0,0 +1,101 @@ +/* + Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications + Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org + + Pseudo-Random Bit Sequence generator for test purposes. + */ +/* + This file is part of ODR-DabMux. + + ODR-DabMux is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + ODR-DabMux is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ODR-DabMux. If not, see . + */ + +#include "input/Prbs.h" + +#include +#include +#include +#include +#include +#include +#include "utils.h" + +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 Prbs::open(const string& name) +{ + if (name.empty()) { + m_prbs.setup(PRBS_DEFAULT_POLY); + } + else { + if (name[0] != ':') { + throw invalid_argument( + "Invalid PRBS address format. " + "Must be prbs://:polynomial."); + } + + const string poly_str = name.substr(1); + + long polynomial = hexparse(poly_str); + + if (polynomial == 0) { + throw invalid_argument("No polynomial given for PRBS input"); + } + + m_prbs.setup(polynomial); + } + rewind(); + + return 0; +} + +int Prbs::readFrame(void* buffer, int size) +{ + unsigned char* cbuffer = reinterpret_cast(buffer); + + for (int i = 0; i < size; ++i) { + cbuffer[i] = m_prbs.step(); + } + + return size; +} + +int Prbs::setBitrate(int bitrate) +{ + return bitrate; +} + +int Prbs::close() +{ + return 0; +} + +int Prbs::rewind() +{ + m_prbs.rewind(); + return 0; +} + +}; diff --git a/src/input/Prbs.h b/src/input/Prbs.h new file mode 100644 index 0000000..47b52ad --- /dev/null +++ b/src/input/Prbs.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications + Research Center Canada) + + Copyright (C) 2016 + Matthias P. Braendli, matthias.braendli@mpb.li + + http://www.opendigitalradio.org + + Pseudo-Random Bit Sequence generator for test purposes. + */ +/* + This file is part of ODR-DabMux. + + ODR-DabMux is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + ODR-DabMux is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ODR-DabMux. If not, see . + */ + +#pragma once + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "input/inputs.h" +#include "prbs.h" + +namespace Inputs { + +class Prbs : public InputBase { + public: + virtual int open(const std::string& name); + virtual int readFrame(void* buffer, int size); + virtual int setBitrate(int bitrate); + virtual int close(); + + private: + virtual int rewind(); + + PrbsGenerator m_prbs; +}; + +}; + diff --git a/src/input/Zmq.cpp b/src/input/Zmq.cpp new file mode 100644 index 0000000..6ef5fce --- /dev/null +++ b/src/input/Zmq.cpp @@ -0,0 +1,625 @@ +/* + Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications + Research Center Canada) + + Copyright (C) 2016 Matthias P. Braendli + http://www.opendigitalradio.org + + ZeroMQ input. see www.zeromq.org for more info + + For the AAC+ input, each zeromq message must contain one superframe + or one zmq_frame_header_t followed by a superframe. + + For the MPEG input, each zeromq message must contain one frame. + + Encryption is provided by zmq_curve, see the corresponding manpage. + + From the ZeroMQ manpage 'zmq': + + The 0MQ lightweight messaging kernel is a library which extends the standard + socket interfaces with features traditionally provided by specialised + messaging middleware products. 0MQ sockets provide an abstraction of + asynchronous message queues, multiple messaging patterns, message filtering + (subscriptions), seamless access to multiple transport protocols and more. + */ +/* + This file is part of ODR-DabMux. + + ODR-DabMux is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + ODR-DabMux is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ODR-DabMux. If not, see . + */ + +#include "input/Zmq.h" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_INPUT_ZEROMQ + +#include "zmq.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#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) +{ + 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 */ + key[CURVE_KEYLEN] = '\0'; + + return 0; +} + +/***** Common functions (MPEG and AAC) ******/ + +/* If necessary, unbind the socket, then check the keys, + * if they are ok and encryption is required, set the + * keys to the socket, and finally bind the socket + * to the new address + */ +void ZmqBase::rebind() +{ + if (! m_zmq_sock_bound_to.empty()) { + try { + m_zmq_sock.unbind(m_zmq_sock_bound_to.c_str()); + } + catch (zmq::error_t& err) { + etiLog.level(warn) << "ZMQ unbind for input " << m_name << " failed"; + } + } + + m_zmq_sock_bound_to = ""; + + /* Load each key independently */ + if (! m_config.curve_public_keyfile.empty()) { + int rc = readkey(m_config.curve_public_keyfile, m_curve_public_key); + + if (rc < 0) { + etiLog.level(warn) << "Invalid public key for input " << + m_name; + + INVALIDATE_KEY(m_curve_public_key); + } + } + + if (! m_config.curve_secret_keyfile.empty()) { + int rc = readkey(m_config.curve_secret_keyfile, m_curve_secret_key); + + if (rc < 0) { + etiLog.level(warn) << "Invalid secret key for input " << + m_name; + + INVALIDATE_KEY(m_curve_secret_key); + } + } + + if (! m_config.curve_encoder_keyfile.empty()) { + int rc = readkey(m_config.curve_encoder_keyfile, m_curve_encoder_key); + + if (rc < 0) { + etiLog.level(warn) << "Invalid encoder key for input " << + m_name; + + INVALIDATE_KEY(m_curve_encoder_key); + } + } + + /* If you want encryption, you need to have defined all + * key files + */ + if ( m_config.enable_encryption && + ( ! (KEY_VALID(m_curve_public_key) && + KEY_VALID(m_curve_secret_key) && + KEY_VALID(m_curve_encoder_key) ) ) ) { + throw std::runtime_error("When enabling encryption, all three " + "keyfiles must be valid!"); + } + + if (m_config.enable_encryption) { + try { + /* We want to check that the encoder is the right one, + * so the encoder is the CURVE server. + */ + m_zmq_sock.setsockopt(ZMQ_CURVE_SERVERKEY, + m_curve_encoder_key, CURVE_KEYLEN); + } + catch (zmq::error_t& err) { + std::ostringstream os; + os << "ZMQ set encoder key for input " << m_name << " failed" << + err.what(); + throw std::runtime_error(os.str()); + } + + try { + m_zmq_sock.setsockopt(ZMQ_CURVE_PUBLICKEY, + m_curve_public_key, CURVE_KEYLEN); + } + catch (zmq::error_t& err) { + std::ostringstream os; + os << "ZMQ set public key for input " << m_name << " failed" << + err.what(); + throw std::runtime_error(os.str()); + } + + try { + m_zmq_sock.setsockopt(ZMQ_CURVE_SECRETKEY, + m_curve_secret_key, CURVE_KEYLEN); + } + catch (zmq::error_t& err) { + std::ostringstream os; + os << "ZMQ set secret key for input " << m_name << " failed" << + err.what(); + throw std::runtime_error(os.str()); + } + } + else { + try { + /* This forces the socket to go to the ZMQ_NULL auth + * mechanism + */ + const int no = 0; + m_zmq_sock.setsockopt(ZMQ_CURVE_SERVER, &no, sizeof(no)); + } + catch (zmq::error_t& err) { + etiLog.level(warn) << "ZMQ disable encryption keys for input " << + m_name << " failed: " << err.what(); + } + + } + + // Prepare the ZMQ socket to accept connections + try { + m_zmq_sock.bind(m_inputUri.c_str()); + } + catch (zmq::error_t& err) { + std::ostringstream os; + os << "ZMQ bind for input " << m_name << " failed" << + err.what(); + throw std::runtime_error(os.str()); + } + + m_zmq_sock_bound_to = m_inputUri; + + try { + m_zmq_sock.setsockopt(ZMQ_SUBSCRIBE, nullptr, 0); + } + catch (zmq::error_t& err) { + std::ostringstream os; + os << "ZMQ set socket options for input " << m_name << " failed" << + err.what(); + throw std::runtime_error(os.str()); + } +} + +int ZmqBase::open(const std::string& inputUri) +{ + m_inputUri = inputUri; + + /* Let caller handle exceptions when we open() */ + rebind(); + + // We want to appear in the statistics ! + m_stats.registerAtServer(); + + return 0; +} + +int ZmqBase::close() +{ + m_zmq_sock.close(); + return 0; +} + +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 ZmqBase::readFrame(void* buffer, int size) +{ + int rc; + + /* We must *always* read data from the ZMQ socket, + * to make sure that ZMQ internal buffers are emptied + * quickly. It's the only way to control the buffers + * of the whole path from encoder to our frame_buffer. + */ + rc = readFromSocket(size); + + /* Notify of a buffer overrun, and drop some frames */ + if (m_frame_buffer.size() >= m_config.buffer_size) { + m_stats.notifyOverrun(); + + /* If the buffer is really too full, we drop as many frames as needed + * to get down to the prebuffering size. We would like to have our buffer + * filled to the prebuffering length. + */ + if (m_frame_buffer.size() >= 1.5*m_config.buffer_size) { + size_t over_max = m_frame_buffer.size() - m_config.prebuffering; + + while (over_max--) { + delete[] m_frame_buffer.front(); + m_frame_buffer.pop_front(); + } + } + else { + /* Our frame_buffer contains DAB logical frames. Five of these make one + * AAC superframe. + * + * Dropping this superframe amounts to dropping 120ms of audio. + * + * We're actually not sure to drop five DAB logical frames + * belonging to the same AAC superframe. It is assumed that no + * receiver will crash because of this. At least, the DAB logical frame + * vs. AAC superframe alignment is preserved. + * + * TODO: of course this assumption probably doesn't hold. Fix this ! + * TODO: also, with MPEG, the above doesn't hold, so we drop five + * frames even though we could drop less. + * */ + for (int frame_del_count = 0; frame_del_count < 5; frame_del_count++) { + delete[] m_frame_buffer.front(); + m_frame_buffer.pop_front(); + } + } + } + + if (m_prebuf_current > 0) { + if (rc > 0) + m_prebuf_current--; + if (m_prebuf_current == 0) + etiLog.log(info, "inputZMQ %s input pre-buffering complete\n", + m_name.c_str()); + + /* During prebuffering, give a zeroed frame to the mux */ + m_stats.notifyUnderrun(); + memset(buffer, 0, size); + return size; + } + + // Save stats data in bytes, not in frames + m_stats.notifyBuffer(m_frame_buffer.size() * size); + + if (m_frame_buffer.empty()) { + etiLog.log(warn, "inputZMQ %s input empty, re-enabling pre-buffering\n", + m_name.c_str()); + // reset prebuffering + m_prebuf_current = m_config.prebuffering; + + /* We have no data to give, we give a zeroed frame */ + m_stats.notifyUnderrun(); + memset(buffer, 0, size); + return size; + } + else + { + /* Normal situation, give a frame from the frame_buffer */ + uint8_t* newframe = m_frame_buffer.front(); + memcpy(buffer, newframe, size); + delete[] newframe; + m_frame_buffer.pop_front(); + return size; + } +} + + +/******** MPEG input *******/ + +// Read a MPEG frame from the socket, and push to list +int ZmqMPEG::readFromSocket(size_t framesize) +{ + bool messageReceived = false; + zmq::message_t msg; + + try { + messageReceived = m_zmq_sock.recv(&msg, ZMQ_DONTWAIT); + if (!messageReceived) { + return 0; + } + + } + catch (zmq::error_t& err) + { + etiLog.level(error) << "Failed to receive MPEG frame from zmq socket " << + m_name << ": " << err.what(); + } + + /* This is the old 'one superframe per ZMQ message' format */ + uint8_t* data = (uint8_t*)msg.data(); + size_t datalen = msg.size(); + + /* Look for the new zmq_frame_header_t format */ + zmq_frame_header_t* frame = (zmq_frame_header_t*)msg.data(); + + if (msg.size() == ZMQ_FRAME_SIZE(frame) && + frame->version == 1 && + frame->encoder == ZMQ_ENCODER_TOOLAME) { + datalen = frame->datasize; + data = ZMQ_FRAME_DATA(frame); + + m_stats.notifyPeakLevels(frame->audiolevel_left, + frame->audiolevel_right); + } + + + if (datalen == framesize) + { + if (m_frame_buffer.size() > m_config.buffer_size) { + etiLog.level(warn) << + "inputZMQ " << m_name << + " buffer full (" << m_frame_buffer.size() << ")," + " dropping incoming frame !"; + messageReceived = false; + } + else if (m_enable_input) { + // copy the input frame blockwise into the frame_buffer + auto framedata = new uint8_t[framesize]; + memcpy(framedata, data, framesize); + m_frame_buffer.push_back(framedata); + } + else { + return 0; + } + } + else { + etiLog.level(error) << + "inputZMQ " << m_name << + " verify bitrate: recv'd " << msg.size() << " B" << + ", need " << framesize << "."; + messageReceived = false; + } + + return messageReceived ? msg.size() : 0; +} + +/******** AAC+ input *******/ + +// Read a AAC+ superframe from the socket, cut it into five frames, +// and push to list +int ZmqAAC::readFromSocket(size_t framesize) +{ + bool messageReceived; + zmq::message_t msg; + + try { + messageReceived = m_zmq_sock.recv(&msg, ZMQ_DONTWAIT); + if (!messageReceived) { + return 0; + } + + } + catch (zmq::error_t& err) + { + etiLog.level(error) << + "Failed to receive AAC superframe from zmq socket " << + m_name << ": " << err.what(); + } + + /* This is the old 'one superframe per ZMQ message' format */ + uint8_t* data = (uint8_t*)msg.data(); + size_t datalen = msg.size(); + + /* Look for the new zmq_frame_header_t format */ + zmq_frame_header_t* frame = (zmq_frame_header_t*)msg.data(); + + if (msg.size() == ZMQ_FRAME_SIZE(frame) && + frame->version == 1 && + frame->encoder == ZMQ_ENCODER_FDK) { + datalen = frame->datasize; + data = ZMQ_FRAME_DATA(frame); + + m_stats.notifyPeakLevels(frame->audiolevel_left, + frame->audiolevel_right); + } + + + /* TS 102 563, Section 6: + * Audio super frames are transported in five successive DAB logical frames + * with additional error protection. + */ + if (datalen) + { + if (datalen == 5*framesize) + { + if (m_frame_buffer.size() > m_config.buffer_size) { + etiLog.level(warn) << + "inputZMQ " << m_name << + " buffer full (" << m_frame_buffer.size() << ")," + " dropping incoming superframe !"; + datalen = 0; + } + else if (m_enable_input) { + // copy the input frame blockwise into the frame_buffer + for (uint8_t* framestart = data; + framestart < &data[5*framesize]; + framestart += framesize) { + auto audioframe = new uint8_t[framesize]; + memcpy(audioframe, framestart, framesize); + m_frame_buffer.push_back(audioframe); + } + } + else { + datalen = 0; + } + } + else { + etiLog.level(error) << + "inputZMQ " << m_name << + " verify bitrate: recv'd " << msg.size() << " B" << + ", need " << 5*framesize << "."; + + datalen = 0; + } + } + else { + etiLog.level(error) << + "inputZMQ " << m_name << + " invalid frame received"; + } + + return datalen; +} + +/********* REMOTE CONTROL ***********/ + +void ZmqBase::set_parameter(const string& parameter, + const string& value) +{ + if (parameter == "buffer") { + size_t new_limit = atol(value.c_str()); + + if (new_limit < INPUT_ZMQ_MIN_BUFFER_SIZE) { + throw ParameterError("Desired buffer size too small." + " Minimum " STRINGIFY(INPUT_ZMQ_MIN_BUFFER_SIZE) ); + } + else if (new_limit > INPUT_ZMQ_MAX_BUFFER_SIZE) { + throw ParameterError("Desired buffer size too large." + " Maximum " STRINGIFY(INPUT_ZMQ_MAX_BUFFER_SIZE) ); + } + + m_config.buffer_size = new_limit; + } + else if (parameter == "prebuffering") { + size_t new_prebuf = atol(value.c_str()); + + if (new_prebuf < INPUT_ZMQ_MIN_BUFFER_SIZE) { + throw ParameterError("Desired prebuffering too small." + " Minimum " STRINGIFY(INPUT_ZMQ_MIN_BUFFER_SIZE) ); + } + else if (new_prebuf > INPUT_ZMQ_MAX_BUFFER_SIZE) { + throw ParameterError("Desired prebuffering too large." + " Maximum " STRINGIFY(INPUT_ZMQ_MAX_BUFFER_SIZE) ); + } + + m_config.prebuffering = new_prebuf; + } + else if (parameter == "enable") { + if (value == "1") { + m_enable_input = true; + } + else if (value == "0") { + m_enable_input = false; + } + else { + throw ParameterError("Value not understood, specify 0 or 1."); + } + } + else if (parameter == "encryption") { + if (value == "1") { + m_config.enable_encryption = true; + } + else if (value == "0") { + m_config.enable_encryption = false; + } + else { + throw ParameterError("Value not understood, specify 0 or 1."); + } + + try { + rebind(); + } + catch (std::runtime_error &e) { + stringstream ss; + ss << "Could not bind socket again with new keys." << + e.what(); + throw ParameterError(ss.str()); + } + } + else if (parameter == "secretkey") { + m_config.curve_secret_keyfile = value; + } + else if (parameter == "publickey") { + m_config.curve_public_keyfile = value; + } + else if (parameter == "encoderkey") { + m_config.curve_encoder_keyfile = value; + } + else { + stringstream ss; + ss << "Parameter '" << parameter << + "' is not exported by controllable " << get_rc_name(); + throw ParameterError(ss.str()); + } +} + +const string ZmqBase::get_parameter(const string& parameter) const +{ + stringstream ss; + if (parameter == "buffer") { + ss << m_config.buffer_size; + } + else if (parameter == "prebuffering") { + ss << m_config.prebuffering; + } + else if (parameter == "enable") { + if (m_enable_input) + ss << "true"; + else + ss << "false"; + } + else if (parameter == "encryption") { + if (m_config.enable_encryption) + ss << "true"; + else + ss << "false"; + } + else if (parameter == "secretkey") { + ss << m_config.curve_secret_keyfile; + } + else if (parameter == "publickey") { + ss << m_config.curve_public_keyfile; + } + else if (parameter == "encoderkey") { + ss << m_config.curve_encoder_keyfile; + } + else { + ss << "Parameter '" << parameter << + "' is not exported by controllable " << get_rc_name(); + throw ParameterError(ss.str()); + } + return ss.str(); + +} + +}; + +#endif + diff --git a/src/input/Zmq.h b/src/input/Zmq.h new file mode 100644 index 0000000..d1dd2d5 --- /dev/null +++ b/src/input/Zmq.h @@ -0,0 +1,271 @@ +/* + Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications + Research Center Canada) + + Copyright (C) 2016 Matthias P. Braendli + http://www.opendigitalradio.org + + ZeroMQ input. see www.zeromq.org for more info + + For the AAC+ input, each zeromq message must contain one superframe, + or one zmq_frame_header_t followed by a superframe. + + For the MPEG input, each zeromq message must contain one frame. + + Encryption is provided by zmq_curve, see the corresponding manpage. + + From the ZeroMQ manpage 'zmq': + + The 0MQ lightweight messaging kernel is a library which extends the standard + socket interfaces with features traditionally provided by specialised + messaging middleware products. 0MQ sockets provide an abstraction of + asynchronous message queues, multiple messaging patterns, message filtering + (subscriptions), seamless access to multiple transport protocols and more. + */ +/* + This file is part of ODR-DabMux. + + It defines a ZeroMQ input for dabplus data. + + ODR-DabMux is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + ODR-DabMux is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ODR-DabMux. If not, see . + */ + +#pragma once + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_INPUT_ZEROMQ + +#include +#include +#include +#include "zmq.hpp" +#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) + */ + +// Minimum frame_buffer size in number of elements +// This is one AAC superframe, but you probably don't want to +// go that low anyway. +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. +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. + */ +const size_t CURVE_KEYLEN = 40; + +/* helper to invalidate a key */ +#define INVALIDATE_KEY(k) memset(k, 0, CURVE_KEYLEN+1) + +/* Verification for key validity */ +#define KEY_VALID(k) (k[0] != '\0') + +/* Read a key from file into key + * + * Returns 0 on success, negative value on failure + */ +int readkey(std::string& keyfile, char* key); + +struct dab_input_zmq_config_t +{ + /* The size of the internal buffer, measured in number + * of elements. + * + * Each element corresponds to five frames, + * or one AAC superframe. + */ + size_t buffer_size; + + /* The amount of prebuffering to do before we start streaming + * + * Same units as buffer_size + */ + size_t prebuffering; + + /* Whether to enforce encryption or not + */ + bool enable_encryption; + + /* Full path to file containing public key. + */ + std::string curve_public_keyfile; + + /* Full path to file containing secret key. + */ + std::string curve_secret_keyfile; + + /* Full path to file containing encoder public key. + */ + std::string curve_encoder_keyfile; +}; + +#define ZMQ_ENCODER_FDK 1 +#define ZMQ_ENCODER_TOOLAME 2 + +/* This defines the on-wire representation of a ZMQ message header. + * + * The data follows right after this header */ +struct zmq_frame_header_t +{ + uint16_t version; // we support version=1 now + uint16_t encoder; // see ZMQ_ENCODER_XYZ + + /* length of the 'data' field */ + uint32_t datasize; + + /* Audio level, peak, linear PCM */ + int16_t audiolevel_left; + int16_t audiolevel_right; + + /* Data follows this header */ +} __attribute__ ((packed)); + +/* The expected frame size incl data of the given frame */ +#define ZMQ_FRAME_SIZE(f) (sizeof(zmq_frame_header_t) + f->datasize) + +#define ZMQ_FRAME_DATA(f) ( ((uint8_t*)f)+sizeof(zmq_frame_header_t) ) + + +class ZmqBase : public InputBase, public RemoteControllable { + public: + ZmqBase(const std::string name, + dab_input_zmq_config_t config) + : RemoteControllable(name), + m_zmq_context(1), + m_zmq_sock(m_zmq_context, ZMQ_SUB), + m_zmq_sock_bound_to(""), + m_bitrate(0), + m_enable_input(true), + m_config(config), + m_stats(m_name), + m_prebuf_current(config.prebuffering) { + RC_ADD_PARAMETER(enable, + "If the input is enabled. Set to zero to empty the buffer."); + + RC_ADD_PARAMETER(encryption, + "If encryption is enabled or disabled [1 or 0]." + " If 1 is written, the keys are reloaded."); + + RC_ADD_PARAMETER(publickey, + "The multiplexer's public key file."); + + RC_ADD_PARAMETER(secretkey, + "The multiplexer's secret key file."); + + RC_ADD_PARAMETER(encoderkey, + "The encoder's public key file."); + + /* Set all keys to zero */ + INVALIDATE_KEY(m_curve_public_key); + INVALIDATE_KEY(m_curve_secret_key); + INVALIDATE_KEY(m_curve_encoder_key); + } + + virtual int open(const std::string& inputUri); + virtual int readFrame(void* buffer, int size); + virtual int setBitrate(int bitrate); + virtual int close(); + + /* Remote control */ + virtual void set_parameter(const std::string& parameter, + const std::string& value); + + /* Getting a parameter always returns a string. */ + virtual const std::string get_parameter(const std::string& parameter) const; + + protected: + virtual int readFromSocket(size_t framesize) = 0; + + virtual void rebind(); + + zmq::context_t m_zmq_context; + zmq::socket_t m_zmq_sock; // handle for the zmq socket + + /* If the socket is bound, this saves the endpoint, + * otherwise, it's an empty string + */ + std::string m_zmq_sock_bound_to; + int m_bitrate; + + /* set this to zero to empty the input buffer */ + bool m_enable_input; + + /* stores elements of type char[] */ + std::list m_frame_buffer; + + dab_input_zmq_config_t m_config; + + /* Key management, keys need to be zero-terminated */ + char m_curve_public_key[CURVE_KEYLEN+1]; + char m_curve_secret_key[CURVE_KEYLEN+1]; + char m_curve_encoder_key[CURVE_KEYLEN+1]; + + std::string m_inputUri; + + InputStat m_stats; + + private: + size_t m_prebuf_current; +}; + +class ZmqMPEG : public ZmqBase { + public: + ZmqMPEG(const std::string name, + dab_input_zmq_config_t config) + : ZmqBase(name, config) { + RC_ADD_PARAMETER(buffer, + "Size of the input buffer [mpeg frames]"); + + RC_ADD_PARAMETER(prebuffering, + "Min buffer level before streaming starts [mpeg frames]"); + } + + private: + virtual int readFromSocket(size_t framesize); +}; + +class ZmqAAC : public ZmqBase { + public: + ZmqAAC(const std::string name, + dab_input_zmq_config_t config) + : ZmqBase(name, config) { + RC_ADD_PARAMETER(buffer, + "Size of the input buffer [aac superframes]"); + + RC_ADD_PARAMETER(prebuffering, + "Min buffer level before streaming starts [aac superframes]"); + } + + private: + virtual int readFromSocket(size_t framesize); +}; + +}; +#endif // HAVE_INPUT_ZMQ + + -- cgit v1.2.3 From 8db328c61832a92bf3f7641061b68767141104f3 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 4 Nov 2016 14:49:11 +0100 Subject: Change readFrame argument types --- src/dabInput.h | 2 +- src/input/File.cpp | 18 ++++++++---------- src/input/File.h | 6 +++--- src/input/Prbs.cpp | 8 +++----- src/input/Prbs.h | 2 +- src/input/Udp.cpp | 2 +- src/input/Udp.h | 2 +- src/input/Zmq.cpp | 2 +- src/input/Zmq.h | 2 +- src/input/inputs.h | 2 +- 10 files changed, 21 insertions(+), 25 deletions(-) (limited to 'src/dabInput.h') diff --git a/src/dabInput.h b/src/dabInput.h index 0accddb..d2c5f49 100644 --- a/src/dabInput.h +++ b/src/dabInput.h @@ -62,7 +62,7 @@ class DabInputCompatible : public DabInputBase { virtual int setbuf(int size) { return m_ops.setbuf(args, size); } - virtual int readFrame(void* buffer, int size) + virtual int readFrame(uint8_t* buffer, size_t size) { if (m_ops.lock) { m_ops.lock(args); diff --git a/src/input/File.cpp b/src/input/File.cpp index 9721b97..eb26136 100644 --- a/src/input/File.cpp +++ b/src/input/File.cpp @@ -64,7 +64,7 @@ int FileBase::rewind() return ::lseek(m_fd, 0, SEEK_SET); } -int MPEGFile::readFrame(void* buffer, int size) +int MPEGFile::readFrame(uint8_t* buffer, size_t size) { int result; bool do_rewind = false; @@ -122,7 +122,7 @@ MUTE_SUBCHANNEL: memset(buffer, 0, size); } else { - if (result < size) { + if (result < (ssize_t)size) { etiLog.log(warn, "bitrate too low from file " "-> frame padded\n"); memset((char*)buffer + result, 0, size - result); @@ -164,7 +164,7 @@ MUTE_SUBCHANNEL: int MPEGFile::setBitrate(int bitrate) { if (bitrate == 0) { - char buffer[4]; + uint8_t buffer[4]; if (readFrame(buffer, 4) == 0) { bitrate = getMpegBitrate(buffer); @@ -178,11 +178,9 @@ int MPEGFile::setBitrate(int bitrate) } -int DABPlusFile::readFrame(void* buffer, int size) +int DABPlusFile::readFrame(uint8_t* buffer, size_t size) { - uint8_t* dataOut = reinterpret_cast(buffer); - - ssize_t ret = read(m_fd, dataOut, size); + ssize_t ret = read(m_fd, buffer, size); if (ret == -1) { etiLog.log(alert, "ERROR: Can't read file\n"); @@ -190,7 +188,7 @@ int DABPlusFile::readFrame(void* buffer, int size) return -1; } - if (ret < size) { + if (ret < (ssize_t)size) { ssize_t sizeOut = ret; etiLog.log(info, "reach end of file -> rewinding\n"); if (rewind() == -1) { @@ -198,14 +196,14 @@ int DABPlusFile::readFrame(void* buffer, int size) return -1; } - ret = read(m_fd, dataOut + sizeOut, size - sizeOut); + ret = read(m_fd, buffer + sizeOut, size - sizeOut); if (ret == -1) { etiLog.log(alert, "ERROR: Can't read file\n"); perror(""); return -1; } - if (ret < size) { + if (ret < (ssize_t)size) { etiLog.log(alert, "ERROR: Not enough data in file\n"); return -1; } diff --git a/src/input/File.h b/src/input/File.h index 61be8b1..01f4f21 100644 --- a/src/input/File.h +++ b/src/input/File.h @@ -36,7 +36,7 @@ namespace Inputs { class FileBase : public InputBase { public: virtual int open(const std::string& name); - virtual int readFrame(void* buffer, int size) = 0; + virtual int readFrame(uint8_t* buffer, size_t size) = 0; virtual int setBitrate(int bitrate) = 0; virtual int close(); @@ -52,7 +52,7 @@ class FileBase : public InputBase { class MPEGFile : public FileBase { public: - virtual int readFrame(void* buffer, int size); + virtual int readFrame(uint8_t* buffer, size_t size); virtual int setBitrate(int bitrate); private: @@ -61,7 +61,7 @@ class MPEGFile : public FileBase { class DABPlusFile : public FileBase { public: - virtual int readFrame(void* buffer, int size); + virtual int readFrame(uint8_t* buffer, size_t size); virtual int setBitrate(int bitrate); }; diff --git a/src/input/Prbs.cpp b/src/input/Prbs.cpp index 8e5a9ae..607ce9f 100644 --- a/src/input/Prbs.cpp +++ b/src/input/Prbs.cpp @@ -77,12 +77,10 @@ int Prbs::open(const string& name) return 0; } -int Prbs::readFrame(void* buffer, int size) +int Prbs::readFrame(uint8_t* buffer, size_t size) { - unsigned char* cbuffer = reinterpret_cast(buffer); - - for (int i = 0; i < size; ++i) { - cbuffer[i] = m_prbs.step(); + for (size_t i = 0; i < size; ++i) { + buffer[i] = m_prbs.step(); } return size; diff --git a/src/input/Prbs.h b/src/input/Prbs.h index 1ad5047..3b2b7d4 100644 --- a/src/input/Prbs.h +++ b/src/input/Prbs.h @@ -38,7 +38,7 @@ namespace Inputs { class Prbs : public InputBase { public: virtual int open(const std::string& name); - virtual int readFrame(void* buffer, int size); + virtual int readFrame(uint8_t* buffer, size_t size); virtual int setBitrate(int bitrate); virtual int close(); diff --git a/src/input/Udp.cpp b/src/input/Udp.cpp index e534a06..a238d9b 100644 --- a/src/input/Udp.cpp +++ b/src/input/Udp.cpp @@ -87,7 +87,7 @@ int Udp::open(const std::string& name) return 0; } -int Udp::readFrame(void* buffer, int size) +int Udp::readFrame(uint8_t* buffer, size_t size) { uint8_t* data = reinterpret_cast(buffer); diff --git a/src/input/Udp.h b/src/input/Udp.h index b6705e9..379dbf3 100644 --- a/src/input/Udp.h +++ b/src/input/Udp.h @@ -36,7 +36,7 @@ namespace Inputs { class Udp : public InputBase { public: virtual int open(const std::string& name); - virtual int readFrame(void* buffer, int size); + virtual int readFrame(uint8_t* buffer, size_t size); virtual int setBitrate(int bitrate); virtual int close(); diff --git a/src/input/Zmq.cpp b/src/input/Zmq.cpp index 985fad3..a5601fa 100644 --- a/src/input/Zmq.cpp +++ b/src/input/Zmq.cpp @@ -246,7 +246,7 @@ int ZmqBase::setBitrate(int bitrate) } // size corresponds to a frame size. It is constant for a given bitrate -int ZmqBase::readFrame(void* buffer, int size) +int ZmqBase::readFrame(uint8_t* buffer, size_t size) { int rc; diff --git a/src/input/Zmq.h b/src/input/Zmq.h index 02fce3a..8d729e0 100644 --- a/src/input/Zmq.h +++ b/src/input/Zmq.h @@ -181,7 +181,7 @@ class ZmqBase : public InputBase, public RemoteControllable { } virtual int open(const std::string& inputUri); - virtual int readFrame(void* buffer, int size); + virtual int readFrame(uint8_t* buffer, size_t size); virtual int setBitrate(int bitrate); virtual int close(); diff --git a/src/input/inputs.h b/src/input/inputs.h index 3bc1fa4..bfb1fb6 100644 --- a/src/input/inputs.h +++ b/src/input/inputs.h @@ -39,7 +39,7 @@ namespace Inputs { class InputBase { public: virtual int open(const std::string& name) = 0; - virtual int readFrame(void* buffer, int size) = 0; + virtual int readFrame(uint8_t* buffer, size_t size) = 0; virtual int setBitrate(int bitrate) = 0; virtual int close() = 0; -- cgit v1.2.3 From e9b2ff4084c48e5978298ac080275e474d7858a8 Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 7 Nov 2016 21:58:44 +0100 Subject: Remove old src/dabInput files --- src/dabInput.cpp | 49 ---- src/dabInput.h | 103 -------- src/dabInputDabplusFifo.cpp | 186 ------------- src/dabInputDabplusFifo.h | 54 ---- src/dabInputDabplusFile.cpp | 177 ------------- src/dabInputDabplusFile.h | 62 ----- src/dabInputEnhancedFifo.cpp | 64 ----- src/dabInputEnhancedFifo.h | 46 ---- src/dabInputEnhancedPacketFile.cpp | 60 ----- src/dabInputEnhancedPacketFile.h | 47 ---- src/dabInputFifo.cpp | 518 ------------------------------------- src/dabInputFifo.h | 103 -------- src/dabInputFile.cpp | 104 -------- src/dabInputFile.h | 49 ---- src/dabInputMpegFifo.cpp | 47 ---- src/dabInputMpegFifo.h | 37 --- src/dabInputMpegFile.cpp | 170 ------------ src/dabInputMpegFile.h | 42 --- src/dabInputPacketFile.cpp | 263 ------------------- src/dabInputPacketFile.h | 46 ---- src/dabInputRawFifo.cpp | 193 -------------- src/dabInputRawFifo.h | 63 ----- src/dabInputRawFile.cpp | 59 ----- src/dabInputRawFile.h | 45 ---- src/dabInputUdp.cpp | 199 -------------- src/dabInputUdp.h | 59 ----- 26 files changed, 2845 deletions(-) delete mode 100644 src/dabInput.cpp delete mode 100644 src/dabInput.h delete mode 100644 src/dabInputDabplusFifo.cpp delete mode 100644 src/dabInputDabplusFifo.h delete mode 100644 src/dabInputDabplusFile.cpp delete mode 100644 src/dabInputDabplusFile.h delete mode 100644 src/dabInputEnhancedFifo.cpp delete mode 100644 src/dabInputEnhancedFifo.h delete mode 100644 src/dabInputEnhancedPacketFile.cpp delete mode 100644 src/dabInputEnhancedPacketFile.h delete mode 100644 src/dabInputFifo.cpp delete mode 100644 src/dabInputFifo.h delete mode 100644 src/dabInputFile.cpp delete mode 100644 src/dabInputFile.h delete mode 100644 src/dabInputMpegFifo.cpp delete mode 100644 src/dabInputMpegFifo.h delete mode 100644 src/dabInputMpegFile.cpp delete mode 100644 src/dabInputMpegFile.h delete mode 100644 src/dabInputPacketFile.cpp delete mode 100644 src/dabInputPacketFile.h delete mode 100644 src/dabInputRawFifo.cpp delete mode 100644 src/dabInputRawFifo.h delete mode 100644 src/dabInputRawFile.cpp delete mode 100644 src/dabInputRawFile.h delete mode 100644 src/dabInputUdp.cpp delete mode 100644 src/dabInputUdp.h (limited to 'src/dabInput.h') diff --git a/src/dabInput.cpp b/src/dabInput.cpp deleted file mode 100644 index 942e58d..0000000 --- a/src/dabInput.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in - Right of Canada (Communications Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInput.h" -#include "Log.h" - -#include - -bool dabInputOperations::operator==(const dabInputOperations& ops) -{ - return memcmp(this, &ops, sizeof(*this)) == 0; -} - - -int dabInputSetbuf(void* args, int size) -{ - return 0; -} - - -int dabInputSetbitrate(dabInputOperations* ops, void* args, int bitrate) -{ - if (bitrate <= 0) { - etiLog.log(error, "Invalid bitrate (%i)\n", bitrate); - return -1; - } - if (ops->setbuf(args, bitrate * 3) == 0) { - return bitrate; - } - return -1; -} diff --git a/src/dabInput.h b/src/dabInput.h deleted file mode 100644 index d2c5f49..0000000 --- a/src/dabInput.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in - Right of Canada (Communications Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_H -#define DAB_INPUT_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include "Log.h" -#include "RemoteControl.h" -#include - -// TODO replace usage of dabInputOperations by a -// class hierarchy -struct dabInputOperations { - int (*init)(void** args); - int (*open)(void* args, const char* name); - int (*setbuf)(void* args, int size); - int (*read)(void* args, void* buffer, int size); - int (*lock)(void* args); - int (*unlock)(void* args); - int (*readFrame)(dabInputOperations* ops, void* args, void* buffer, int size); - int (*setBitrate)(dabInputOperations* ops, void* args, int bitrate); - int (*close)(void* args); - int (*clean)(void** args); - int (*rewind)(void* args); - bool operator==(const dabInputOperations&); -}; - -/* Wrapper class for old-style dabInputOperations inputs */ -class DabInputCompatible : public DabInputBase { - public: - DabInputCompatible(dabInputOperations ops) - : m_ops(ops) - { m_ops.init(&args); } - - virtual ~DabInputCompatible() - { m_ops.clean(&args); } - - virtual int open(const std::string& name) - { return m_ops.open(args, name.c_str()); } - - virtual int setbuf(int size) - { return m_ops.setbuf(args, size); } - - virtual int readFrame(uint8_t* buffer, size_t size) - { - if (m_ops.lock) { - m_ops.lock(args); - } - int result = m_ops.readFrame(&m_ops, args, buffer, size); - if (m_ops.unlock) { - m_ops.unlock(args); - } - return result; - } - - virtual int setBitrate(int bitrate) - { return m_ops.setBitrate(&m_ops, args, bitrate); } - - virtual int close() - { return m_ops.close(args); } - - virtual int rewind() - { return m_ops.rewind(args); } - - virtual int read(void* buffer, int size) - { return m_ops.read(args, buffer, size); } - - virtual dabInputOperations getOpts() { return m_ops; } - - private: - DabInputCompatible& operator=(const DabInputCompatible& other); - DabInputCompatible(const DabInputCompatible& other); - - dabInputOperations m_ops; - void* args; -}; - -int dabInputSetbuf(void* args, int size); -int dabInputSetbitrate(dabInputOperations* ops, void* args, int bitrate); - - -#endif // DAB_INPUT_H diff --git a/src/dabInputDabplusFifo.cpp b/src/dabInputDabplusFifo.cpp deleted file mode 100644 index 94aec13..0000000 --- a/src/dabInputDabplusFifo.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputDabplusFifo.h" -#include "dabInputDabplusFile.h" -#include "dabInputFifo.h" -#include "dabInput.h" - -#include -#include -#include -#include -#include - -#ifndef _WIN32 -# define O_BINARY 0 -#endif - - -#ifdef HAVE_FORMAT_DABPLUS -# ifdef HAVE_INPUT_FILE - - -struct dabInputDabplusFifoData { - void* fifoData; - uint8_t* buffer; - size_t bufferSize; - size_t bufferIndex; - size_t bufferOffset; -}; - - -struct dabInputOperations dabInputDabplusFifoOperations = { - dabInputDabplusFifoInit, - dabInputDabplusFifoOpen, - dabInputDabplusFifoSetbuf, - dabInputDabplusFifoRead, - dabInputDabplusFifoLock, - dabInputDabplusFifoUnlock, - dabInputDabplusFileReadFrame, - dabInputSetbitrate, - dabInputDabplusFifoClose, - dabInputDabplusFifoClean, - dabInputDabplusFifoRewind -}; - - -int dabInputDabplusFifoInit(void** args) -{ - dabInputDabplusFifoData* data = new dabInputDabplusFifoData; - - dabInputFifoInit(&data->fifoData); - data->buffer = nullptr; - data->bufferSize = 0; - data->bufferIndex = 0; - data->bufferOffset = 0; - - *args = data; - - return 0; -} - - -int dabInputDabplusFifoOpen(void* args, const char* filename) -{ - dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - - return dabInputFifoOpen(data->fifoData, filename); -} - - -int dabInputDabplusFifoSetbuf(void* args, int size) -{ - dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - - return dabInputFifoSetbuf(data->fifoData, size); -} - - -int dabInputDabplusFifoRead(void* args, void* buffer, int size) -{ - dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - - if (data->bufferSize != (size_t)size * 5) { - if (data->buffer != nullptr) { - delete[] data->buffer; - } - data->buffer = new uint8_t[size * 5]; - data->bufferSize = size * 5; - data->bufferIndex = 0; - } - - if (data->bufferOffset < data->bufferSize) { - int ret = dabInputFifoRead(data->fifoData, - &data->buffer[data->bufferOffset], - data->bufferSize - data->bufferOffset); - if (ret < 0) { - return ret; - } - data->bufferOffset += ret; - if (data->bufferOffset != data->bufferSize) { - etiLog.log(alert, "ERROR: Incomplete DAB+ frame!\n"); - return 0; - } - } - - memcpy(buffer, &data->buffer[data->bufferIndex], size); - data->bufferIndex += size; - if (data->bufferIndex >= data->bufferSize) { - data->bufferIndex = 0; - data->bufferOffset = 0; - } - return size; -} - - -int dabInputDabplusFifoLock(void* args) -{ - dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - - return dabInputFifoLock(data->fifoData); -} - - -int dabInputDabplusFifoUnlock(void* args) -{ - dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - - return dabInputFifoUnlock(data->fifoData); -} - - -int dabInputDabplusFifoReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size) -{ - return ops->read(args, buffer, size); -} - - -int dabInputDabplusFifoClose(void* args) -{ - dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - - return dabInputFifoClose(data->fifoData); -} - - -int dabInputDabplusFifoClean(void** args) -{ - dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - - dabInputFifoClean(&data->fifoData); - delete data; - - return 0; -} - - -int dabInputDabplusFifoRewind(void* args) -{ - dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - - return dabInputFifoRewind(data->fifoData); -} - - -# endif -#endif diff --git a/src/dabInputDabplusFifo.h b/src/dabInputDabplusFifo.h deleted file mode 100644 index 83368d6..0000000 --- a/src/dabInputDabplusFifo.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_DABPLUS_FIFO_H -#define DAB_INPUT_DABPLUS_FIFO_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - - -#ifdef HAVE_FORMAT_DABPLUS -# ifdef HAVE_INPUT_FIFO - - -extern struct dabInputOperations dabInputDabplusFifoOperations; - - -int dabInputDabplusFifoInit(void** args); -int dabInputDabplusFifoOpen(void* args, const char* filename); -int dabInputDabplusFifoSetbuf(void* args, int size); -int dabInputDabplusFifoRead(void* args, void* buffer, int size); -int dabInputDabplusFifoLock(void* args); -int dabInputDabplusFifoUnlock(void* args); -int dabInputDabplusFifoReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size); -int dabInputDabplusFifoClose(void* args); -int dabInputDabplusFifoClean(void** args); -int dabInputDabplusFifoRewind(void* args); - - -# endif -#endif - - -#endif // DAB_INPUT_DABPLUS_FIFO_H diff --git a/src/dabInputDabplusFile.cpp b/src/dabInputDabplusFile.cpp deleted file mode 100644 index 64b7f07..0000000 --- a/src/dabInputDabplusFile.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputDabplusFile.h" -#include "dabInput.h" - -#include -#include -#include - -#ifndef _WIN32 -# define O_BINARY 0 -#endif - - -#ifdef HAVE_FORMAT_DABPLUS -# ifdef HAVE_INPUT_FILE - - -struct dabInputOperations dabInputDabplusFileOperations = { - dabInputDabplusFileInit, - dabInputDabplusFileOpen, - dabInputSetbuf, - dabInputDabplusFileRead, - nullptr, - nullptr, - dabInputDabplusFileReadFrame, - dabInputSetbitrate, - dabInputDabplusFileClose, - dabInputDabplusFileClean, - dabInputDabplusFileRewind -}; - - -int dabInputDabplusFileInit(void** args) -{ - dabInputDabplusFileData* data = new dabInputDabplusFileData; - data->file = -1; - data->buffer = nullptr; - data->bufferSize = 0; - data->bufferIndex = 0; - - *args = data; - return 0; -} - - -int dabInputDabplusFileOpen(void* args, const char* filename) -{ - dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; - data->file = open(filename, O_RDONLY | O_BINARY); - if (data->file == -1) { - perror(filename); - return -1; - } - - return 0; -} - - -int dabInputDabplusFileRead(void* args, void* buffer, int size) -{ - dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; - if (data->bufferSize != (size_t)size * 5) { - if (data->buffer == nullptr) { - delete[] data->buffer; - } - data->buffer = new uint8_t[size * 5]; - memset(data->buffer, 0, size * 5); - data->bufferSize = size * 5; - data->bufferIndex = 0; - } - - if (data->bufferIndex + size > data->bufferSize) { - int ret = read(data->file, data->buffer, data->bufferSize); - if (ret != (int)data->bufferSize) { - if (ret != 0) { - etiLog.log(alert, "ERROR: Incomplete DAB+ frame!\n"); - } - return 0; - } - data->bufferIndex = 0; - } - - memcpy(buffer, &data->buffer[data->bufferIndex], size); - data->bufferIndex += size; - - return size; -} - - -int dabInputDabplusFileReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size) -{ - //dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; - int result; - uint8_t* dataOut = reinterpret_cast(buffer); - - result = ops->read(args, dataOut, size); - if (result == -1) { - etiLog.log(alert, "ERROR: Can't read file\n"); - perror(""); - return -1; - } - if (result < size) { - int sizeOut = result; - etiLog.log(info, "reach end of file -> rewinding\n"); - if (ops->rewind(args) == -1) { - etiLog.log(alert, "ERROR: Can't rewind file\n"); - return -1; - } - - result = ops->read(args, dataOut + sizeOut, size - sizeOut); - if (result == -1) { - etiLog.log(alert, "ERROR: Can't read file\n"); - perror(""); - return -1; - } - - if (result < size) { - etiLog.log(alert, "ERROR: Not enought data in file\n"); - return -1; - } - } - - return size; -} - - -int dabInputDabplusFileClose(void* args) -{ - dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; - if (data->file != -1) { - close(data->file); - } - return 0; -} - - -int dabInputDabplusFileClean(void** args) -{ - dabInputDabplusFileData* data = (dabInputDabplusFileData*)*args; - if (data->buffer != nullptr) { - delete[] data->buffer; - } - delete data; - return 0; -} - - -int dabInputDabplusFileRewind(void* args) -{ - dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; - return lseek(data->file, 0, SEEK_SET); -} - - -# endif -#endif diff --git a/src/dabInputDabplusFile.h b/src/dabInputDabplusFile.h deleted file mode 100644 index 5fe2dec..0000000 --- a/src/dabInputDabplusFile.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_DABPLUS_FILE_H -#define DAB_INPUT_DABPLUS_FILE_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include - - -#ifdef HAVE_FORMAT_DABPLUS -# ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputDabplusFileOperations; - - -struct dabInputDabplusFileData { - int file; - uint8_t* buffer; - size_t bufferSize; - size_t bufferIndex; -}; - - -int dabInputDabplusFileInit(void** args); -int dabInputDabplusFileOpen(void* args, const char* filename); -int dabInputDabplusFileRead(void* args, void* buffer, int size); -int dabInputDabplusFileReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size); -int dabInputDabplusFileClose(void* args); -int dabInputDabplusFileClean(void** args); -int dabInputDabplusFileRewind(void* args); - - -# endif -#endif - - -#endif // DAB_INPUT_DABPLUS_FILE_H diff --git a/src/dabInputEnhancedFifo.cpp b/src/dabInputEnhancedFifo.cpp deleted file mode 100644 index 3a8a27c..0000000 --- a/src/dabInputEnhancedFifo.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputEnhancedFifo.h" -#include "dabInputPacketFile.h" -#include "dabInputFifo.h" - - -#ifdef HAVE_FORMAT_PACKET -# ifdef HAVE_FORMAT_EPM -# ifdef HAVE_INPUT_FIFO - - -struct dabInputOperations dabInputEnhancedFifoOperations = { - dabInputEnhancedFifoInit, - dabInputFifoOpen, - dabInputFifoSetbuf, - dabInputFifoRead, - dabInputFifoLock, - dabInputFifoUnlock, - dabInputPacketFileRead, - dabInputSetbitrate, - dabInputFifoClose, - dabInputFifoClean, - dabInputFifoRewind -}; - - -int dabInputEnhancedFifoInit(void** args) -{ - dabInputFifoInit(args); - dabInputFifoData* data = (dabInputFifoData*)*args; - - data->packetData = new unsigned char[96]; - data->enhancedPacketData = new unsigned char*[12]; - for (int i = 0; i < 12; ++i) { - data->enhancedPacketData[i] = new unsigned char[204]; - } - - return 0; -} - - -# endif -# endif -#endif diff --git a/src/dabInputEnhancedFifo.h b/src/dabInputEnhancedFifo.h deleted file mode 100644 index 4c87e24..0000000 --- a/src/dabInputEnhancedFifo.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_ENHANCED_FIFO_H -#define DAB_INPUT_ENHANCED_FIFO_H - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_PACKET -# ifdef HAVE_FORMAT_EPM -# ifdef HAVE_INPUT_FIFO - - -extern struct dabInputOperations dabInputEnhancedFifoOperations; -int dabInputEnhancedFifoInit(void** args); - - -# endif -# endif -#endif - - -#endif // DAB_INPUT_ENHANCED_FIFO_H diff --git a/src/dabInputEnhancedPacketFile.cpp b/src/dabInputEnhancedPacketFile.cpp deleted file mode 100644 index 5c26188..0000000 --- a/src/dabInputEnhancedPacketFile.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputEnhancedPacketFile.h" -#include "dabInputPacketFile.h" -#include "dabInputFile.h" - -#ifdef HAVE_FORMAT_PACKET -# ifdef HAVE_FORMAT_EPM -# ifdef HAVE_INPUT_FILE - -struct dabInputOperations dabInputEnhancedPacketFileOperations = { - dabInputEnhancedFileInit, - dabInputFileOpen, - dabInputSetbuf, - dabInputFileRead, - nullptr, - nullptr, - dabInputPacketFileRead, - dabInputSetbitrate, - dabInputFileClose, - dabInputFileClean, - dabInputFileRewind -}; - - -int dabInputEnhancedFileInit(void** args) -{ - dabInputFileInit(args); - dabInputFileData* data = (dabInputFileData*)*args; - - data->enhancedPacketData = new unsigned char*[12]; - for (int i = 0; i < 12; ++i) { - data->enhancedPacketData[i] = new unsigned char[204]; - } - - return 0; -} - -# endif -# endif -#endif diff --git a/src/dabInputEnhancedPacketFile.h b/src/dabInputEnhancedPacketFile.h deleted file mode 100644 index 74f59de..0000000 --- a/src/dabInputEnhancedPacketFile.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_ENHANCED_PACKET_FILE_H -#define DAB_INPUT_ENHANCED_PACKET_FILE_H - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_PACKET -# ifdef HAVE_FORMAT_EPM -# ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputEnhancedPacketFileOperations; - -int dabInputEnhancedFileInit(void** args); - - -# endif -# endif -#endif - - -#endif // DAB_INPUT_ENHANCED_PACKET_FILE_H diff --git a/src/dabInputFifo.cpp b/src/dabInputFifo.cpp deleted file mode 100644 index 6fa3aad..0000000 --- a/src/dabInputFifo.cpp +++ /dev/null @@ -1,518 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Copyright (C) 2016 - Matthias P. Braendli, matthias.braendli@mpb.li - - http://www.opendigitalradio.org - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputFifo.h" -#include "dabInputPacketFile.h" -#include "dabInput.h" - -#include -#include -#include -#include -#include - - -#ifdef HAVE_FORMAT_PACKET -# ifdef HAVE_INPUT_FIFO - - -int dabInputFifoData::nb = 0; - - -struct dabInputOperations dabInputFifoOperations = { - dabInputFifoInit, - dabInputFifoOpen, - dabInputFifoSetbuf, - dabInputFifoRead, - dabInputFifoLock, - dabInputFifoUnlock, - dabInputPacketFileRead, - dabInputSetbitrate, - dabInputFifoClose, - dabInputFifoClean, - dabInputFifoRewind -}; - - -int dabInputFifoInit(void** args) -{ - dabInputFifoData* data = new dabInputFifoData; - memset(data, 0, sizeof(*data)); - data->stats.id = dabInputFifoData::nb++; - data->maxSize = 0; - data->curSize = 0; - data->head = 0; - data->tail = 0; - data->buffer = nullptr; - data->packetData = nullptr; - data->enhancedPacketData = nullptr; - data->packetLength = 0; - data->enhancedPacketLength = 0; - data->enhancedPacketWaiting = 0; - data->full = false; - data->running = true; - data->thread = (pthread_t)NULL; -#ifdef _WIN32 - char semName[32]; - sprintf(semName, "semInfo%i", data->stats.id); - data->semInfo = CreateSemaphore(NULL, 1, 1, semName); - if (data->semInfo == NULL) { - fprintf(stderr, "Can't init FIFO data semaphore %s\n", semName); - return -1; - } - sprintf(semName, "semBuffer%i", data->stats.id); - data->semBuffer = CreateSemaphore(NULL, 1, 1, semName); - if (data->semBuffer == NULL) { - fprintf(stderr, "Can't init FIFO buffer semaphore %s\n", semName); - return -1; - } - sprintf(semName, "semFull%i", data->stats.id); - data->semFull = CreateSemaphore(NULL, 1, 1, semName); - if (data->semFull == NULL) { - fprintf(stderr, "Can't init FIFO semaphore %s\n", semName); - return -1; - } -#else - if (sem_init(&data->semInfo, 0, 1) == -1) { - perror("Can't init FIFO data semaphore"); - return -1; - } - if (sem_init(&data->semBuffer, 0, 0) == -1) { - perror("Can't init fIFO buffer semaphore"); - return -1; - } - if (sem_init(&data->semFull, 0, 0) == -1) { - perror("Can't init FIFO semaphore"); - return -1; - } -#endif - - if (data->maxSize > 0) { -#ifdef _WIN32 - ReleaseSemaphore(data->semBuffer, 1, NULL); -#else - sem_post(&data->semBuffer); -#endif - } - *args = data; - return 0; -} - - -int dabInputFifoOpen(void* args, const char* filename) -{ - dabInputFifoData* data = (dabInputFifoData*)args; - data->file = open(filename, O_RDONLY | O_BINARY | O_NONBLOCK); - if (data->file == -1) { - perror(filename); - return -1; - } -#ifdef _WIN32 -#else - int flags = fcntl(data->file, F_GETFL); - if (flags == -1) { - perror(filename); - return -1; - } - if (fcntl(data->file, F_SETFL, flags & ~O_NONBLOCK) == -1) { - perror(filename); - return -1; - } -#endif - -#ifdef _WIN32 - data->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)dabInputFifoThread, data, 0, NULL); - if (data->thread == NULL) { - fprintf(stderr, "Can't create FIFO child\n"); - return -1; - } -#else - if (pthread_create(&data->thread, nullptr, dabInputFifoThread, data)) { - perror("Can't create FIFO child"); - return -1; - } -#endif - - return 0; -} - - -int dabInputFifoSetbuf(void* args, int size) -{ - dabInputFifoData* data = (dabInputFifoData*)args; - - if (data->maxSize > 0) { -#ifdef _WIN32 - WaitForSingleObject(data->semBuffer, INFINITE); -#else - sem_wait(&data->semBuffer); -#endif - } - if (data->buffer != nullptr) { - delete data->buffer; - } - if (size == 0) { - size = 1024; - } - data->buffer = new unsigned char[size * 16]; - data->maxSize = size * 16; -#ifdef _WIN32 - ReleaseSemaphore(data->semBuffer, 1, NULL); -#else - sem_post(&data->semBuffer); -#endif - - return 0; -} - - -int dabInputFifoRead(void* args, void* buffer, int size) -{ - //fprintf(stderr, "INFO: read %i bytes\n", size); - dabInputFifoData* data = (dabInputFifoData*)args; - dabInputFifoStats* stats = &data->stats; - int head; - int tail; - int curSize; - int maxSize; -#ifdef _WIN32 - WaitForSingleObject(data->semInfo, INFINITE); -#else - sem_wait(&data->semInfo); -#endif - head = data->head; - tail = data->tail; - curSize = data->curSize; - maxSize = data->maxSize; -#ifdef _WIN32 - ReleaseSemaphore(data->semInfo, 1, NULL); -#else - sem_post(&data->semInfo); -#endif - //fprintf(stderr, "head: %i, tail: %i, curSize: %i\n", head, tail, curSize); - if (size > curSize) { - if (curSize == 0) { - stats->empty = true; - } else { - etiLog.log(warn, "Not enough data in FIFO buffer: (%i) %i/%i\n", - data->stats.id, curSize, size); - } - return 0; - } - if (head > tail) { - memcpy(buffer, data->buffer + tail, size); -#ifdef _WIN32 - WaitForSingleObject(data->semInfo, INFINITE); -#else - sem_wait(&data->semInfo); -#endif - data->tail += size; - data->curSize -= size; -#ifdef _WIN32 - ReleaseSemaphore(data->semInfo, 1, NULL); -#else - sem_post(&data->semInfo); -#endif - return size; - } else { - if (maxSize - tail >= size) { - memcpy(buffer, data->buffer + tail, size); -#ifdef _WIN32 - WaitForSingleObject(data->semInfo, INFINITE); -#else - sem_wait(&data->semInfo); -#endif - data->tail += size; - data->curSize -= size; -#ifdef _WIN32 - ReleaseSemaphore(data->semInfo, 1, NULL); -#else - sem_post(&data->semInfo); -#endif - return size; - } else { - memcpy(buffer, data->buffer + tail, maxSize - tail); -#ifdef _WIN32 - WaitForSingleObject(data->semInfo, INFINITE); -#else - sem_wait(&data->semInfo); -#endif - data->tail = 0; - data->curSize -= maxSize - tail; -#ifdef _WIN32 - ReleaseSemaphore(data->semInfo, 1, NULL); -#else - sem_post(&data->semInfo); -#endif - return maxSize - tail + dabInputFifoRead(data, (char*)buffer + maxSize - tail, size - (maxSize - tail)); - } - } - return -1; -} - - -int dabInputFifoLock(void* args) { - dabInputFifoData* data = (dabInputFifoData*)args; - dabInputFifoStats* stats = &data->stats; - - int maxSize; - int curSize; -#ifdef _WIN32 - WaitForSingleObject(data->semInfo, INFINITE); -#else - sem_wait(&data->semInfo); -#endif - maxSize = data->maxSize; - curSize = data->curSize; -#ifdef _WIN32 - ReleaseSemaphore(data->semInfo, 1, NULL); -#else - sem_post(&data->semInfo); -#endif - - stats->bufferRecords[stats->bufferCount].curSize = curSize; - stats->bufferRecords[stats->bufferCount].maxSize = maxSize; - - if (++stats->bufferCount == NB_RECORDS) { - etiLog.log(info, "FIFO buffer state: (%i)", stats->id); - for (int i = 0; i < stats->bufferCount; ++i) { - etiLog.log(info, " %i/%i", - stats->bufferRecords[i].curSize, - stats->bufferRecords[i].maxSize); - } - etiLog.log(info, "\n"); - - if (stats->full) { - etiLog.log(warn, "FIFO buffer full: (%i)\n", - data->stats.id); - stats->full = false; - } - if (stats->empty) { - etiLog.log(warn, "FIFO buffer empty: (%i)\n", - data->stats.id); - stats->empty = false; - } - if (stats->error) { - etiLog.log(error, "FIFO input read error: (%i)\n", - data->stats.id); - stats->error = false; - } - if (stats->input) { - etiLog.log(error, "FIFO input not connected: (%i)\n", - data->stats.id); - stats->input = false; - } - - stats->bufferCount = 0; - } - return 0; -} - - -int dabInputFifoUnlock(void* args) { - dabInputFifoData* data = (dabInputFifoData*)args; - if (data->full) { -#ifdef _WIN32 - ReleaseSemaphore(data->semFull, 1, NULL); -#else - sem_post(&data->semFull); -#endif - } - return 0; -} - - -int dabInputFifoClose(void* args) -{ - dabInputFifoData* data = (dabInputFifoData*)args; - close(data->file); - return 0; -} - - -int dabInputFifoClean(void** args) -{ - dabInputFifoData* data = (dabInputFifoData*)*args; - data->running = false; - etiLog.log(debug, "Wait FIFO child...\n"); -#ifdef WIN32 - DWORD status; - for (int i = 0; i < 5; ++i) { - if (GetExitCodeThread(data->thread, &status)) { - break; - } - Sleep(100); - } - TerminateThread(data->thread, 1); - if (CloseHandle(data->thread) == 0) { - etiLog.log(debug, "ERROR: Failed to close FIFO child thread\n"); - } -#else - if (data->thread != (pthread_t)NULL) { - if (pthread_join(data->thread, nullptr)) { - etiLog.log(debug, "ERROR: FIFO child thread had not exit normally\n"); - } - } -#endif - etiLog.log(debug, "Done\n"); -#ifdef _WIN32 - CloseHandle(data->semInfo); - CloseHandle(data->semFull); - CloseHandle(data->semBuffer); -#else - sem_destroy(&data->semInfo); - sem_destroy(&data->semFull); - sem_destroy(&data->semBuffer); -#endif - if (data->packetData != nullptr) { - delete[] data->packetData; - } - if (data->enhancedPacketData != nullptr) { - for (int i = 0; i < 12; ++i) { - if (data->enhancedPacketData[i] != nullptr) { - delete[] data->enhancedPacketData[i]; - } - } - delete[] data->enhancedPacketData; - } - delete data->buffer; - delete data; - return 0; -} - - -int dabInputFifoRewind(void* args) -{ - return -1; -} - - -void* dabInputFifoThread(void* args) -{ - dabInputFifoData* data = (dabInputFifoData*)args; - int head; - int tail; - int curSize; - int maxSize; - int ret; - while (data->running) { -#ifdef _WIN32 - WaitForSingleObject(data->semBuffer, INFINITE); - WaitForSingleObject(data->semInfo, INFINITE); -#else - sem_wait(&data->semBuffer); - sem_wait(&data->semInfo); -#endif - head = data->head; - tail = data->tail; - curSize = data->curSize; - maxSize = data->maxSize; -#ifdef _WIN32 - ReleaseSemaphore(data->semInfo, 1, NULL); -#else - sem_post(&data->semInfo); -#endif - //fprintf(stderr, "thread, head: %i, tail: %i, curSize: %i\n", head, tail, curSize); - - if (curSize == maxSize) { - data->stats.full = true; - data->full = true; -#ifdef _WIN32 - WaitForSingleObject(data->semFull, INFINITE); -#else - sem_wait(&data->semFull); -#endif - } else if (head >= tail) { // 2 blocks - ret = read(data->file, data->buffer + head, maxSize - head); - if (ret == 0) { - data->stats.input = true; - data->full = true; -#ifdef _WIN32 - WaitForSingleObject(data->semFull, INFINITE); -#else - sem_wait(&data->semFull); -#endif - } else if (ret == -1) { - data->stats.error = true; - } else { -#ifdef _WIN32 - WaitForSingleObject(data->semInfo, INFINITE); -#else - sem_wait(&data->semInfo); -#endif - data->head += ret; - data->curSize += ret; - if (data->head == maxSize) { - data->head = 0; - } -#ifdef _WIN32 - ReleaseSemaphore(data->semInfo, 1, NULL); -#else - sem_post(&data->semInfo); -#endif - } - } else { // 1 block - ret = read(data->file, data->buffer + head, tail - head); - if (ret == 0) { - data->stats.input = true; - data->full = true; -#ifdef _WIN32 - WaitForSingleObject(data->semFull, INFINITE); -#else - sem_wait(&data->semFull); -#endif - } else if (ret == -1) { - data->stats.error = true; - } else { -#ifdef _WIN32 - WaitForSingleObject(data->semInfo, INFINITE); -#else - sem_wait(&data->semInfo); -#endif - data->head += ret; - data->curSize += ret; - if (data->head == maxSize) { - data->head = 0; - } -#ifdef _WIN32 - ReleaseSemaphore(data->semInfo, 1, NULL); -#else - sem_post(&data->semInfo); -#endif - } - } -#ifdef _WIN32 - ReleaseSemaphore(data->semBuffer, 1, NULL); -#else - sem_post(&data->semBuffer); -#endif - } - return nullptr; -} - - -# endif -#endif diff --git a/src/dabInputFifo.h b/src/dabInputFifo.h deleted file mode 100644 index 99edac6..0000000 --- a/src/dabInputFifo.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - - Copyright (C) 2016 - Matthias P. Braendli, matthias.braendli@mpb.li - - http://www.opendigitalradio.org - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#pragma once - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "dabInputFile.h" -#include "Log.h" - - -#ifdef _WIN32 -# include -# define sem_t HANDLE -# define O_NONBLOCK 0 -#else -# include -# define O_BINARY 0 -#endif - - -#ifdef HAVE_FORMAT_PACKET -# ifdef HAVE_INPUT_FIFO -extern struct dabInputOperations dabInputFifoOperations; - - -struct dabInputFifoStatRecord { - int curSize; - int maxSize; -}; - - -#define NB_RECORDS 10 -struct dabInputFifoStats { - int id; - bool full; - bool empty; - bool error; - bool input; - int bufferCount; - dabInputFifoStatRecord bufferRecords[NB_RECORDS]; - int frameCount; - dabInputFifoStatRecord frameRecords[NB_RECORDS]; -}; - - -struct dabInputFifoData : dabInputFileData { - static int nb; - int maxSize; - int curSize; - int head; - int tail; - dabInputFifoStats stats; - unsigned char* buffer; - pthread_t thread; - sem_t semInfo; - sem_t semBuffer; - sem_t semFull; - bool full; - bool running; -}; - - -int dabInputFifoInit(void** args); -int dabInputFifoOpen(void* args, const char* filename); -int dabInputFifoSetbuf(void* args, int size); -int dabInputFifoRead(void* args, void* buffer, int size); -int dabInputFifoLock(void* args); -int dabInputFifoUnlock(void* args); -int dabInputFifoClose(void* args); -int dabInputFifoClean(void** args); -int dabInputFifoRewind(void* args); -void* dabInputFifoThread(void* args); - - -# endif -#endif - diff --git a/src/dabInputFile.cpp b/src/dabInputFile.cpp deleted file mode 100644 index 2847caa..0000000 --- a/src/dabInputFile.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - Copyright (C) 2009,2011 Her Majesty the Queen in Right of Canada - (Communications Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputFile.h" - -#include -#include -#include -#include - -#ifndef _WIN32 -# define O_BINARY 0 -#endif - - -int dabInputFileInit(void** args) -{ - dabInputFileData* data = new dabInputFileData; - data->file = -1; - data->parity = false; - data->packetLength = 0; - data->packetData = new unsigned char[96]; - data->enhancedPacketData = nullptr; - data->enhancedPacketLength = 0; - data->enhancedPacketWaiting = 0; - - *args = data; - return 0; -} - - -int dabInputFileOpen(void* args, const char* filename) -{ - dabInputFileData* data = (dabInputFileData*)args; - data->file = open(filename, O_RDONLY | O_BINARY); - if (data->file == -1) { - perror(filename); - return -1; - } - return 0; -} - - -int dabInputFileRead(void* args, void* buffer, int size) -{ - dabInputFileData* data = (dabInputFileData*)args; - return read(data->file, buffer, size); -} - - -int dabInputFileClose(void* args) -{ - dabInputFileData* data = (dabInputFileData*)args; - if (data->file != -1) { - close(data->file); - } - return 0; -} - - -int dabInputFileClean(void** args) -{ - dabInputFileData* data = (dabInputFileData*)*args; - if (data->packetData != nullptr) { - delete[] data->packetData; - } - if (data->enhancedPacketData != nullptr) { - for (int i = 0; i < 12; ++i) { - if (data->enhancedPacketData[i] != nullptr) { - delete[] data->enhancedPacketData[i]; - } - } - delete[] data->enhancedPacketData; - } - delete data; - return 0; -} - - -int dabInputFileRewind(void* args) -{ - dabInputFileData* data = (dabInputFileData*)args; - return lseek(data->file, 0, SEEK_SET); -} - - diff --git a/src/dabInputFile.h b/src/dabInputFile.h deleted file mode 100644 index e3eaa48..0000000 --- a/src/dabInputFile.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_FILE_H -#define DAB_INPUT_FILE_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - - -struct dabInputFileData { - int file; - bool parity; - unsigned packetLength; - unsigned char* packetData; - unsigned char** enhancedPacketData; - unsigned enhancedPacketLength; - unsigned enhancedPacketWaiting; -}; - - -int dabInputFileInit(void** args); -int dabInputFileOpen(void* args, const char* filename); -int dabInputFileRead(void* args, void* buffer, int size); -int dabInputFileClose(void* args); -int dabInputFileClean(void** args); -int dabInputFileRewind(void* args); - - -#endif // DAB_INPUT_FILE_H diff --git a/src/dabInputMpegFifo.cpp b/src/dabInputMpegFifo.cpp deleted file mode 100644 index 0f1d3b0..0000000 --- a/src/dabInputMpegFifo.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputMpegFifo.h" -#include "dabInputFifo.h" -#include "dabInputMpegFile.h" - - -#ifdef HAVE_FORMAT_MPEG -# ifdef HAVE_INPUT_FIFO - - -struct dabInputOperations dabInputMpegFifoOperations = { - dabInputFifoInit, - dabInputFifoOpen, - dabInputFifoSetbuf, - dabInputFifoRead, - dabInputFifoLock, - dabInputFifoUnlock, - dabInputMpegFileRead, - dabInputSetbitrate, - dabInputFifoClose, - dabInputFifoClean, - dabInputFifoRewind -}; - - -# endif -#endif diff --git a/src/dabInputMpegFifo.h b/src/dabInputMpegFifo.h deleted file mode 100644 index a14ccbd..0000000 --- a/src/dabInputMpegFifo.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_MPEG_FIFO_H -#define DAB_INPUT_MPEG_FIFO_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - - -#ifdef HAVE_FORMAT_MPEG -# ifdef HAVE_INPUT_FIFO -extern struct dabInputOperations dabInputMpegFifoOperations; -# endif -#endif - - -#endif // DAB_INPUT_MPEG_FIFO_H diff --git a/src/dabInputMpegFile.cpp b/src/dabInputMpegFile.cpp deleted file mode 100644 index 6f24f32..0000000 --- a/src/dabInputMpegFile.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputMpegFile.h" -#include "dabInputFile.h" -#include "mpeg.h" - -#include -#include -#include - - -#ifdef HAVE_FORMAT_MPEG -# ifdef HAVE_INPUT_FILE - - -struct dabInputOperations dabInputMpegFileOperations = { - dabInputFileInit, - dabInputFileOpen, - dabInputSetbuf, - dabInputFileRead, - nullptr, - nullptr, - dabInputMpegFileRead, - dabInputMpegSetbitrate, - dabInputFileClose, - dabInputFileClean, - dabInputFileRewind -}; - - -int dabInputMpegFileRead(dabInputOperations* ops, void* args, void* buffer, int size) -{ - dabInputFileData* data = (dabInputFileData*)args; - int result; - bool rewind = false; -READ_SUBCHANNEL: - if (data->parity) { - result = readData(data->file, buffer, size, 2); - data->parity = false; - return 0; - } else { - result = readMpegHeader(data->file, buffer, size); - if (result > 0) { - result = readMpegFrame(data->file, buffer, size); - if (result < 0 && getMpegFrequency(buffer) == 24000) { - data->parity = true; - result = size; - } - } - } - switch (result) { - case MPEG_BUFFER_UNDERFLOW: - etiLog.log(warn, "data underflow -> frame muted\n"); - goto MUTE_SUBCHANNEL; - case MPEG_BUFFER_OVERFLOW: - etiLog.log(warn, "bitrate too high -> frame muted\n"); - goto MUTE_SUBCHANNEL; - case MPEG_FILE_EMPTY: - if (rewind) { - etiLog.log(error, "file rewinded and still empty " - "-> frame muted\n"); - goto MUTE_SUBCHANNEL; - } else { - rewind = true; - etiLog.log(info, "reach end of file -> rewinding\n"); - lseek(data->file, 0, SEEK_SET); - goto READ_SUBCHANNEL; - } - case MPEG_FILE_ERROR: - etiLog.log(alert, "can't read file (%i) -> frame muted\n", errno); - perror(""); - goto MUTE_SUBCHANNEL; - case MPEG_SYNC_NOT_FOUND: - etiLog.log(alert, "mpeg sync not found, maybe is not a valid file " - "-> frame muted\n"); - goto MUTE_SUBCHANNEL; - case MPEG_INVALID_FRAME: - etiLog.log(alert, "file is not a valid mpeg file " - "-> frame muted\n"); - goto MUTE_SUBCHANNEL; - default: - if (result < 0) { - etiLog.log(alert, - "unknown error (code = %i) -> frame muted\n", - result); -MUTE_SUBCHANNEL: - memset(buffer, 0, size); - } else { - if (result < size) { - etiLog.log(warn, "bitrate too low from file " - "-> frame padded\n"); - memset((char*)buffer + result, 0, size - result); - } - result = checkDabMpegFrame(buffer); - switch (result) { - case MPEG_FREQUENCY: - etiLog.log(error, "file has a frame with an invalid " - "frequency: %i, should be 48000 or 24000\n", - getMpegFrequency(buffer)); - break; - case MPEG_PADDING: - etiLog.log(warn, - "file has a frame with padding bit set\n"); - break; - case MPEG_COPYRIGHT: - etiLog.log(warn, - "file has a frame with copyright bit set\n"); - break; - case MPEG_ORIGINAL: - etiLog.log(warn, - "file has a frame with original bit set\n"); - break; - case MPEG_EMPHASIS: - etiLog.log(warn, - "file has a frame with emphasis bits set\n"); - break; - default: - if (result < 0) { - etiLog.log(alert, "mpeg file has an invalid DAB " - "mpeg frame (unknown reason: %i)\n", result); - } - break; - } - } - } - return result; -} - - -int dabInputMpegSetbitrate(dabInputOperations* ops, void* args, int bitrate) -{ - //dabInputFileData* data = (dabInputFileData*)args; - if (bitrate == 0) { - char buffer[4]; - - if (ops->readFrame(ops, args, buffer, 4) == 0) { - bitrate = getMpegBitrate(buffer); - } else { - bitrate = -1; - } - ops->rewind(args); - } - if (ops->setbuf(args, bitrate * 3) != 0) { - bitrate = -1; - } - return bitrate; -} - - -# endif -#endif diff --git a/src/dabInputMpegFile.h b/src/dabInputMpegFile.h deleted file mode 100644 index a7dcb76..0000000 --- a/src/dabInputMpegFile.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_MPEG_FILE_H -#define DAB_INPUT_MPEG_FILE_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_MPEG -# ifdef HAVE_INPUT_FILE -extern struct dabInputOperations dabInputMpegFileOperations; - -int dabInputMpegFileRead(dabInputOperations* ops, void* args, void* buffer, int size); -int dabInputMpegSetbitrate(dabInputOperations* ops, void* args, int bitrate); -int checkDabMpegFrame(void* data); -# endif -#endif - - -#endif // DAB_INPUT_MPEG_FILE_H diff --git a/src/dabInputPacketFile.cpp b/src/dabInputPacketFile.cpp deleted file mode 100644 index 867d9fc..0000000 --- a/src/dabInputPacketFile.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* - Copyright (C) 2009, 2011 Her Majesty the Queen in Right of Canada - (Communications Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputPacketFile.h" -#include "dabInputFile.h" -#include "dabInputFifo.h" -#include "ReedSolomon.h" - -#ifdef HAVE_FORMAT_PACKET -# ifdef HAVE_INPUT_FILE - - -#include -#include -#include - - -#ifdef _WIN32 -# pragma pack(push, 1) -#endif -struct packetHeader { - unsigned char addressHigh:2; - unsigned char last:1; - unsigned char first:1; - unsigned char continuityIndex:2; - unsigned char packetLength:2; - unsigned char addressLow; - unsigned char dataLength:7; - unsigned char command; -} -#ifdef _WIN32 -# pragma pack(pop) -#else -__attribute((packed)) -#endif -; - - -struct dabInputOperations dabInputPacketFileOperations = { - dabInputFileInit, - dabInputFileOpen, - dabInputSetbuf, - dabInputFileRead, - nullptr, - nullptr, - dabInputPacketFileRead, - dabInputSetbitrate, - dabInputFileClose, - dabInputFileClean, - dabInputFileRewind -}; - - -int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, - int size) -{ - dabInputFileData* data = (dabInputFileData*)args; - unsigned char* dataBuffer = (unsigned char*)buffer; - int written = 0; - int length; - packetHeader* header; - int indexRow; - int indexCol; - - while (written < size) { - if (data->enhancedPacketWaiting > 0) { - *dataBuffer = 192 - data->enhancedPacketWaiting; - *dataBuffer /= 22; - *dataBuffer <<= 2; - *(dataBuffer++) |= 0x03; - *(dataBuffer++) = 0xfe; - indexCol = 188; - indexCol += (192 - data->enhancedPacketWaiting) / 12; - indexRow = 0; - indexRow += (192 - data->enhancedPacketWaiting) % 12; - for (int j = 0; j < 22; ++j) { - if (data->enhancedPacketWaiting == 0) { - *(dataBuffer++) = 0; - } else { - *(dataBuffer++) = data->enhancedPacketData[indexRow][indexCol]; - if (++indexRow == 12) { - indexRow = 0; - ++indexCol; - } - --data->enhancedPacketWaiting; - } - } - written += 24; - if (data->enhancedPacketWaiting == 0) { - data->enhancedPacketLength = 0; - } - } else if (data->packetLength != 0) { - header = (packetHeader*)data->packetData; - if (written + data->packetLength > (unsigned)size) { - memset(dataBuffer, 0, 22); - dataBuffer[22] = 0x60; - dataBuffer[23] = 0x4b; - length = 24; - } else if (data->enhancedPacketData != nullptr) { - if (data->enhancedPacketLength + data->packetLength - > (12 * 188)) { - memset(dataBuffer, 0, 22); - dataBuffer[22] = 0x60; - dataBuffer[23] = 0x4b; - length = 24; - } else { - memcpy(dataBuffer, data->packetData, data->packetLength); - length = data->packetLength; - data->packetLength = 0; - } - } else { - memcpy(dataBuffer, data->packetData, data->packetLength); - length = data->packetLength; - data->packetLength = 0; - } - if (data->enhancedPacketData != nullptr) { - indexCol = data->enhancedPacketLength / 12; - indexRow = data->enhancedPacketLength % 12; // TODO Check if always 0 - for (int j = 0; j < length; ++j) { - data->enhancedPacketData[indexRow][indexCol] = dataBuffer[j]; - if (++indexRow == 12) { - indexRow = 0; - ++indexCol; - } - } - data->enhancedPacketLength += length; - if (data->enhancedPacketLength >= (12 * 188)) { - data->enhancedPacketLength = (12 * 188); - ReedSolomon encoder(204, 188); - for (int j = 0; j < 12; ++j) { - encoder.encode(data->enhancedPacketData[j], 188); - } - data->enhancedPacketWaiting = 192; - } - } - written += length; - dataBuffer += length; - } else { - int nbBytes = ops->read(args, dataBuffer, 3); - header = (packetHeader*)dataBuffer; - if (nbBytes == -1) { - if (errno == EAGAIN) goto END_PACKET; - perror("Packet file"); - return -1; - } else if (nbBytes == 0) { - if (ops->rewind(args) == -1) { - goto END_PACKET; - } - continue; - } else if (nbBytes < 3) { - etiLog.log(error, - "Error while reading file for packet header; " - "read %i out of 3 bytes\n", nbBytes); - break; - } - - length = header->packetLength * 24 + 24; - if (written + length > size) { - memcpy(data->packetData, header, 3); - ops->read(args, &data->packetData[3], length - 3); - data->packetLength = length; - continue; - } - if (data->enhancedPacketData != nullptr) { - if (data->enhancedPacketLength + length > (12 * 188)) { - memcpy(data->packetData, header, 3); - ops->read(args, &data->packetData[3], length - 3); - data->packetLength = length; - continue; - } - } - nbBytes = ops->read(args, dataBuffer + 3, length - 3); - if (nbBytes == -1) { - perror("Packet file"); - return -1; - } else if (nbBytes == 0) { - etiLog.log(info, - "Packet header read, but no data!\n"); - if (ops->rewind(args) == -1) { - goto END_PACKET; - } - continue; - } else if (nbBytes < length - 3) { - etiLog.log(error, "Error while reading packet file; " - "read %i out of %i bytes\n", nbBytes, length - 3); - break; - } - if (data->enhancedPacketData != nullptr) { - indexCol = data->enhancedPacketLength / 12; - indexRow = data->enhancedPacketLength % 12; // TODO Check if always 0 - for (int j = 0; j < length; ++j) { - data->enhancedPacketData[indexRow][indexCol] = dataBuffer[j]; - if (++indexRow == 12) { - indexRow = 0; - ++indexCol; - } - } - data->enhancedPacketLength += length; - if (data->enhancedPacketLength >= (12 * 188)) { - if (data->enhancedPacketLength > (12 * 188)) { - etiLog.log(error, - "Error, too much enhanced packet data!\n"); - } - ReedSolomon encoder(204, 188); - for (int j = 0; j < 12; ++j) { - encoder.encode(data->enhancedPacketData[j], 188); - } - data->enhancedPacketWaiting = 192; - } - } - written += length; - dataBuffer += length; - } - } -END_PACKET: - if (ops->read == dabInputFifoRead) { - dabInputFifoData* fifoData = (dabInputFifoData*)args; - dabInputFifoStats* fifoStats = (dabInputFifoStats*)&fifoData->stats; - fifoStats->frameRecords[fifoStats->frameCount].curSize = written; - fifoStats->frameRecords[fifoStats->frameCount].maxSize = size; - if (++fifoStats->frameCount == NB_RECORDS) { - etiLog.log(info, "Packet subchannel usage: (%i)", - fifoStats->id); - for (int i = 0; i < fifoStats->frameCount; ++i) { - etiLog.log(info, " %i/%i", - fifoStats->frameRecords[i].curSize, - fifoStats->frameRecords[i].maxSize); - } - etiLog.log(info, "\n"); - fifoStats->frameCount = 0; - } - } - while (written < size) { - memset(dataBuffer, 0, 22); - dataBuffer[22] = 0x60; - dataBuffer[23] = 0x4b; - dataBuffer += 24; - written += 24; - } - return written; -} - - -# endif -#endif diff --git a/src/dabInputPacketFile.h b/src/dabInputPacketFile.h deleted file mode 100644 index 77f33a6..0000000 --- a/src/dabInputPacketFile.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_PACKET_FILE_H -#define DAB_INPUT_PACKET_FILE_H - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_PACKET -# ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputPacketFileOperations; - -int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, - int size); - - -# endif -#endif - - -#endif // DAB_INPUT_PACKET_FILE_H diff --git a/src/dabInputRawFifo.cpp b/src/dabInputRawFifo.cpp deleted file mode 100644 index cc6268b..0000000 --- a/src/dabInputRawFifo.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputRawFifo.h" - -#include -#include -#include -#include - -#ifndef _WIN32 -# define O_BINARY 0 -#endif - - -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_FILE - - -struct dabInputOperations dabInputRawFifoOperations = { - dabInputRawFifoInit, - dabInputRawFifoOpen, - dabInputRawFifoSetbuf, - dabInputRawFifoRead, - nullptr, - nullptr, - dabInputRawFifoReadFrame, - dabInputSetbitrate, - dabInputRawFifoClose, - dabInputRawFifoClean, - dabInputRawFifoRewind -}; - - -int dabInputRawFifoInit(void** args) -{ - dabInputRawFifoData* data = new dabInputRawFifoData; - data->file = -1; - data->buffer = nullptr; - data->bufferSize = 0; - data->bufferOffset = 0; - - *args = data; - return 0; -} - - -int dabInputRawFifoOpen(void* args, const char* filename) -{ - dabInputRawFifoData* data = (dabInputRawFifoData*)args; - data->file = open(filename, O_RDONLY | O_BINARY | O_NONBLOCK); - if (data->file == -1) { - perror(filename); - return -1; - } -#ifdef _WIN32 -#else - int flags = fcntl(data->file, F_GETFL); - if (flags == -1) { - perror(filename); - return -1; - } - if (fcntl(data->file, F_SETFL, flags & ~O_NONBLOCK) == -1) { - perror(filename); - return -1; - } -#endif - - return 0; -} - - -int dabInputRawFifoSetbuf(void* args, int size) -{ - dabInputRawFifoData* data = (dabInputRawFifoData*)args; - - if (size <= 0) { - return size; - } - - if (data->bufferSize != (size_t)size) { - if (data->buffer != nullptr) { - delete[] data->buffer; - } - data->buffer = new uint8_t[size]; - data->bufferSize = size; - data->bufferOffset = 0; - } - - return 0; -} - - -int dabInputRawFifoRead(void* args, void* buffer, int size) -{ - dabInputRawFifoData* data = (dabInputRawFifoData*)args; - - return read(data->file, buffer, size); -} - - -int dabInputRawFifoReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size) -{ - dabInputRawFifoData* data = (dabInputRawFifoData*)args; - int result; - - result = ops->read(args, data->buffer + data->bufferOffset, size - data->bufferOffset); - if (result == -1) { - etiLog.log(alert, "ERROR: Can't read fifo\n"); - perror(""); - return -1; - } - - if (result + data->bufferOffset < (size_t)size) { - data->bufferOffset += result; - - etiLog.log(info, "reach end of fifo -> rewinding\n"); - if (ops->rewind(args) == -1) { - etiLog.log(alert, "ERROR: Can't rewind fifo\n"); - return -1; - } - - result = ops->read(args, data->buffer + data->bufferOffset, size - data->bufferOffset); - if (result == -1) { - etiLog.log(alert, "ERROR: Can't read fifo\n"); - perror(""); - return -1; - } - - if (result < size) { - etiLog.log(alert, "ERROR: Not enought data in fifo\n"); - return 0; - } - } - - memcpy(buffer, data->buffer, size); - data->bufferOffset = 0; - - return size; -} - - -int dabInputRawFifoClose(void* args) -{ - dabInputRawFifoData* data = (dabInputRawFifoData*)args; - - if (data->file != -1) { - close(data->file); - data->file = -1; - } - return 0; -} - - -int dabInputRawFifoClean(void** args) -{ - dabInputRawFifoData* data = (dabInputRawFifoData*)*args; - if (data->buffer != nullptr) { - delete[] data->buffer; - } - delete data; - return 0; -} - - -int dabInputRawFifoRewind(void* args) -{ - dabInputRawFifoData* data = (dabInputRawFifoData*)args; - return lseek(data->file, 0, SEEK_SET); -} - - -# endif -#endif diff --git a/src/dabInputRawFifo.h b/src/dabInputRawFifo.h deleted file mode 100644 index 7d2a3a0..0000000 --- a/src/dabInputRawFifo.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_RAW_FIFO_H -#define DAB_INPUT_RAW_FIFO_H - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "dabInput.h" - -#include - - -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputRawFifoOperations; - -int dabInputRawFifoInit(void** args); -int dabInputRawFifoOpen(void* args, const char* filename); -int dabInputRawFifoSetbuf(void* args, int size); -int dabInputRawFifoRead(void* args, void* buffer, int size); -int dabInputRawFifoReadFrame(dabInputOperations* ops, void* args, - void* buffer, int size); -int dabInputRawFifoClose(void* args); -int dabInputRawFifoClean(void** args); -int dabInputRawFifoRewind(void* args); - - -struct dabInputRawFifoData { - int file; - uint8_t* buffer; - size_t bufferSize; - size_t bufferOffset; -}; - - -# endif -#endif - -#endif // DAB_INPUT_RAW_FIFO_H diff --git a/src/dabInputRawFile.cpp b/src/dabInputRawFile.cpp deleted file mode 100644 index be33a45..0000000 --- a/src/dabInputRawFile.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputRawFile.h" -#include "dabInputFile.h" - - -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_FILE - - -struct dabInputOperations dabInputRawFileOperations = { - dabInputFileInit, - dabInputFileOpen, - dabInputSetbuf, - dabInputFileRead, - nullptr, - nullptr, - dabInputRawFileRead, - dabInputSetbitrate, - dabInputFileClose, - dabInputFileClean, - dabInputFileRewind -}; - - -int dabInputRawFileRead(dabInputOperations* ops, void* args, void* buffer, - int size) -{ - int ret = ops->read(args, buffer, size); - if (ret == 0) { - etiLog.log(info, "reach end of raw file -> rewinding\n"); - ops->rewind(args); - ret = ops->read(args, buffer, size); - } - return ret; -} - - -# endif -#endif diff --git a/src/dabInputRawFile.h b/src/dabInputRawFile.h deleted file mode 100644 index 9a4a607..0000000 --- a/src/dabInputRawFile.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_RAW_FILE_H -#define DAB_INPUT_RAW_FILE_H - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputRawFileOperations; - -int dabInputRawFileRead(dabInputOperations* ops, void* args, void* buffer, - int size); - - -# endif -#endif - -#endif // DAB_INPUT_RAW_FILE_H diff --git a/src/dabInputUdp.cpp b/src/dabInputUdp.cpp deleted file mode 100644 index 0765599..0000000 --- a/src/dabInputUdp.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#include "dabInputUdp.h" - -#include -#include - - -#ifdef __MINGW32__ -# define bzero(s, n) memset(s, 0, n) -#endif - -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_UDP - - -struct dabInputOperations dabInputUdpOperations = { - dabInputUdpInit, - dabInputUdpOpen, - dabInputSetbuf, - NULL, - NULL, - NULL, - dabInputUdpRead, - dabInputSetbitrate, - dabInputUdpClose, - dabInputUdpClean, - NULL -}; - - -int dabInputUdpInit(void** args) -{ - dabInputUdpData* input = new dabInputUdpData; - memset(&input->stats, 0, sizeof(input->stats)); - input->stats.id = dabInputFifoData::nb++; - input->socket = new UdpSocket(); - input->packet = new UdpPacket(2048); - *args = input; - - UdpSocket::init(); - return 0; -} - - -int dabInputUdpOpen(void* args, const char* inputName) -{ - int returnCode = 0; - char* address; - char* ptr; - long port; - dabInputUdpData* input = (dabInputUdpData*)args; - - // Skip the udp:// part if it is present - if (strncmp(inputName, "udp://", 6) == 0) { - address = strdup(inputName + 6); - } - else { - address = strdup(inputName); - } - - ptr = strchr(address, ':'); - if (ptr == NULL) { - etiLog.log(error, - "\"%s\" is an invalid format for udp address: " - "should be [udp://][address]:port - > aborting\n", address); - returnCode = -1; - goto udpopen_ptr_null_out; - } - *(ptr++) = 0; - port = strtol(ptr, (char **)NULL, 10); - if ((port == LONG_MIN) || (port == LONG_MAX)) { - etiLog.log(error, - "can't convert port number in udp address %s\n", - address); - returnCode = -1; - } - if (port == 0) { - etiLog.log(error, "can't use port number 0 in udp address\n"); - returnCode = -1; - } - if (input->socket->create(port) == -1) { - etiLog.log(error, "can't set port %i on Udp input (%s: %s)\n", - port, inetErrDesc, inetErrMsg); - returnCode = -1; - } - - if (*address != 0) { - if (input->socket->joinGroup(address) == -1) { - etiLog.log(error, - "can't join multicast group %s (%s: %s)\n", - address, inetErrDesc, inetErrMsg); - returnCode = -1; - } - } - - if (input->socket->setBlocking(false) == -1) { - etiLog.log(error, "can't set Udp input socket in blocking mode " - "(%s: %s)\n", inetErrDesc, inetErrMsg); - returnCode = -1; - } - -udpopen_ptr_null_out: - free(address); - etiLog.log(debug, "check return code of create\n"); - return returnCode; -} - - -int dabInputUdpRead(dabInputOperations* ops, void* args, void* buffer, int size) -{ - int nbBytes = 0; - uint8_t* data = reinterpret_cast(buffer); - - dabInputUdpData* input = (dabInputUdpData*)args; - dabInputFifoStats* stats = (dabInputFifoStats*)&input->stats; - - input->stats.frameRecords[input->stats.frameCount].curSize = 0; - input->stats.frameRecords[input->stats.frameCount].maxSize = size; - - if (input->packet->getLength() == 0) { - input->socket->receive(*input->packet); - } - - while (nbBytes < size) { - unsigned freeSize = size - nbBytes; - if (input->packet->getLength() > freeSize) { - // Not enought place in output - memcpy(&data[nbBytes], input->packet->getData(), freeSize); - nbBytes = size; - input->packet->setOffset(input->packet->getOffset() + freeSize); - } else { - unsigned length = input->packet->getLength(); - memcpy(&data[nbBytes], input->packet->getData(), length); - nbBytes += length; - input->packet->setOffset(0); - input->socket->receive(*input->packet); - if (input->packet->getLength() == 0) { - break; - } - } - } - input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes; - bzero(&data[nbBytes], size - nbBytes); - - input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes; - if (++stats->frameCount == NB_RECORDS) { - etiLog.log(info, "Data subchannel usage: (%i)", - stats->id); - for (int i = 0; i < stats->frameCount; ++i) { - etiLog.log(info, " %i/%i", - stats->frameRecords[i].curSize, - stats->frameRecords[i].maxSize); - } - etiLog.log(info, "\n"); - stats->frameCount = 0; - } - - return size; -} - - -int dabInputUdpClose(void* args) -{ - return 0; -} - - -int dabInputUdpClean(void** args) -{ - dabInputUdpData* input = (dabInputUdpData*)(*args); - delete input->socket; - delete input->packet; - delete input; - return 0; -} - - -# endif -#endif diff --git a/src/dabInputUdp.h b/src/dabInputUdp.h deleted file mode 100644 index ac9ddb0..0000000 --- a/src/dabInputUdp.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications - Research Center Canada) - */ -/* - This file is part of ODR-DabMux. - - ODR-DabMux is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - ODR-DabMux is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with ODR-DabMux. If not, see . - */ - -#ifndef DAB_INPUT_UDP_H -#define DAB_INPUT_UDP_H - - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include "dabInput.h" -#include "dabInputFifo.h" -#include "UdpSocket.h" - - -#ifdef HAVE_FORMAT_RAW -# ifdef HAVE_INPUT_UDP - - -extern struct dabInputOperations dabInputUdpOperations; - - -struct dabInputUdpData { - UdpSocket* socket; - UdpPacket* packet; - dabInputFifoStats stats; -}; - - -int dabInputUdpInit(void** args); -int dabInputUdpOpen(void* args, const char* inputName); -int dabInputUdpRead(dabInputOperations* ops, void* args, void* buffer, int size); -int dabInputUdpClose(void* args); -int dabInputUdpClean(void** args); - - -# endif -#endif - - -#endif // DAB_INPUT_UDP_H -- cgit v1.2.3