aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2016-11-12 16:30:30 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2016-11-12 16:30:30 +0100
commit96b4dc4efca1b164f79a7f7394449866f034ac31 (patch)
tree101b796f40fee444c8193ccc3e13cf5644c83d5f
parent5132756f09c7a0dafe4644db92718ee3d1a58d6c (diff)
parentfedab89cd4625617b3e481f1f59ba0fc97b7305b (diff)
downloaddabmux-96b4dc4efca1b164f79a7f7394449866f034ac31.tar.gz
dabmux-96b4dc4efca1b164f79a7f7394449866f034ac31.tar.bz2
dabmux-96b4dc4efca1b164f79a7f7394449866f034ac31.zip
Merge branch 'next' into servicelinking
-rw-r--r--.travis.yml15
-rw-r--r--TODO24
-rw-r--r--configure.ac103
-rw-r--r--doc/advanced.mux32
-rw-r--r--src/ConfigParser.cpp313
-rw-r--r--src/DabMux.cpp24
-rw-r--r--src/DabMux.h7
-rw-r--r--src/Makefile.am26
-rw-r--r--src/MuxElements.cpp4
-rw-r--r--src/MuxElements.h4
-rw-r--r--src/TcpSocket.cpp43
-rw-r--r--src/TcpSocket.h17
-rw-r--r--src/UdpSocket.cpp18
-rw-r--r--src/UdpSocket.h10
-rw-r--r--src/bridge.c515
-rw-r--r--src/bridge.h112
-rw-r--r--src/dabInput.h118
-rw-r--r--src/dabInputBridgeUdp.cpp129
-rw-r--r--src/dabInputBridgeUdp.h49
-rw-r--r--src/dabInputDabplusFifo.cpp186
-rw-r--r--src/dabInputDabplusFifo.h54
-rw-r--r--src/dabInputDabplusFile.cpp177
-rw-r--r--src/dabInputDabplusFile.h62
-rw-r--r--src/dabInputEnhancedFifo.cpp64
-rw-r--r--src/dabInputEnhancedFifo.h46
-rw-r--r--src/dabInputEnhancedPacketFile.cpp53
-rw-r--r--src/dabInputEnhancedPacketFile.h47
-rw-r--r--src/dabInputFifo.cpp518
-rw-r--r--src/dabInputFifo.h103
-rw-r--r--src/dabInputFile.cpp104
-rw-r--r--src/dabInputFile.h49
-rw-r--r--src/dabInputMpegFifo.cpp47
-rw-r--r--src/dabInputMpegFifo.h37
-rw-r--r--src/dabInputMpegFile.cpp201
-rw-r--r--src/dabInputMpegFile.h42
-rw-r--r--src/dabInputPacketFile.cpp263
-rw-r--r--src/dabInputPacketFile.h46
-rw-r--r--src/dabInputRawFifo.cpp193
-rw-r--r--src/dabInputRawFifo.h63
-rw-r--r--src/dabInputRawFile.cpp59
-rw-r--r--src/dabInputRawFile.h45
-rw-r--r--src/dabInputTest.cpp105
-rw-r--r--src/dabInputTest.h50
-rw-r--r--src/dabInputUdp.cpp199
-rw-r--r--src/dabOutput/dabOutput.h7
-rw-r--r--src/dabOutput/dabOutputTcp.cpp36
-rw-r--r--src/input/File.cpp443
-rw-r--r--src/input/File.h91
-rw-r--r--src/input/Prbs.cpp (renamed from src/dabInputPrbs.cpp)59
-rw-r--r--src/input/Prbs.h (renamed from src/dabInputPrbs.h)16
-rw-r--r--src/input/Udp.cpp134
-rw-r--r--src/input/Udp.h (renamed from src/dabInputUdp.h)51
-rw-r--r--src/input/Zmq.cpp (renamed from src/dabInputZmq.cpp)53
-rw-r--r--src/input/Zmq.h (renamed from src/dabInputZmq.h)50
-rw-r--r--src/input/inputs.h (renamed from src/dabInput.cpp)47
-rw-r--r--src/mpeg.c26
-rw-r--r--src/mpeg.h7
-rw-r--r--src/prbs.cpp61
-rw-r--r--src/prbs.h24
-rw-r--r--src/utils.cpp52
-rw-r--r--src/utils.h8
-rw-r--r--src/zmqinput-keygen.c1
62 files changed, 1131 insertions, 4411 deletions
diff --git a/.travis.yml b/.travis.yml
index ecd00c1..b21773f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,20 +16,17 @@ addons: &addons
- gcc-5
- g++-5
+env:
+ - CONF=--disable-output-edi
+ - CONF=
+ - CONF=--enable-output-raw
+
compiler:
- gcc
script:
- |
./bootstrap.sh
- CC=gcc-5 CXX=g++-5 ./configure --disable-output-edi
- make
- - |
- ./bootstrap.sh
- CC=gcc-5 CXX=g++-5 ./configure
- make
- - |
- ./bootstrap.sh
- CC=gcc-5 CXX=g++-5 ./configure --enable-input-prbs --enable-input-test --enable-input-udp --enable-output-raw
+ CC=gcc-5 CXX=g++-5 ./configure $CONF
make
diff --git a/TODO b/TODO
index 3bf746f..50fc9b8 100644
--- a/TODO
+++ b/TODO
@@ -15,6 +15,7 @@ ODR-DabMod to add EDI input there too.
Initial work started in http://git.mpb.li/git/odr-edilib/
+
Explicit Service Linking
------------------------
At the moment there is no support to signal explicit service linking.
@@ -36,19 +37,23 @@ Clarify usage of PTy
We currently transmit dynamic PTy in FIG0/17 since it can be changed in
through the remote control. Some receivers might not display the dynamic
PTy, but only the static PTy. Clarify if we need to add both PTy variants
-to the configuration and the code.o
+to the configuration and the code.
-Refactor inputs
----------------
-The input code is written in very C-like OOP, with structures of function
-pointers that do dynamic dispatch. Refactoring this to proper classes and
-documenting it properly will simplify the addition of new input formats,
-facilitate runtime configurability and clarify the usages of the inputs.
+Improvements for inputs
+-----------------------
+Add statistics to UDP input, in a similar way that ZeroMQ offers statistics.
+This would mean we have to move the packet buffer from the operating system
+into our own buffer, so that we can actually get the statistics.
+
+Also see the STI-D over EDI topic above.
-Also, all inputs using UDP are now broken.
-Find out what purpose the bridge input serves.
+Fix DMB input
+-------------
+The code that does interleaving and reed-solomon encoding for DMB is not used
+anymore, and is untested. The relevant parts are src/dabInputDmb* and src/Dmb.cpp
+
Communicate Leap Seconds
------------------------
@@ -58,6 +63,7 @@ concept is totally unaware of that, this is not done. We need to know for EDI
TIST, and the ClockTAI class can get the information from the Internet, but it
is not used in FIG0/10.
+
Add support for services with different ECC than ensemble
---------------------------------------------------------
FIG 0/9 can transmit an Extended field for this information. Needs change of
diff --git a/configure.ac b/configure.ac
index 6297365..34abe67 100644
--- a/configure.ac
+++ b/configure.ac
@@ -101,33 +101,6 @@ AC_FUNC_VPRINTF
AC_CHECK_FUNCS([bzero gethostbyname gettimeofday inet_ntoa memchr memmove memset socket strchr strdup strerror strrchr strstr strtol strtoul])
# Options
-# Inputs
-# FIFO
-AC_ARG_ENABLE([input_fifo],
- [AS_HELP_STRING([--disable-input-fifo], [Disable FIFO input])],
- [], [enable_input_fifo=yes])
-AS_IF([test "x$enable_input_fifo" = "xyes"],
- [AC_DEFINE(HAVE_INPUT_FIFO, [1], [Define if FIFO input is enabled])])
-# FILE
-AC_ARG_ENABLE([input_file],
- [AS_HELP_STRING([--disable-input-file], [Disable FILE input])],
- [], [enable_input_file=yes])
-AS_IF([test "x$enable_input_file" = "xyes"],
- [AC_DEFINE(HAVE_INPUT_FILE, [1], [Define if FILE input is enabled])])
-
-# TEST
-AC_ARG_ENABLE([input_test],
- [AS_HELP_STRING([--enable-input-test], [Enable TEST input])],
- [], [enable_input_test=no])
-AS_IF([test "x$enable_input_test" = "xyes"],
- [AC_DEFINE(HAVE_INPUT_TEST, [1], [Define if TEST input is enabled])])
-# UDP
-AC_ARG_ENABLE([input_udp],
- [AS_HELP_STRING([--enable-input-udp], [Enable UDP input])],
- [], [enable_input_udp=no])
-AS_IF([test "x$enable_input_udp" = "xyes"],
- [AC_DEFINE(HAVE_INPUT_UDP, [1], [Define if UDP input is enabled])])
-
# Outputs
# FILE
AC_ARG_ENABLE([output_file],
@@ -190,51 +163,6 @@ AM_CONDITIONAL([HAVE_CURL_TEST],
AM_CONDITIONAL([HAVE_OUTPUT_RAW_TEST],
[test "x$enable_output_raw" = "xyes"])
-
-# Formats
-# RAW
-AC_ARG_ENABLE([format_raw],
- [AS_HELP_STRING([--disable-format-raw], [Disable RAW format])],
- [], [enable_format_raw=yes])
-AS_IF([test "x$enable_format_raw" = "xyes"],
- [AC_DEFINE(HAVE_FORMAT_RAW, [1], [Define if RAW format is enabled])])
-# BRIDGE
-AC_ARG_ENABLE([format_bridge],
- [AS_HELP_STRING([--enable-format-bridge], [Enable BRIDGE format])],
- [], [enable_format_bridge=no])
-AS_IF([test "x$enable_format_bridge" = "xno"],
- [AC_DEFINE(HAVE_FORMAT_BRIDGE, [1], [Define if BRIDGE format is enabled])])
-# MPEG
-AC_ARG_ENABLE([format_mpeg],
- [AS_HELP_STRING([--disable-format-mpeg], [Disable MPEG format])],
- [], [enable_format_mpeg=yes])
-AS_IF([test "x$enable_format_mpeg" = "xyes"],
- [AC_DEFINE(HAVE_FORMAT_MPEG, [1], [Define if MPEG format is enabled])])
-# PACKET
-AC_ARG_ENABLE([format_packet],
- [AS_HELP_STRING([--disable-format-packet], [Disable PACKET format])],
- [], [enable_format_packet=yes])
-AS_IF([test "x$enable_format_packet" = "xyes"],
- [AC_DEFINE(HAVE_FORMAT_PACKET, [1], [Define if PACKET format is enabled])])
-# DABPLUS
-AC_ARG_ENABLE([format_dabplus],
- [AS_HELP_STRING([--disable-format-dabplus], [Disable DABPLUS format])],
- [], [enable_format_dabplus=yes])
-AS_IF([test "x$enable_format_dabplus" = "xyes"],
- [AC_DEFINE(HAVE_FORMAT_DABPLUS, [1], [Define if DABPLUS format is enabled])])
-# DMB
-AC_ARG_ENABLE([format_dmb],
- [AS_HELP_STRING([--disable-format-dmb], [Disable DMB format])],
- [], [enable_format_dmb=yes])
-AS_IF([test "x$enable_format_dmb" = "xyes"],
- [AC_DEFINE(HAVE_FORMAT_DMB, [1], [Define if DMB format is enabled])])
-# EPM
-AC_ARG_ENABLE([format_epm],
- [AS_HELP_STRING([--disable-format-epm], [Disable EPM format])],
- [], [enable_format_epm=yes])
-AS_IF([test "x$enable_format_epm" = "xyes"],
- [AC_DEFINE(HAVE_FORMAT_EPM, [1], [Define if EPM format is enabled])])
-
AM_CONDITIONAL([IS_GIT_REPO], [test -d '.git'])
AC_CONFIG_FILES([Makefile
@@ -247,34 +175,11 @@ AC_OUTPUT
echo
echo "***********************************************"
echo
-echo ZeroMQ input, output and management server enabled.
+echo "ZeroMQ management server enabled."
echo
-echo "Inputs:"
-enabled=""
-disabled=""
-for output in prbs test udp fifo file
-do
- eval var=\$enable_input_$output
- AS_IF([test "x$var" = "xyes"],
- [enabled="$enabled $output"],
- [disabled="$disabled $output"])
-done
-echo " Enabled: $enabled"
-echo " Disabled: $disabled"
-
+echo "Inputs: prbs udp zmq fifo file"
echo
-echo "Formats:"
-enabled=""
-disabled=""
-for format in raw bridge mpeg packet dabplus dmb epm
-do
- eval var=\$enable_format_$format
- AS_IF([test "x$var" = "xyes"],
- [enabled="$enabled $format"],
- [disabled="$disabled $format"])
-done
-echo " Enabled: $enabled"
-echo " Disabled: $disabled"
+echo "Formats: raw mpeg packet dabplus dmb epm"
echo
echo "Outputs:"
@@ -287,7 +192,7 @@ do
[enabled="$enabled $output"],
[disabled="$disabled $output"])
done
-echo " Enabled: $enabled"
+echo " Enabled: $enabled zmq"
echo " Disabled: $disabled"
echo
diff --git a/doc/advanced.mux b/doc/advanced.mux
index 8d460d2..41a3446 100644
--- a/doc/advanced.mux
+++ b/doc/advanced.mux
@@ -130,8 +130,17 @@ services {
}
; The subchannels are defined in the corresponding section.
-; supported types are : audio, bridge, data, enhancedpacket,
-; dabplus, dmb, packet, test
+; supported types are : audio, data, enhancedpacket,
+; dabplus, packet
+;
+; Type 'packet' expects to receive data in the format described
+; in EN 300 401 Clause 3.5.2.
+;
+; 'enhancedpacket' mode will calculate FEC for MSC packet mode
+; as described in EN 300 401 Clause 5.3.5.
+;
+; 'data' will read from the source and write it unmodified into
+; the MSC.
subchannels {
sub-fu {
type audio
@@ -235,6 +244,25 @@ subchannels {
zmq-buffer 40
zmq-prebuffering 20
}
+
+ ; 'prbs' will generate a pseudorandom bit sequence according to
+ ; ETS 300 799 Clause G.2.1. This is useful for testing purposes and
+ ; measurement of bit error rate.
+ sub-prbs {
+ type data
+
+ ; Use the default PRBS polynomial.
+ inputfile "prbs://"
+
+ ; To use another polynomial, set it in the url as hexadecimal
+ ; The default polynomial is G(x) = x^20 + x^17 + 1, represented as
+ ; (1 << 20) + (1 << 17) + (1 << 0) = 0x120001
+ ;inputuri "prbs://:0x120001
+
+ bitrate 16
+ id 5
+ protection 3
+ }
}
; For now, each component links one service to one subchannel
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp
index fa12521..1b6093e 100644
--- a/src/ConfigParser.cpp
+++ b/src/ConfigParser.cpp
@@ -48,29 +48,16 @@
#include <map>
#include <cstring>
#include "dabOutput/dabOutput.h"
-#include "dabInput.h"
+#include "input/inputs.h"
#include "utils.h"
-#include "dabInputFile.h"
-#include "dabInputFifo.h"
-#include "dabInputMpegFile.h"
-#include "dabInputMpegFifo.h"
-#include "dabInputDabplusFile.h"
-#include "dabInputDabplusFifo.h"
-#include "dabInputPacketFile.h"
-#include "dabInputEnhancedPacketFile.h"
-#include "dabInputEnhancedFifo.h"
-#include "dabInputUdp.h"
-#include "dabInputBridgeUdp.h"
-#include "dabInputTest.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"
+#include "input/File.h"
+#include "input/Udp.h"
+
#ifdef _WIN32
# pragma warning ( disable : 4103 )
@@ -112,24 +99,6 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,
std::shared_ptr<dabEnsemble> ensemble,
const string& subchanuid);
-/* a helper class to parse hexadecimal ids */
-static int hexparse(std::string input)
-{
- int value;
- if (input.find("0x") == 0) {
- value = strtoll(input.c_str() + 2, nullptr, 16);
- }
- else {
- value = strtoll(input.c_str(), nullptr, 10);
- }
-
- if (errno == ERANGE) {
- throw runtime_error("hex conversion: value out of range");
- }
-
- return value;
-}
-
static uint16_t get_announcement_flag_from_ptree(
boost::property_tree::ptree& pt
)
@@ -490,7 +459,7 @@ void parse_ptree(
catch (runtime_error &e) {
etiLog.log(error,
"%s\n", e.what());
- throw e;
+ throw;
}
@@ -649,13 +618,13 @@ void parse_ptree(
parse_linkage(pt, ensemble);
}
-static dab_input_zmq_config_t setup_zmq_input(
+static Inputs::dab_input_zmq_config_t setup_zmq_input(
const boost::property_tree::ptree &pt,
const std::string& subchanuid)
{
using boost::property_tree::ptree_error;
- dab_input_zmq_config_t zmqconfig;
+ Inputs::dab_input_zmq_config_t zmqconfig;
try {
zmqconfig.buffer_size = pt.get<int>("zmq-buffer");
@@ -702,20 +671,19 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,
throw runtime_error(ss.str());
}
- string inputUri = "";
- // fail if no inputUri given unless type is test
- if (type != "test") {
- inputUri = pt.get<string>("inputuri", "");
+ /* Both inputfile and inputuri are supported, and are equivalent.
+ * inputuri has precedence
+ */
+ string inputUri = pt.get<string>("inputuri", "");
- if (inputUri == "") {
- try {
- inputUri = pt.get<string>("inputfile");
- }
- catch (ptree_error &e) {
- stringstream ss;
- ss << "Subchannel with uid " << subchanuid << " has no inputUri defined!";
- throw runtime_error(ss.str());
- }
+ if (inputUri == "") {
+ try {
+ inputUri = pt.get<string>("inputfile");
+ }
+ catch (ptree_error &e) {
+ stringstream ss;
+ ss << "Subchannel with uid " << subchanuid << " has no inputUri defined!";
+ throw runtime_error(ss.str());
}
}
@@ -730,80 +698,44 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,
subchan->inputUri = inputUri;
- /* The input is of the old_style type,
- * with the struct of function pointers,
- * and needs to be a DabInputCompatible
- */
- bool input_is_old_style = true;
- dabInputOperations operations;
dabProtection* protection = &subchan->protection;
+ const bool nonblock = pt.get("nonblock", false);
+ if (nonblock) {
+ etiLog.level(warn) << "The nonblock option is not supported";
+ }
- if (0) {
-#if defined(HAVE_FORMAT_MPEG)
- } else if (type == "audio") {
+ if (type == "dabplus" or type == "audio") {
subchan->type = subchannel_type_t::Audio;
subchan->bitrate = 0;
- if (0) {
-#if defined(HAVE_INPUT_FILE)
- } else if (proto == "file") {
- operations = dabInputMpegFileOperations;
-#endif // defined(HAVE_INPUT_FILE)
-#if defined(HAVE_INPUT_ZEROMQ)
- }
- else if (proto == "tcp" ||
- proto == "epgm" ||
- proto == "ipc") {
- input_is_old_style = false;
-
- auto zmqconfig = setup_zmq_input(pt, subchanuid);
-
- DabInputZmqMPEG* inzmq =
- new DabInputZmqMPEG(subchanuid, zmqconfig);
- rcs.enrol(inzmq);
- subchan->input = inzmq;
-
- if (proto == "epgm") {
- etiLog.level(warn) << "Using untested epgm:// zeromq input";
+ if (proto == "file") {
+ if (type == "audio") {
+ subchan->input = make_shared<Inputs::MPEGFile>();
}
- else if (proto == "ipc") {
- etiLog.level(warn) << "Using untested ipc:// zeromq input";
+ else if (type == "dabplus") {
+ subchan->input = make_shared<Inputs::RawFile>();
+ }
+ else {
+ throw logic_error("Incomplete handling of file input");
}
-
-#endif // defined(HAVE_INPUT_ZEROMQ)
- } else {
- stringstream ss;
- ss << "Subchannel with uid " << subchanuid <<
- ": Invalid protocol for MPEG input (" <<
- proto << ")" << endl;
- throw runtime_error(ss.str());
- }
-#endif // defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG)
-#if defined(HAVE_FORMAT_DABPLUS)
- } else if (type == "dabplus") {
- subchan->type = subchannel_type_t::Audio;
- subchan->bitrate = 32;
-
- if (0) {
-#if defined(HAVE_INPUT_FILE)
- } else if (proto == "file") {
- operations = dabInputDabplusFileOperations;
-#endif // defined(HAVE_INPUT_FILE)
-#if defined(HAVE_INPUT_ZEROMQ)
}
else if (proto == "tcp" ||
proto == "epgm" ||
proto == "ipc") {
- input_is_old_style = false;
auto zmqconfig = setup_zmq_input(pt, subchanuid);
- DabInputZmqAAC* inzmq =
- new DabInputZmqAAC(subchanuid, zmqconfig);
-
- rcs.enrol(inzmq);
- subchan->input = inzmq;
+ if (type == "audio") {
+ auto inzmq = make_shared<Inputs::ZmqMPEG>(subchanuid, zmqconfig);
+ rcs.enrol(inzmq.get());
+ subchan->input = inzmq;
+ }
+ else if (type == "dabplus") {
+ auto inzmq = make_shared<Inputs::ZmqAAC>(subchanuid, zmqconfig);
+ rcs.enrol(inzmq.get());
+ subchan->input = inzmq;
+ }
if (proto == "epgm") {
etiLog.level(warn) << "Using untested epgm:// zeromq input";
@@ -811,44 +743,25 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,
else if (proto == "ipc") {
etiLog.level(warn) << "Using untested ipc:// zeromq input";
}
-#endif // defined(HAVE_INPUT_ZEROMQ)
- } else {
+ }
+ else {
stringstream ss;
ss << "Subchannel with uid " << subchanuid <<
- ": Invalid protocol for DAB+ input (" <<
+ ": Invalid protocol for " << type << " input (" <<
proto << ")" << endl;
throw runtime_error(ss.str());
}
-#endif // defined(HAVE_FORMAT_DABPLUS)
- } else if (type == "bridge") {
- // TODO default proto should be udp://
- if (0) {
-#if defined(HAVE_FORMAT_BRIDGE)
-#if defined(HAVE_INPUT_UDP)
- } else if (proto == "udp") {
- operations = dabInputBridgeUdpOperations;
-#endif // defined(HAVE_INPUT_UDP)
-#endif // defined(HAVE_FORMAT_BRIDGE)
- }
- } else if (type == "data" and proto == "prbs") {
- input_is_old_style = false;
-
- subchan->input = new DabInputPrbs();
+ }
+ else if (type == "data" and proto == "prbs") {
+ subchan->input = make_shared<Inputs::Prbs>();
subchan->type = subchannel_type_t::DataDmb;
subchan->bitrate = DEFAULT_DATA_BITRATE;
- } else if (type == "data") {
- // TODO default proto should be udp://
- if (0) {
-#if defined(HAVE_INPUT_UDP)
- } else if (proto == "udp") {
- operations = dabInputUdpOperations;
-#endif
-#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_RAW)
- } else if (proto == "file") {
- operations = dabInputRawFileOperations;
-#endif
- } else if (proto == "fifo") {
- operations = dabInputRawFifoOperations;
+ }
+ else if (type == "data" or type == "dmb") {
+ if (proto == "udp") {
+ subchan->input = make_shared<Inputs::Udp>();
+ } else if (proto == "file" or proto == "fifo") {
+ subchan->input = make_shared<Inputs::RawFile>();
} else {
stringstream ss;
ss << "Subchannel with uid " << subchanuid <<
@@ -859,52 +772,23 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,
subchan->type = subchannel_type_t::DataDmb;
subchan->bitrate = DEFAULT_DATA_BITRATE;
-#if defined(HAVE_INPUT_TEST) && defined(HAVE_FORMAT_RAW)
- } else if (type == "test") {
- subchan->type = subchannel_type_t::DataDmb;
- subchan->bitrate = DEFAULT_DATA_BITRATE;
- operations = dabInputTestOperations;
-#endif // defined(HAVE_INPUT_TEST)) && defined(HAVE_FORMAT_RAW)
-#ifdef HAVE_FORMAT_PACKET
- } else if (type == "packet") {
- subchan->type = subchannel_type_t::Packet;
- subchan->bitrate = DEFAULT_PACKET_BITRATE;
-#ifdef HAVE_INPUT_FILE
- operations = dabInputPacketFileOperations;
-#elif defined(HAVE_INPUT_FIFO)
- operations = dabInputFifoOperations;
-#else
-# pragma error("Must define at least one packet input")
-#endif // defined(HAVE_INPUT_FILE)
-#ifdef HAVE_FORMAT_EPM
- } else if (type == "enhancedpacket") {
+
+ if (type == "dmb") {
+ /* The old dmb input took care of interleaving and Reed-Solomon encoding. This
+ * code is unported.
+ * See dabInputDmbFile.cpp
+ */
+ etiLog.level(warn) << "uid " << subchanuid << " of type Dmb uses RAW input";
+ }
+ }
+ else if (type == "packet" or type == "enhancedpacket") {
subchan->type = subchannel_type_t::Packet;
subchan->bitrate = DEFAULT_PACKET_BITRATE;
- operations = dabInputEnhancedPacketFileOperations;
-#endif // defined(HAVE_FORMAT_EPM)
-#endif // defined(HAVE_FORMAT_PACKET)
-#ifdef HAVE_FORMAT_DMB
- } else if (type == "dmb") {
- // TODO default proto should be UDP
- if (0) {
-#if defined(HAVE_INPUT_UDP)
- } else if (proto == "udp") {
- operations = dabInputDmbUdpOperations;
-#endif
- } else if (proto == "file") {
- operations = dabInputDmbFileOperations;
- } else {
- stringstream ss;
- ss << "Subchannel with uid " << subchanuid <<
- ": Invalid protocol for DMB input (" <<
- proto << ")" << endl;
- throw runtime_error(ss.str());
- }
- subchan->type = subchannel_type_t::DataDmb;
- subchan->bitrate = DEFAULT_DATA_BITRATE;
-#endif
- } else {
+ bool enhanced = (type == "enhancedpacket");
+ subchan->input = make_shared<Inputs::PacketFile>(enhanced);
+ }
+ else {
stringstream ss;
ss << "Subchannel with uid " << subchanuid << " has unknown type!";
throw runtime_error(ss.str());
@@ -915,7 +799,8 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,
protection->form = UEP;
protection->level = 2;
protection->uep.tableIndex = 0;
- } else {
+ }
+ else {
protection->level = 2;
protection->form = EEP;
protection->eep.profile = EEP_A;
@@ -937,55 +822,7 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,
throw runtime_error(ss.str());
}
-#if defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE)
- /* Get nonblock */
- bool nonblock = pt.get("nonblock", false);
- if (nonblock) {
- switch (subchan->type) {
-#ifdef HAVE_FORMAT_PACKET
- case subchannel_type_t::Packet:
- if (operations == dabInputPacketFileOperations) {
- operations = dabInputFifoOperations;
-#ifdef HAVE_FORMAT_EPM
- } else if (operations == dabInputEnhancedPacketFileOperations) {
- operations = dabInputEnhancedFifoOperations;
-#endif // defined(HAVE_FORMAT_EPM)
- } else {
- stringstream ss;
- ss << "Error, wrong packet operations for subchannel " <<
- subchanuid;
- throw runtime_error(ss.str());
- }
- break;
-#endif // defined(HAVE_FORMAT_PACKET)
-#ifdef HAVE_FORMAT_MPEG
- case subchannel_type_t::Audio:
- if (operations == dabInputMpegFileOperations) {
- operations = dabInputMpegFifoOperations;
- } else if (operations == dabInputDabplusFileOperations) {
- operations = dabInputDabplusFifoOperations;
- } else {
- stringstream ss;
- ss << "Error, wrong audio operations for subchannel " <<
- subchanuid;
- throw runtime_error(ss.str());
- }
- break;
-#endif // defined(HAVE_FORMAT_MPEG)
- case subchannel_type_t::DataDmb:
- case subchannel_type_t::Fidc:
- default:
- stringstream ss;
- ss << "Subchannel with uid " << subchanuid <<
- " non-blocking I/O only available for audio or packet services!";
- throw runtime_error(ss.str());
- }
-#endif // defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE)
- }
-
-
/* Get id */
-
try {
subchan->id = hexparse(pt.get<std::string>("id"));
}
@@ -1045,11 +882,5 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,
": protection level undefined!";
throw runtime_error(ss.str());
}
-
- /* Create object */
- if (input_is_old_style) {
- subchan->input = new DabInputCompatible(operations);
- }
- // else { it's already been created! }
}
diff --git a/src/DabMux.cpp b/src/DabMux.cpp
index 2af58c5..04d1980 100644
--- a/src/DabMux.cpp
+++ b/src/DabMux.cpp
@@ -94,24 +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 "dabInputBridgeUdp.h"
-#include "dabInputTest.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"
@@ -411,7 +395,7 @@ int main(int argc, char *argv[])
if (outputs.size() == 0) {
- etiLog.log(emerg, "no output defined");
+ etiLog.log(alert, "no output defined");
throw MuxInitException();
}
@@ -491,7 +475,7 @@ int main(int argc, char *argv[])
outputs.clear();
if (returnCode != 0) {
- etiLog.log(emerg, "...aborting\n");
+ etiLog.log(alert, "...aborting\n");
} else {
etiLog.log(debug, "...done\n");
}
diff --git a/src/DabMux.h b/src/DabMux.h
index 5dda759..80b4881 100644
--- a/src/DabMux.h
+++ b/src/DabMux.h
@@ -25,8 +25,7 @@
You should have received a copy of the GNU General Public License
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _DABMUX_H
-#define _DABMUX_H
+#pragma once
#include <stdint.h>
#include <string>
@@ -34,7 +33,7 @@
#include "DabMultiplexer.h"
#include "RemoteControl.h"
#include "dabOutput/dabOutput.h"
-#include "dabInput.h"
+#include "input/inputs.h"
#include "Eti.h"
#include "MuxElements.h"
@@ -44,5 +43,3 @@
# include <sys/time.h>
#endif
-#endif
-
diff --git a/src/Makefile.am b/src/Makefile.am
index 1d33231..de2aa37 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -47,25 +47,11 @@ odr_dabmux_LDADD =$(ZMQ_LIBS) $(CURL_LIBS) \
odr_dabmux_SOURCES =DabMux.cpp DabMux.h \
DabMultiplexer.cpp DabMultiplexer.h \
- dabInput.h dabInput.cpp \
- dabInputBridgeUdp.h dabInputBridgeUdp.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 \
- dabInputTest.h dabInputTest.cpp \
- dabInputUdp.h dabInputUdp.cpp \
- dabInputZmq.h dabInputZmq.cpp \
+ input/inputs.h \
+ input/Prbs.cpp input/Prbs.h \
+ input/Zmq.cpp input/Zmq.h \
+ input/File.cpp input/File.h \
+ input/Udp.cpp input/Udp.h \
dabOutput/dabOutput.h \
dabOutput/dabOutputFile.cpp \
dabOutput/dabOutputFifo.cpp \
@@ -80,7 +66,6 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \
dabOutput/edi/PFT.cpp dabOutput/edi/PFT.h \
ClockTAI.h ClockTAI.cpp \
ConfigParser.cpp ConfigParser.h \
- Dmb.h Dmb.cpp \
Eti.h Eti.cpp \
InetAddress.h InetAddress.cpp \
Interleaver.h Interleaver.cpp \
@@ -93,7 +78,6 @@ odr_dabmux_SOURCES =DabMux.cpp DabMux.h \
TcpSocket.h TcpSocket.cpp \
UdpSocket.h UdpSocket.cpp \
ThreadsafeQueue.h \
- bridge.h bridge.c \
crc.h crc.c \
fig/FIG.h fig/FIG.cpp \
fig/FIG0.h fig/FIG0structs.h \
diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp
index 2215bda..7f92652 100644
--- a/src/MuxElements.cpp
+++ b/src/MuxElements.cpp
@@ -385,7 +385,7 @@ void DabComponent::set_parameter(const string& parameter,
throw ParameterError(ss.str());
default:
ss << m_name << " short label definition: program error !";
- etiLog.level(emerg) << ss.str();
+ etiLog.level(alert) << ss.str();
throw ParameterError(ss.str());
}
}
@@ -500,7 +500,7 @@ void DabService::set_parameter(const string& parameter,
throw ParameterError(ss.str());
default:
ss << m_name << " short label definition: program error !";
- etiLog.level(emerg) << ss.str();
+ etiLog.level(alert) << ss.str();
throw ParameterError(ss.str());
}
}
diff --git a/src/MuxElements.h b/src/MuxElements.h
index 79100a9..7ff23a6 100644
--- a/src/MuxElements.h
+++ b/src/MuxElements.h
@@ -40,7 +40,7 @@
#include <boost/optional.hpp>
#include <stdint.h>
#include "dabOutput/dabOutput.h"
-#include "dabInput.h"
+#include "input/inputs.h"
#include "RemoteControl.h"
#include "Eti.h"
@@ -297,7 +297,7 @@ public:
std::string uid;
std::string inputUri;
- DabInputBase* input;
+ std::shared_ptr<Inputs::InputBase> input;
unsigned char id;
subchannel_type_t type;
uint16_t startAddress;
diff --git a/src/TcpSocket.cpp b/src/TcpSocket.cpp
index 433e5c1..b9824fa 100644
--- a/src/TcpSocket.cpp
+++ b/src/TcpSocket.cpp
@@ -39,31 +39,30 @@ using namespace std;
TcpSocket::TcpSocket() :
m_sock(INVALID_SOCKET)
{
- if ((m_sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
- throw std::runtime_error("Can't create socket");
- }
}
TcpSocket::TcpSocket(int port, const string& name) :
m_sock(INVALID_SOCKET)
{
- if ((m_sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
- throw std::runtime_error("Can't create socket");
- }
+ if (port) {
+ if ((m_sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
+ throw std::runtime_error("Can't create socket");
+ }
- reuseopt_t reuse = 1;
- if (setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))
- == SOCKET_ERROR) {
- throw std::runtime_error("Can't reuse address");
- }
+ reuseopt_t reuse = 1;
+ if (setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))
+ == SOCKET_ERROR) {
+ throw std::runtime_error("Can't reuse address");
+ }
- m_own_address.setAddress(name);
- m_own_address.setPort(port);
+ m_own_address.setAddress(name);
+ m_own_address.setPort(port);
- if (bind(m_sock, m_own_address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) {
- ::close(m_sock);
- m_sock = INVALID_SOCKET;
- throw std::runtime_error("Can't bind socket");
+ if (bind(m_sock, m_own_address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) {
+ ::close(m_sock);
+ m_sock = INVALID_SOCKET;
+ throw std::runtime_error("Can't bind socket");
+ }
}
}
@@ -116,6 +115,11 @@ TcpSocket::~TcpSocket()
close();
}
+bool TcpSocket::isValid()
+{
+ return m_sock != INVALID_SOCKET;
+}
+
ssize_t TcpSocket::recv(void* data, size_t size)
{
ssize_t ret = ::recv(m_sock, (char*)data, size, 0);
@@ -167,7 +171,7 @@ TcpSocket TcpSocket::accept()
}
}
-boost::optional<TcpSocket> TcpSocket::accept(int timeout_ms)
+TcpSocket TcpSocket::accept(int timeout_ms)
{
struct pollfd fds[1];
fds[0].fd = m_sock;
@@ -184,7 +188,8 @@ boost::optional<TcpSocket> TcpSocket::accept(int timeout_ms)
return accept();
}
else {
- return boost::none;
+ TcpSocket invalidsock(0, "");
+ return invalidsock;
}
}
diff --git a/src/TcpSocket.h b/src/TcpSocket.h
index 5a4a808..660515d 100644
--- a/src/TcpSocket.h
+++ b/src/TcpSocket.h
@@ -46,7 +46,7 @@
#include <iostream>
#include <string>
-#include <boost/optional.hpp>
+#include <memory>
/**
* This class represents a TCP socket.
@@ -67,8 +67,12 @@ class TcpSocket
~TcpSocket();
TcpSocket(TcpSocket&& other);
TcpSocket& operator=(TcpSocket&& other);
+ TcpSocket(const TcpSocket& other) = delete;
+ TcpSocket& operator=(const TcpSocket& other) = delete;
- int close();
+ bool isValid(void);
+
+ int close(void);
/** Send data over the TCP connection.
* @param data The buffer that will be sent.
@@ -86,7 +90,12 @@ class TcpSocket
void listen(void);
TcpSocket accept(void);
- boost::optional<TcpSocket> accept(int timeout_ms);
+
+ /* Returns either valid socket if a connection was
+ * accepted before the timeout expired, or an invalid
+ * socket otherwise.
+ */
+ TcpSocket accept(int timeout_ms);
/** Retrieve address this socket is bound to */
InetAddress getOwnAddress() const;
@@ -94,8 +103,6 @@ class TcpSocket
private:
TcpSocket(SOCKET sock, InetAddress own, InetAddress remote);
- TcpSocket(const TcpSocket& other) = delete;
- TcpSocket& operator=(const TcpSocket& other) = delete;
/// The address on which the socket is bound.
InetAddress m_own_address;
diff --git a/src/UdpSocket.cpp b/src/UdpSocket.cpp
index 020e3f5..ccdd7ed 100644
--- a/src/UdpSocket.cpp
+++ b/src/UdpSocket.cpp
@@ -37,19 +37,19 @@ using namespace std;
UdpSocket::UdpSocket() :
listenSocket(INVALID_SOCKET)
{
- init_sock(0, "");
+ reinit(0, "");
}
UdpSocket::UdpSocket(int port) :
listenSocket(INVALID_SOCKET)
{
- init_sock(port, "");
+ reinit(port, "");
}
UdpSocket::UdpSocket(int port, const std::string& name) :
listenSocket(INVALID_SOCKET)
{
- init_sock(port, name);
+ reinit(port, name);
}
@@ -67,7 +67,7 @@ int UdpSocket::setBlocking(bool block)
return 0;
}
-int UdpSocket::init_sock(int port, const std::string& name)
+int UdpSocket::reinit(int port, const std::string& name)
{
if (listenSocket != INVALID_SOCKET) {
::close(listenSocket);
@@ -98,6 +98,16 @@ int UdpSocket::init_sock(int port, const std::string& name)
return 0;
}
+int UdpSocket::close()
+{
+ if (listenSocket != INVALID_SOCKET) {
+ ::close(listenSocket);
+ }
+
+ listenSocket = INVALID_SOCKET;
+
+ return 0;
+}
UdpSocket::~UdpSocket()
{
diff --git a/src/UdpSocket.h b/src/UdpSocket.h
index 535499e..dfeaac1 100644
--- a/src/UdpSocket.h
+++ b/src/UdpSocket.h
@@ -80,6 +80,15 @@ class UdpSocket
UdpSocket(const UdpSocket& other) = delete;
const UdpSocket& operator=(const UdpSocket& other) = delete;
+ /** reinitialise socket. Close the already open socket, and
+ * create a new one
+ */
+ int reinit(int port, const std::string& name);
+
+ /** Close the socket
+ */
+ int close(void);
+
/** Send an UDP packet.
* @param packet The UDP packet to be sent. It includes the data and the
* destination address
@@ -111,7 +120,6 @@ class UdpSocket
int setBlocking(bool block);
protected:
- int init_sock(int port, const std::string& name);
/// The address on which the socket is bound.
InetAddress address;
diff --git a/src/bridge.c b/src/bridge.c
deleted file mode 100644
index d66a7b2..0000000
--- a/src/bridge.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- Copyright (C) 2003, 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 <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#ifdef _WIN32
-# include <winsock2.h>
-#else
-# include <netinet/in.h>
-#endif // _WIN32
-#include <string.h>
-#include "bridge.h"
-#include "crc.h"
-
-#include <assert.h>
-#include "PcDebug.h"
-
-#ifdef _WIN32
-# ifdef _DEBUG
- int bridgeVerbosity = 0;
-# endif
-#else
-# ifdef DEBUG
- int bridgeVerbosity = 0;
-# endif
-#endif
-
-void printStats(struct bridgeInfo* info, FILE* out)
-{
- struct bridgeStats stats = getStats(info);
- fprintf(out, "frames : %lu\n", stats.frames);
- fprintf(out, " valids : %lu\n", stats.valids);
- fprintf(out, " invalids : %lu\n", stats.invalids);
- fprintf(out, " bytes : %lu\n", stats.bytes);
- fprintf(out, " packets : %lu\n", stats.packets);
- fprintf(out, " errors : %lu\n", stats.errors);
- fprintf(out, " missings : %lu\n", stats.missings);
- fprintf(out, " dropped : %lu\n", stats.dropped);
- fprintf(out, " crc : %lu\n", stats.crc);
- fprintf(out, " overruns : %lu\n", stats.overruns);
-}
-
-
-void resetStats(struct bridgeInfo* info)
-{
- memset(&info->stats, 0, sizeof(info->stats));
-}
-
-
-struct bridgeStats getStats(struct bridgeInfo* info)
-{
- return info->stats;
-}
-
-
-void bridgeInitInfo(struct bridgeInfo* info)
-{
- memset(info, 0, sizeof(*info));
- info->transmitted = -8;
-};
-
-
-int writePacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut,
- struct bridgeInfo* info)
-{
- static struct bridgeHdr header = { 0 };
-
- PDEBUG4_VERBOSE(1, bridgeVerbosity, "writePacket\n sizeIn: %i, sizeOut: %i, "
- "offset: %i, transmitted: %i\n",
- sizeIn, sizeOut, info->offset, info->transmitted);
-
- assert(info->transmitted < sizeIn);
-
- if ((info->offset == 0) && (sizeIn > 0)) {
- ((unsigned short*)dataOut)[0] = 0xb486;
- info->offset = 2;
- }
- if (sizeIn == 0) {
- memset((unsigned char*)dataOut + info->offset, 0, sizeOut - info->offset);
- info->offset = 0;
- info->transmitted = -8;
- PDEBUG1_VERBOSE(1, bridgeVerbosity, " return %i (sizeIn == 0)\n",
- sizeOut);
- return 0;
- }
-
- while (info->offset < sizeOut) {
- switch (info->transmitted) {
- case (-8):
- ((unsigned char*)dataOut)[info->offset++] = 0xcb;
- ++info->transmitted;
- break;
- case (-7):
- ((unsigned char*)dataOut)[info->offset++] = 0x28;
- ++info->transmitted;
- break;
- case (-6):
- header.size = htons((unsigned short)sizeIn);
- header.crc = htons((unsigned short)(crc16(0xffff, &header, 4) ^ 0xffff));
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[0];
- ++info->transmitted;
- break;
- case (-5):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[1];
- ++info->transmitted;
- break;
- case (-4):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[2];
- ++info->transmitted;
- break;
- case (-3):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[3];
- ++info->transmitted;
- break;
- case (-2):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[4];
- ++info->transmitted;
- break;
- case (-1):
- ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[5];
- ++info->transmitted;
- header.seqNb = htons((unsigned short)(ntohs(header.seqNb) + 1));
- break;
- default:
- ((unsigned char*)dataOut)[info->offset++] =
- ((unsigned char*)dataIn)[info->transmitted++];
- if (info->transmitted == sizeIn) {
- PDEBUG2_VERBOSE(1, bridgeVerbosity,
- " Packet done, %i bytes at offset %i\n",
- info->transmitted, info->offset);
- PDEBUG1_VERBOSE(1, bridgeVerbosity,
- " return %i (sizeIn == transmitted)\n", info->offset);
- info->transmitted = -8;
- return info->offset;
- }
- }
- }
-
- PDEBUG1_VERBOSE(1, bridgeVerbosity, " return %i (offset >= sizeOut)\n",
- info->offset);
- info->offset = 0;
- return 0;
-}
-
-
-int getPacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut,
- struct bridgeInfo* info, char async)
-{
- unsigned char* in = (unsigned char*)dataIn;
- unsigned char* out = (unsigned char*)dataOut;
- unsigned char ch;
- unsigned short crc;
- unsigned short diff;
-
- PDEBUG3_VERBOSE(1, bridgeVerbosity,
- "getPacket\n pos\t%i\n state\t%i\n received\t%i\n",
- info->pos, info->state, info->received);
-
- if (info->pos == 0) {
- ++info->stats.frames;
- if (((unsigned short*)dataIn)[0] != 0xb486) {
- if (((unsigned short*)dataIn)[0] != 0) {
- ++info->stats.invalids;
- printf("WARNING: processing frame with invalid magic "
- "number!\n");
- } else {
- PDEBUG0_VERBOSE(1, bridgeVerbosity,
- "getPacket: not a valid frame\n");
- return 0;
- }
- } else {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "Valid frame\n");
- info->pos += 2;
- ++info->stats.valids;
- }
- info->stats.bytes += sizeIn;
- }
- while (info->pos < sizeIn) {
- ch = in[info->pos++];
- switch (info->state) {
- case 0: // sync search
- info->sync <<= 8;
- info->sync |= ch;
- if (info->sync == 0xcb28) {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "Sync found\n");
- ++info->stats.packets;
- info->received = 0;
- info->state = 1;
- }
- if (info->sync == 0) { // Padding
- info->pos = 0;
- return 0;
- }
- break;
- case 1: // header search
- ((char*)&info->header)[info->received++] = ch;
- if (info->received == sizeof(struct bridgeHdr)) {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "Header found\n");
- out = (unsigned char*)dataOut;
- info->received = 0;
- info->state = 2;
- crc = crc16(0xffff, &info->header, 4);
- crc ^= 0xffff;
- info->header.size = ntohs(info->header.size);
- info->header.seqNb = ntohs(info->header.seqNb);
- info->header.crc = ntohs(info->header.crc);
- PDEBUG4_VERBOSE(2, bridgeVerbosity,
- " size\t%i\n seq\t%i\n crc\t0x%.4x (0x%.4x)\n",
- info->header.size, info->header.seqNb,
- info->header.crc, crc);
- if (crc != info->header.crc) {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "CRC error\n");
- ++info->stats.errors;
- ++info->stats.crc;
- info->state = 0;
- if (info->pos < sizeof(struct bridgeHdr) + 2 + 2) {
- info->pos = 2;
- }
- } else {
- if (!info->initSeq) {
- info->lastSeq = info->header.seqNb;
- info->initSeq = 1;
- } else {
- if (info->header.seqNb > info->lastSeq) {
- diff = (info->header.seqNb - info->lastSeq) - 1;
- } else {
- diff = ((short)info->lastSeq -
- (short)info->header.seqNb) - 1;
- }
- info->stats.errors += diff;
- info->stats.missings += diff;
- info->lastSeq = info->header.seqNb;
- }
- }
- }
- break;
- case 2: // data
- out[info->received++] = ch;
- if (info->received == info->header.size) {
- PDEBUG0_VERBOSE(2, bridgeVerbosity, "data found\n");
- info->state = 0;
- return info->received;
- }
- if (info->received == sizeOut) {
- PDEBUG1_VERBOSE(1, bridgeVerbosity, "To much data: %i\n",
- info->received);
- ++info->stats.errors;
- ++info->stats.overruns;
- info->sync = 0;
- info->state = 0;
- return -1;
- }
- break;
- case 3: // Padding or sync
- if (ch == 0) { // Padding
- info->pos = 0;
- return 0;
- }
- if (ch != 0xcb) { // error
- info->sync = ch;
- info->state = 0;
- } else {
- info->state = 4;
- }
- break;
- case 4: // Low byte sync
- if (ch != 28) { // error
- info->sync <<= 8;
- info->sync |= ch;
- info->state = 0;
- } else {
- info->state = 2;
- }
- break;
- }
- }
- info->pos = 0;
- return 0;
-}
-
-
-void dump(void* data, int size, FILE* stream)
-{
- int i;
- fprintf(stream, "%i bytes\n", size);
- for (i = 0; i < size; ++i) {
- fprintf(stream, " 0x%.2x", ((unsigned char*)data)[i]);
- if (i % 8 == 7)
- fprintf(stream, "\n");
- }
- fprintf(stream, "\n");
-}
-
-
-#ifdef BRIDGE_TEST
-#include <stdlib.h>
-
-
-int test(const unsigned char* data)
-{
- unsigned char bridgeSize = data[0];
- unsigned char nbInput = data[1];
- unsigned char nbBridge = 1;
- struct bridgeInfo info;
-
- int i, j;
- int index = 0;
- int max = 0;
- int nbBytes;
-
- unsigned char** inputData;
- unsigned char** bridgeData;
- unsigned char* outputData;
-
- inputData = malloc(nbInput * 4);
- bridgeData = malloc(nbBridge * 4);
- for (i = 0; i < nbInput; ++i) {
- if (data[i + 2] > 0)
- inputData[i] = malloc(data[i + 2]);
- if (data[i + 2] > max) {
- max = data[i + 2];
- }
- for (j = 0; j < data[i + 2]; ++j) {
- inputData[i][j] = index++;
- }
- }
- bridgeData[0] = malloc(bridgeSize);
- memset(bridgeData[0], 0, bridgeSize);
- outputData = malloc(max);
- bridgeInitInfo(&info);
-
- // Write packets
- index = 0;
- while (1) {
- if (data[index + 2] == 0) {
- if (++index == nbInput)
- break;
- }
- while ((nbBytes = writePacket(inputData[index], data[index + 2],
- bridgeData[nbBridge - 1], bridgeSize, &info))
- != 0) {
- if (++index == nbInput) {
- break;
- }
- }
- if (index == nbInput)
- break;
- // TODO check null
- bridgeData = realloc(bridgeData, (++nbBridge) * 4);
- bridgeData[nbBridge - 1] = malloc(bridgeSize);
- memset(bridgeData[nbBridge - 1], 0, bridgeSize);
- }
-// if (nbBytes != bridgeSize) {
- writePacket(NULL, 0, bridgeData[nbBridge - 1], bridgeSize, &info);
-// }
-
- // read packets
- index = 0;
- for (i = 0; i < nbBridge; ++i) {
- while ((nbBytes = getPacket(bridgeData[i], bridgeSize, outputData, max,
- &info, 0)) != 0) {
- while (data[index + 2] == 0) {
- ++index;
- }
- if (nbBytes != data[index + 2]) {
- printf("FAILED\n");
- printf("Invalid size at bridge %i, data %i: %i != %i\n",
- i, index, nbBytes, data[index + 2]);
- for (i = 0; i < nbInput; ++i) {
- printf("Input %i: ", i);
- dump(inputData[i], data[i + 2], stdout);
- }
- for (i = 0; i < nbBridge; ++i) {
- printf("Bridge %i: ", i);
- dump(bridgeData[i], bridgeSize, stdout);
- }
- printf("Output %i: ", index);
- dump(outputData, nbBytes, stdout);
- return -1;
- }
- if (memcmp(outputData, inputData[index], data[index + 2]) != 0) {
- printf("FAILED\n");
- printf("output != input\n");
- for (i = 0; i < nbInput; ++i) {
- printf("Input %i: ", i);
- dump(inputData[i], data[i + 2], stdout);
- }
- for (i = 0; i < nbBridge; ++i) {
- printf("Bridge %i: ", i);
- dump(bridgeData[i], bridgeSize, stdout);
- }
- printf("Output %i: ", index);
- dump(outputData, nbBytes, stdout);
- }
- ++index;
- }
- }
-
- printf("SUCCESS\n");
-
- for (i = 0; i < nbInput; ++i) {
- if (data[i + 2] > 0)
- free(inputData[i]);
- }
- free(inputData);
- free(outputData);
- for (i = 0; i < nbBridge; ++i) {
- free(bridgeData[i]);
- }
- free(bridgeData);
-
- return -1;
-}
-
-
-int main(int argc, char* argv[])
-{
- int i;
- // test: bridgesize, nbinput [, input1, input2, ... ]
- const unsigned char complete[] = { 32, 1, 16 };
- const unsigned char split[] = { 32, 1, 48 };
- const unsigned char twice[] = {32, 2, 8, 4 };
- const unsigned char secondSplit[] = { 32, 2, 16, 16 };
- const unsigned char headerSplit[][4] = {
- { 32, 2, 23, 16 },
- { 32, 2, 22, 16 },
- { 32, 2, 21, 16 },
- { 32, 2, 20, 16 },
- { 32, 2, 19, 16 },
- { 32, 2, 18, 16 },
- { 32, 2, 17, 16 }
- };
- const unsigned char two[] = { 32, 3, 16, 0, 16 };
- const unsigned char doubleSplit[] = { 32, 2, 32, 32 };
- const unsigned char full[] = { 32, 2, 24, 12 };
- const unsigned char empty[] = { 32, 3, 0, 0, 5 };
-
-#ifdef _WIN32
- #ifdef _DEBUG
- bridgeVerbosity = argc - 1;
- #endif // DEBUG
-#else
- #ifdef DEBUG
- bridgeVerbosity = argc - 1;
- #endif // DEBUG
-#endif // _WIN32
-
- printf("Complete: ");
- test(complete);
- // printStats(stdout);
- fflush(stdout);
-
- printf("split: ");
- test(split);
- // printStats(stdout);
- fflush(stdout);
-
- printf("twice: ");
- test(twice);
- // printStats(stdout);
- fflush(stdout);
-
- printf("second split: ");
- test(secondSplit);
- // printStats(stdout);
- fflush(stdout);
-
- for (i = 0; i < sizeof(headerSplit) / sizeof(headerSplit[0]); ++i) {
- printf("headerSplit%i: ", i);
- test(headerSplit[i]);
- // printStats(stdout);
- fflush(stdout);
- }
-
- printf("two: ");
- test(two);
- // printStats(stdout);
- fflush(stdout);
-
- printf("doubleSplit: ");
- test(doubleSplit);
- // printStats(stdout);
- fflush(stdout);
-
- printf("full: ");
- test(full);
- // printStats(stdout);
- fflush(stdout);
-
- printf("empty: ");
- test(empty);
- // printStats(stdout);
- fflush(stdout);
-
- return 0;
-}
-
-#endif // BRIDGE_TEST
diff --git a/src/bridge.h b/src/bridge.h
deleted file mode 100644
index 0bae007..0000000
--- a/src/bridge.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- Copyright (C) 2003, 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _BRIDGE
-#define _BRIDGE
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdio.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef _WIN32
-# ifdef _DEBUG
- extern int bridgeVerbosity;
-# endif // _DEBUG
-#else
-# ifndef DEBUG
-# ifndef NDEBUG
-# define NDEBUG
-# endif
-# else
- extern int bridgeVerbosity;
-# endif // DEBUG
-#endif // _WIN32
-
-struct bridgeStats {
- unsigned long frames; // Number of frames analyzed
- unsigned long valids; // Nb of frames with a good magic number
- unsigned long invalids; // Nb of frames with a good magic number
- unsigned long bytes; // Nb of data bytes
- unsigned long packets; // Nb of packets found
- unsigned long errors;
- unsigned long missings;
- unsigned long dropped;
- unsigned long crc; // Nb of crc errors
- unsigned long overruns; // Nb of packet too big
-};
-
-
-struct bridgeHdr {
- unsigned short size;
- unsigned short seqNb;
- unsigned short crc;
-};
-
-
-struct bridgeInfo {
- // Tx
- int transmitted; // Nb bytes written
- int offset; // Offset of the next byte to write
- // Rx
- int received;
- int pos;
- int state;
- unsigned short lastSeq;
- unsigned short sync;
- char initSeq;
- // General
- struct bridgeHdr header;
- struct bridgeStats stats;
-};
-
-
-
-void dump(void* data, int size, FILE* stream);
-
-/*
- * Example of usae:
- * if (data.length == 0)
- * read(data)
- * while (writePacket() != 0)
- * read(read)
- * ...
- */
-int writePacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut, struct bridgeInfo* info);
-
-int getPacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut, struct bridgeInfo* info, char async);
-
-void bridgeInitInfo(struct bridgeInfo* info);
-struct bridgeStats getStats(struct bridgeInfo* info);
-void resetStats(struct bridgeInfo* info);
-void printStats(struct bridgeInfo* info, FILE* out);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _BRIDGE
diff --git a/src/dabInput.h b/src/dabInput.h
deleted file mode 100644
index f1b4348..0000000
--- a/src/dabInput.h
+++ /dev/null
@@ -1,118 +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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAB_INPUT_H
-#define DAB_INPUT_H
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include "Log.h"
-#include "RemoteControl.h"
-#include <string>
-
-extern Logger etiLog;
-
-// 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&);
-};
-
-/* 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:
- 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(void* buffer, int 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/dabInputBridgeUdp.cpp b/src/dabInputBridgeUdp.cpp
deleted file mode 100644
index fdf3d1f..0000000
--- a/src/dabInputBridgeUdp.cpp
+++ /dev/null
@@ -1,129 +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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputBridgeUdp.h"
-#include "dabInputUdp.h"
-#include "bridge.h"
-
-#ifdef HAVE_FORMAT_BRIDGE
-# ifdef HAVE_INPUT_UDP
-
-struct dabInputBridgeUdpData {
- dabInputUdpData* udpData;
- bridgeInfo* info;
-};
-
-
-struct dabInputOperations dabInputBridgeUdpOperations = {
- dabInputBridgeUdpInit,
- dabInputBridgeUdpOpen,
- dabInputSetbuf,
- NULL,
- NULL,
- NULL,
- dabInputBridgeUdpRead,
- dabInputSetbitrate,
- dabInputBridgeUdpClose,
- dabInputBridgeUdpClean,
- NULL
-};
-
-
-int dabInputBridgeUdpInit(void** args)
-{
- dabInputBridgeUdpData* input = new dabInputBridgeUdpData;
- dabInputUdpInit((void**)&input->udpData);
- input->info = new bridgeInfo;
- bridgeInitInfo(input->info);
- *args = input;
-
- return 0;
-}
-
-
-int dabInputBridgeUdpOpen(void* args, const char* inputName)
-{
- dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)args;
-
- return dabInputUdpOpen(input->udpData, inputName);
-}
-
-
-int dabInputBridgeUdpRead(dabInputOperations* ops, void* args, void* buffer, int size)
-{
- int nbBytes = 0;
- dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)args;
- dabInputFifoStats* stats = (dabInputFifoStats*)&input->udpData->stats;
-
- stats->frameRecords[stats->frameCount].curSize = 0;
- stats->frameRecords[stats->frameCount].maxSize = size;
-
- if (input->udpData->packet->getSize() == 0) {
- input->udpData->socket->receive(*input->udpData->packet);
- }
- while ((nbBytes = writePacket(input->udpData->packet->getData(),
- input->udpData->packet->getSize(), buffer, size,
- input->info))
- != 0) {
- stats->frameRecords[stats->frameCount].curSize = nbBytes;
- input->udpData->socket->receive(*input->udpData->packet);
- }
-
- if (input->udpData->packet->getSize() != 0) {
- stats->frameRecords[stats->frameCount].curSize = size;
- }
-
- 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 dabInputBridgeUdpClose(void* args)
-{
- dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)args;
-
- return dabInputUdpClose(input->udpData);
-}
-
-
-int dabInputBridgeUdpClean(void** args)
-{
- dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)(*args);
- dabInputUdpClean((void**)&input->udpData);
- delete input->info;
- delete input;
- return 0;
-}
-
-
-# endif // HAVE_INPUT_UDP
-#endif // HAVE_FORMAT_BRIDGE
-
diff --git a/src/dabInputBridgeUdp.h b/src/dabInputBridgeUdp.h
deleted file mode 100644
index ed00952..0000000
--- a/src/dabInputBridgeUdp.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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAB_INPUT_BRIDGE_UDP_H
-#define DAB_INPUT_BRIDGE_UDP_H
-
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include "dabInput.h"
-
-
-#ifdef HAVE_FORMAT_BRIDGE
-# ifdef HAVE_INPUT_UDP
-
-
-extern struct dabInputOperations dabInputBridgeUdpOperations;
-
-int dabInputBridgeUdpInit(void** args);
-int dabInputBridgeUdpOpen(void* args, const char* inputName);
-int dabInputBridgeUdpRead(dabInputOperations* ops, void* args, void* buffer, int size);
-int dabInputBridgeUdpClose(void* args);
-int dabInputBridgeUdpClean(void** args);
-
-
-# endif
-#endif
-
-
-#endif // DAB_INPUT_BRIDGE_UDP_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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputDabplusFifo.h"
-#include "dabInputDabplusFile.h"
-#include "dabInputFifo.h"
-#include "dabInput.h"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputDabplusFile.h"
-#include "dabInput.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-
-#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<uint8_t*>(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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAB_INPUT_DABPLUS_FILE_H
-#define DAB_INPUT_DABPLUS_FILE_H
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdint.h>
-#include <unistd.h>
-
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#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 3b12e0b..0000000
--- a/src/dabInputEnhancedPacketFile.cpp
+++ /dev/null
@@ -1,53 +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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputEnhancedPacketFile.h"
-#include "dabInputPacketFile.h"
-#include "dabInputFile.h"
-
-
-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;
-}
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 <http://www.gnu.org/licenses/>.
- */
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputFifo.h"
-#include "dabInputPacketFile.h"
-#include "dabInput.h"
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "dabInputFile.h"
-#include "Log.h"
-
-
-#ifdef _WIN32
-# include <io.h>
-# define sem_t HANDLE
-# define O_NONBLOCK 0
-#else
-# include <semaphore.h>
-# 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputFile.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#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 804ea29..0000000
--- a/src/dabInputMpegFile.cpp
+++ /dev/null
@@ -1,201 +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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputMpegFile.h"
-#include "dabInputFile.h"
-#include "mpeg.h"
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-
-#ifdef HAVE_FORMAT_MPEG
-# ifdef HAVE_INPUT_FILE
-
-
-struct dabInputOperations dabInputMpegFileOperations = {
- dabInputFileInit,
- dabInputFileOpen,
- dabInputSetbuf,
- dabInputFileRead,
- nullptr,
- nullptr,
- dabInputMpegFileRead,
- dabInputMpegSetbitrate,
- dabInputFileClose,
- dabInputFileClean,
- dabInputFileRewind
-};
-
-
-#define MPEG_FREQUENCY -2
-#define MPEG_PADDING -3
-#define MPEG_COPYRIGHT -4
-#define MPEG_ORIGINAL -5
-#define MPEG_EMPHASIS -6
-int checkDabMpegFrame(void* data) {
- mpegHeader* header = (mpegHeader*)data;
- unsigned long* headerData = (unsigned long*)data;
- if ((*headerData & 0x0f0ffcff) == 0x0004fcff) return 0;
- if ((*headerData & 0x0f0ffcff) == 0x0004f4ff) return 0;
- if (getMpegFrequency(header) != 48000) {
- if (getMpegFrequency(header) != 24000) {
- return MPEG_FREQUENCY;
- }
- }
- if (header->padding != 0) {
- return MPEG_PADDING;
- }
- if (header->copyright != 0) {
- return MPEG_COPYRIGHT;
- }
- if (header->original != 0) {
- return MPEG_ORIGINAL;
- }
- if (header->emphasis != 0) {
- return MPEG_EMPHASIS;
- }
- return -1;
-}
-
-
-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 <http://www.gnu.org/licenses/>.
- */
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputPacketFile.h"
-#include "dabInputFile.h"
-#include "dabInputFifo.h"
-#include "ReedSolomon.h"
-
-#ifdef HAVE_FORMAT_PACKET
-# ifdef HAVE_INPUT_FILE
-
-
-#include <string.h>
-#include <stdio.h>
-#include <errno.h>
-
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputRawFifo.h"
-
-#include <unistd.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAB_INPUT_RAW_FIFO_H
-#define DAB_INPUT_RAW_FIFO_H
-
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "dabInput.h"
-
-#include <stdint.h>
-
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#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 <http://www.gnu.org/licenses/>.
- */
-
-#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/dabInputTest.cpp b/src/dabInputTest.cpp
deleted file mode 100644
index fd4fc59..0000000
--- a/src/dabInputTest.cpp
+++ /dev/null
@@ -1,105 +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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputTest.h"
-
-#include <string.h>
-#ifdef _WIN32
-#else
-# include <arpa/inet.h>
-#endif
-
-
-#ifdef HAVE_FORMAT_RAW
-# ifdef HAVE_INPUT_TEST
-
-
-struct dabInputTestData {
- unsigned long counter;
-};
-
-
-struct dabInputOperations dabInputTestOperations = {
- dabInputTestInit,
- dabInputTestOpen,
- NULL,
- NULL,
- NULL,
- NULL,
- dabInputTestRead,
- dabInputTestSetbitrate,
- dabInputTestClose,
- dabInputTestClean,
- NULL
-};
-
-
-int dabInputTestInit(void** args)
-{
- dabInputTestData* input = new dabInputTestData;
- memset(input, 0, sizeof(*input));
- input->counter = 0;
- *args = input;
- return 0;
-}
-
-
-int dabInputTestOpen(void* args, const char* inputName)
-{
- return 0;
-}
-
-
-int dabInputTestRead(dabInputOperations* ops, void* args, void* buffer, int size)
-{
- dabInputTestData* input = (dabInputTestData*)args;
- char* data = (char*)buffer;
-
- *((long*)buffer) = htonl(input->counter++);
- for (int i = sizeof(input->counter); i < size; ++i) {
- data[i] = i;
- }
- return size;
-}
-
-
-int dabInputTestSetbitrate(dabInputOperations* ops, void* args, int bitrate)
-{
- return bitrate;
-}
-
-
-int dabInputTestClose(void* args)
-{
- return 0;
-}
-
-
-int dabInputTestClean(void** args)
-{
- dabInputTestData* input = (dabInputTestData*)(*args);
- delete input;
- return 0;
-}
-
-
-# endif
-#endif
diff --git a/src/dabInputTest.h b/src/dabInputTest.h
deleted file mode 100644
index 34ebc05..0000000
--- a/src/dabInputTest.h
+++ /dev/null
@@ -1,50 +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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef DAB_INPUT_TEST_H
-#define DAB_INPUT_TEST_H
-
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include "dabInput.h"
-
-
-#ifdef HAVE_FORMAT_RAW
-# ifdef HAVE_INPUT_TEST
-
-
-extern struct dabInputOperations dabInputTestOperations;
-
-int dabInputTestInit(void** args);
-int dabInputTestOpen(void* args, const char* inputName);
-int dabInputTestRead(dabInputOperations* ops, void* args, void* buffer, int size);
-int dabInputTestSetbitrate(dabInputOperations* ops, void* args, int bitrate);
-int dabInputTestClose(void* args);
-int dabInputTestClean(void** args);
-
-
-# endif
-#endif
-
-
-#endif // DAB_INPUT_TEST_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 <http://www.gnu.org/licenses/>.
- */
-
-#include "dabInputUdp.h"
-
-#include <string.h>
-#include <limits.h>
-
-
-#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<uint8_t*>(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/dabOutput/dabOutput.h b/src/dabOutput/dabOutput.h
index eaa623f..c10d358 100644
--- a/src/dabOutput/dabOutput.h
+++ b/src/dabOutput/dabOutput.h
@@ -222,11 +222,6 @@ class TCPDataDispatcher;
class DabOutputTcp : public DabOutput
{
public:
- DabOutputTcp() {}
- DabOutputTcp(const DabOutputTcp& other) = delete;
- const DabOutputTcp& operator=(const DabOutputTcp& other) = delete;
- ~DabOutputTcp();
-
int Open(const char* name);
int Write(void* buffer, int size);
int Close();
@@ -238,7 +233,7 @@ class DabOutputTcp : public DabOutput
private:
std::string uri_;
- TCPDataDispatcher* dispatcher_;
+ std::shared_ptr<TCPDataDispatcher> dispatcher_;
};
// -------------- Simul ------------------
diff --git a/src/dabOutput/dabOutputTcp.cpp b/src/dabOutput/dabOutputTcp.cpp
index 8696bec..2aab48a 100644
--- a/src/dabOutput/dabOutputTcp.cpp
+++ b/src/dabOutput/dabOutputTcp.cpp
@@ -95,6 +95,10 @@ class TCPConnection
m_running = false;
}
}
+
+ auto addr = m_sock.getRemoteAddress();
+ etiLog.level(debug) << "Dropping TCP Connection from " <<
+ addr.getHostAddress() << ":" << addr.getPort();
}
};
@@ -121,22 +125,28 @@ class TCPDataDispatcher
connection.queue.push(data);
}
- m_connections.remove_if([](TCPConnection& conn){ return conn.is_overloaded(); });
+ m_connections.remove_if([](const TCPConnection& conn){ return conn.is_overloaded(); });
}
private:
void process(long) {
- m_listener_socket.listen();
+ try {
+ m_listener_socket.listen();
- const int timeout_ms = 1000;
+ const int timeout_ms = 1000;
- while (m_running) {
- // Add a new TCPConnection to the list, constructing it from the client socket
- auto optional_sock = m_listener_socket.accept(timeout_ms);
- if (optional_sock) {
- m_connections.emplace(m_connections.begin(), std::move(*optional_sock));
+ while (m_running) {
+ // Add a new TCPConnection to the list, constructing it from the client socket
+ auto sock = m_listener_socket.accept(timeout_ms);
+ if (sock.isValid()) {
+ m_connections.emplace(m_connections.begin(), move(sock));
+ }
}
}
+ catch (std::runtime_error& e) {
+ etiLog.level(error) << "TCPDataDispatcher caught runtime error: " << e.what();
+ m_running = false;
+ }
}
atomic<bool> m_running;
@@ -145,14 +155,6 @@ class TCPDataDispatcher
std::list<TCPConnection> m_connections;
};
-DabOutputTcp::~DabOutputTcp()
-{
- if (dispatcher_) {
- delete dispatcher_;
- dispatcher_ = nullptr;
- }
-}
-
static bool parse_uri(const char *uri, long *port, string& addr)
{
char* const hostport = strdup(uri); // the uri is actually an tuple host:port
@@ -199,7 +201,7 @@ int DabOutputTcp::Open(const char* name)
uri_ = name;
if (success) {
- dispatcher_ = new TCPDataDispatcher();
+ dispatcher_ = make_shared<TCPDataDispatcher>();
try {
dispatcher_->start(port, address);
}
diff --git a/src/input/File.cpp b/src/input/File.cpp
new file mode 100644
index 0000000..5c61fd4
--- /dev/null
+++ b/src/input/File.cpp
@@ -0,0 +1,443 @@
+/*
+ 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
+
+ */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <sstream>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#ifndef _WIN32
+# define O_BINARY 0
+#endif
+
+#include "input/File.h"
+#include "mpeg.h"
+#include "ReedSolomon.h"
+
+namespace Inputs {
+
+#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
+;
+
+
+int FileBase::open(const std::string& name)
+{
+ m_fd = ::open(name.c_str(), O_RDONLY | O_BINARY);
+ if (m_fd == -1) {
+ std::stringstream ss;
+ ss << "Could not open input file " << name << ": " <<
+ strerror(errno);
+ throw std::runtime_error(ss.str());
+ }
+ return 0;
+}
+
+int FileBase::setBitrate(int bitrate)
+{
+ if (bitrate <= 0) {
+ etiLog.log(error, "Invalid bitrate (%i)\n", bitrate);
+ return -1;
+ }
+
+ return bitrate;
+}
+
+
+int FileBase::close()
+{
+ if (m_fd != -1) {
+ ::close(m_fd);
+ m_fd = -1;
+ }
+ return 0;
+}
+
+int FileBase::rewind()
+{
+ return ::lseek(m_fd, 0, SEEK_SET);
+}
+
+ssize_t FileBase::readFromFile(uint8_t* buffer, size_t size)
+{
+ ssize_t ret = read(m_fd, buffer, size);
+
+ if (ret == -1) {
+ etiLog.log(alert, "ERROR: Can't read file\n");
+ perror("");
+ return -1;
+ }
+
+ if (ret < (ssize_t)size) {
+ ssize_t sizeOut = ret;
+ etiLog.log(info, "reach end of file -> rewinding\n");
+ if (rewind() == -1) {
+ etiLog.log(alert, "ERROR: Can't rewind file\n");
+ return -1;
+ }
+
+ 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 < (ssize_t)size) {
+ etiLog.log(alert, "ERROR: Not enough data in file\n");
+ return -1;
+ }
+ }
+
+ return size;
+}
+
+int MPEGFile::readFrame(uint8_t* buffer, size_t size)
+{
+ int result;
+ bool do_rewind = false;
+READ_SUBCHANNEL:
+ if (m_parity) {
+ result = readData(m_fd, buffer, size, 2);
+ m_parity = false;
+ return 0;
+ } else {
+ result = readMpegHeader(m_fd, buffer, size);
+ if (result > 0) {
+ result = readMpegFrame(m_fd, buffer, size);
+ if (result < 0 && getMpegFrequency(buffer) == 24000) {
+ m_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 (do_rewind) {
+ etiLog.log(error, "file rewinded and still empty "
+ "-> frame muted\n");
+ goto MUTE_SUBCHANNEL;
+ }
+ else {
+ etiLog.log(info, "reach end of file -> rewinding\n");
+ rewind();
+ 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 < (ssize_t)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:
+ result = 0;
+ break;
+ case MPEG_ORIGINAL:
+ result = 0;
+ 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 MPEGFile::setBitrate(int bitrate)
+{
+ if (bitrate == 0) {
+ uint8_t buffer[4];
+
+ if (readFrame(buffer, 4) == 0) {
+ bitrate = getMpegBitrate(buffer);
+ }
+ else {
+ bitrate = -1;
+ }
+ rewind();
+ }
+ return bitrate;
+}
+
+int RawFile::readFrame(uint8_t* buffer, size_t size)
+{
+ return readFromFile(buffer, size);
+}
+
+PacketFile::PacketFile(bool enhancedPacketMode)
+{
+ m_enhancedPacketEnabled = enhancedPacketMode;
+}
+
+int PacketFile::readFrame(uint8_t* buffer, size_t size)
+{
+ size_t written = 0;
+ int length;
+ packetHeader* header;
+ int indexRow;
+ int indexCol;
+
+ while (written < size) {
+ if (m_enhancedPacketWaiting > 0) {
+ *buffer = 192 - m_enhancedPacketWaiting;
+ *buffer /= 22;
+ *buffer <<= 2;
+ *(buffer++) |= 0x03;
+ *(buffer++) = 0xfe;
+ indexCol = 188;
+ indexCol += (192 - m_enhancedPacketWaiting) / 12;
+ indexRow = 0;
+ indexRow += (192 - m_enhancedPacketWaiting) % 12;
+ for (int j = 0; j < 22; ++j) {
+ if (m_enhancedPacketWaiting == 0) {
+ *(buffer++) = 0;
+ }
+ else {
+ *(buffer++) = m_enhancedPacketData[indexRow][indexCol];
+ if (++indexRow == 12) {
+ indexRow = 0;
+ ++indexCol;
+ }
+ --m_enhancedPacketWaiting;
+ }
+ }
+ written += 24;
+ if (m_enhancedPacketWaiting == 0) {
+ m_enhancedPacketLength = 0;
+ }
+ }
+ else if (m_packetLength != 0) {
+ header = (packetHeader*)(&m_packetData[0]);
+ if (written + m_packetLength > (unsigned)size) {
+ memset(buffer, 0, 22);
+ buffer[22] = 0x60;
+ buffer[23] = 0x4b;
+ length = 24;
+ }
+ else if (m_enhancedPacketEnabled) {
+ if (m_enhancedPacketLength + m_packetLength > (12 * 188)) {
+ memset(buffer, 0, 22);
+ buffer[22] = 0x60;
+ buffer[23] = 0x4b;
+ length = 24;
+ }
+ else {
+ std::copy(m_packetData.begin(),
+ m_packetData.begin() + m_packetLength,
+ buffer);
+ length = m_packetLength;
+ m_packetLength = 0;
+ }
+ }
+ else {
+ std::copy(m_packetData.begin(),
+ m_packetData.begin() + m_packetLength,
+ buffer);
+ length = m_packetLength;
+ m_packetLength = 0;
+ }
+
+ if (m_enhancedPacketEnabled) {
+ indexCol = m_enhancedPacketLength / 12;
+ indexRow = m_enhancedPacketLength % 12; // TODO Check if always 0
+ for (int j = 0; j < length; ++j) {
+ m_enhancedPacketData[indexRow][indexCol] = buffer[j];
+ if (++indexRow == 12) {
+ indexRow = 0;
+ ++indexCol;
+ }
+ }
+ m_enhancedPacketLength += length;
+ if (m_enhancedPacketLength >= (12 * 188)) {
+ m_enhancedPacketLength = (12 * 188);
+ ReedSolomon encoder(204, 188);
+ for (int j = 0; j < 12; ++j) {
+ encoder.encode(&m_enhancedPacketData[j][0], 188);
+ }
+ m_enhancedPacketWaiting = 192;
+ }
+ }
+ written += length;
+ buffer += length;
+ }
+ else {
+ int nbBytes = readFromFile(buffer, 3);
+ header = (packetHeader*)buffer;
+ if (nbBytes == -1) {
+ if (errno == EAGAIN) goto END_PACKET;
+ perror("Packet file");
+ return -1;
+ }
+ else if (nbBytes == 0) {
+ if (rewind() == -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(&m_packetData[0], header, 3);
+ readFromFile(&m_packetData[3], length - 3);
+ m_packetLength = length;
+ continue;
+ }
+
+ if (m_enhancedPacketEnabled) {
+ if (m_enhancedPacketLength + length > (12 * 188)) {
+ memcpy(&m_packetData[0], header, 3);
+ readFromFile(&m_packetData[3], length - 3);
+ m_packetLength = length;
+ continue;
+ }
+ }
+
+ nbBytes = readFromFile(buffer + 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 (rewind() == -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 (m_enhancedPacketEnabled) {
+ indexCol = m_enhancedPacketLength / 12;
+ indexRow = m_enhancedPacketLength % 12; // TODO Check if always 0
+ for (int j = 0; j < length; ++j) {
+ m_enhancedPacketData[indexRow][indexCol] = buffer[j];
+ if (++indexRow == 12) {
+ indexRow = 0;
+ ++indexCol;
+ }
+ }
+ m_enhancedPacketLength += length;
+ if (m_enhancedPacketLength >= (12 * 188)) {
+ if (m_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(&m_enhancedPacketData[j][0], 188);
+ }
+ m_enhancedPacketWaiting = 192;
+ }
+ }
+ written += length;
+ buffer += length;
+ }
+ }
+END_PACKET:
+ while (written < size) {
+ memset(buffer, 0, 22);
+ buffer[22] = 0x60;
+ buffer[23] = 0x4b;
+ buffer += 24;
+ written += 24;
+ }
+ return written;
+}
+
+};
diff --git a/src/input/File.h b/src/input/File.h
new file mode 100644
index 0000000..080d6b5
--- /dev/null
+++ b/src/input/File.h
@@ -0,0 +1,91 @@
+/*
+ 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
+
+ */
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <vector>
+#include <array>
+#include <string>
+#include <stdint.h>
+#include "input/inputs.h"
+#include "ManagementServer.h"
+
+namespace Inputs {
+
+class FileBase : public InputBase {
+ public:
+ virtual int open(const std::string& name);
+ virtual int readFrame(uint8_t* buffer, size_t size) = 0;
+ virtual int setBitrate(int bitrate);
+ virtual int close();
+
+ /* Rewind the file
+ * Returns -1 on failure, 0 on success
+ */
+ virtual int rewind();
+ protected:
+ /* Read len bytes from the file into buf, and return
+ * the number of bytes read, or -1 in case of error.
+ */
+ virtual ssize_t readFromFile(uint8_t* buf, size_t len);
+
+ // We use unix open() instead of fopen() because
+ // we might want to do non-blocking I/O in the future
+ int m_fd = -1;
+};
+
+class MPEGFile : public FileBase {
+ public:
+ virtual int readFrame(uint8_t* buffer, size_t size);
+ virtual int setBitrate(int bitrate);
+
+ private:
+ bool m_parity = false;
+};
+
+class RawFile : public FileBase {
+ public:
+ virtual int readFrame(uint8_t* buffer, size_t size);
+};
+
+class PacketFile : public FileBase {
+ public:
+ PacketFile(bool enhancedPacketMode);
+ virtual int readFrame(uint8_t* buffer, size_t size);
+
+ protected:
+ std::array<uint8_t,96> m_packetData;
+ size_t m_packetLength;
+
+ /* Enhanced packet mode enables FEC for MSC packet mode
+ * as described in EN 300 401 Clause 5.3.5
+ */
+ bool m_enhancedPacketEnabled = false;
+ std::array<std::array<uint8_t, 204>,12> m_enhancedPacketData;
+ size_t m_enhancedPacketWaiting;
+ size_t m_enhancedPacketLength;
+};
+
+};
diff --git a/src/dabInputPrbs.cpp b/src/input/Prbs.cpp
index f34c427..7856a46 100644
--- a/src/dabInputPrbs.cpp
+++ b/src/input/Prbs.cpp
@@ -26,7 +26,7 @@
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "dabInputPrbs.h"
+#include "input/Prbs.h"
#include <stdexcept>
#include <sstream>
@@ -34,59 +34,72 @@
#include <limits.h>
#include <stdlib.h>
#include <errno.h>
+#include "utils.h"
using namespace std;
-int DabInputPrbs::open(const string name)
+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 << 20) | (1 << 17) | (1 << 0);
+
+int Prbs::open(const string& name)
{
- if (name[0] != ':') {
- throw invalid_argument(
- "Invalid PRBS address format. Must be prbs://:polynomial.");
+ if (name.substr(0, 7) != "prbs://") {
+ throw logic_error("Invalid PRBS name");
}
- const string poly_str = name.substr(1);
+ const string& url_polynomial = name.substr(7);
- long polynomial = strtol(poly_str.c_str(), (char **)NULL, 10);
- if ((polynomial == LONG_MIN) || (polynomial == LONG_MAX)) {
- stringstream ss;
- ss << "Can't convert polynomial number " << poly_str;
- throw invalid_argument(ss.str());
+ if (url_polynomial.empty()) {
+ m_prbs.setup(PRBS_DEFAULT_POLY);
}
+ else {
+ if (url_polynomial[0] != ':') {
+ throw invalid_argument(
+ "Invalid PRBS address format. "
+ "Must be prbs://:polynomial.");
+ }
- if (polynomial == 0) {
- throw invalid_argument("No polynomial given for PRBS input");
- }
+ const string poly_str = url_polynomial.substr(1);
+
+ long polynomial = hexparse(poly_str);
- m_prbs.setup(polynomial);
+ 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)
+int Prbs::readFrame(uint8_t* buffer, size_t size)
{
- unsigned char* cbuffer = reinterpret_cast<unsigned char*>(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;
}
-int DabInputPrbs::setBitrate(int bitrate)
+int Prbs::setBitrate(int bitrate)
{
return bitrate;
}
-int DabInputPrbs::close()
+int Prbs::close()
{
return 0;
}
-int DabInputPrbs::rewind()
+int Prbs::rewind()
{
m_prbs.rewind();
return 0;
}
+};
diff --git a/src/dabInputPrbs.h b/src/input/Prbs.h
index 9cde7e2..3b2b7d4 100644
--- a/src/dabInputPrbs.h
+++ b/src/input/Prbs.h
@@ -28,19 +28,17 @@
#pragma once
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
#include <string>
-#include "dabInput.h"
+#include "input/inputs.h"
#include "prbs.h"
-class DabInputPrbs : public DabInputBase {
+namespace Inputs {
+
+class Prbs : public InputBase {
public:
- virtual int open(const std::string name);
- virtual int readFrame(void* buffer, int size);
+ virtual int open(const std::string& name);
+ virtual int readFrame(uint8_t* buffer, size_t size);
virtual int setBitrate(int bitrate);
virtual int close();
@@ -50,3 +48,5 @@ class DabInputPrbs : public DabInputBase {
PrbsGenerator m_prbs;
};
+};
+
diff --git a/src/input/Udp.cpp b/src/input/Udp.cpp
new file mode 100644
index 0000000..a238d9b
--- /dev/null
+++ b/src/input/Udp.cpp
@@ -0,0 +1,134 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "input/Udp.h"
+
+#include <stdexcept>
+#include <sstream>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "utils.h"
+
+using namespace std;
+
+namespace Inputs {
+
+int Udp::open(const std::string& name)
+{
+ // Skip the udp:// part if it is present
+ const string endpoint = (name.substr(0, 6) == "udp://") ?
+ name.substr(6) : name;
+
+ // The endpoint should be address:port
+ const auto colon_pos = endpoint.find_first_of(":");
+ if (colon_pos == string::npos) {
+ stringstream ss;
+ ss << "'" << name <<
+ " is an invalid format for udp address: "
+ "expected [udp://]address:port";
+ throw invalid_argument(ss.str());
+ }
+
+ const auto address = endpoint.substr(0, colon_pos);
+ const auto port_str = endpoint.substr(colon_pos + 1);
+
+ const long port = strtol(port_str.c_str(), nullptr, 10);
+
+ if ((port == LONG_MIN or port == LONG_MAX) and errno == ERANGE) {
+ throw out_of_range("udp input: port out of range");
+ }
+ else if (port == 0 and errno != 0) {
+ stringstream ss;
+ ss << "udp input port parse error: " << strerror(errno);
+ throw invalid_argument(ss.str());
+ }
+
+ if (port == 0) {
+ throw out_of_range("can't use port number 0 in udp address");
+ }
+
+ if (m_sock.reinit(port, address) == -1) {
+ stringstream ss;
+ ss << "Could not init UDP socket: " << inetErrMsg;
+ throw runtime_error(ss.str());
+ }
+
+ if (m_sock.setBlocking(false) == -1) {
+ stringstream ss;
+ ss << "Could not set non-blocking UDP socket: " << inetErrMsg;
+ throw runtime_error(ss.str());
+ }
+
+ return 0;
+}
+
+int Udp::readFrame(uint8_t* buffer, size_t size)
+{
+ uint8_t* data = reinterpret_cast<uint8_t*>(buffer);
+
+ // Regardless of buffer contents, try receiving data.
+ UdpPacket packet;
+ int ret = m_sock.receive(packet);
+
+ if (ret == -1) {
+ stringstream ss;
+ ss << "Could not read from UDP socket: " << inetErrMsg;
+ throw runtime_error(ss.str());
+ }
+
+ std::copy(packet.getData(), packet.getData() + packet.getSize(),
+ back_inserter(m_buffer));
+
+ // Take data from the buffer if it contains enough data,
+ // in any case write the buffer
+ if (m_buffer.size() >= (size_t)size) {
+ std::copy(m_buffer.begin(), m_buffer.begin() + size, data);
+ }
+ else {
+ memset(data, 0x0, size);
+ }
+
+ return size;
+}
+
+int Udp::setBitrate(int bitrate)
+{
+ if (bitrate <= 0) {
+ etiLog.log(error, "Invalid bitrate (%i)\n", bitrate);
+ return -1;
+ }
+
+ return bitrate;
+}
+
+int Udp::close()
+{
+ return m_sock.close();
+}
+
+};
diff --git a/src/dabInputUdp.h b/src/input/Udp.h
index ac9ddb0..379dbf3 100644
--- a/src/dabInputUdp.h
+++ b/src/input/Udp.h
@@ -1,6 +1,11 @@
/*
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.
@@ -19,41 +24,29 @@
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef DAB_INPUT_UDP_H
-#define DAB_INPUT_UDP_H
-
+#pragma once
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include "dabInput.h"
-#include "dabInputFifo.h"
+#include <string>
+#include <vector>
+#include "input/inputs.h"
#include "UdpSocket.h"
+namespace Inputs {
-#ifdef HAVE_FORMAT_RAW
-# ifdef HAVE_INPUT_UDP
-
-
-extern struct dabInputOperations dabInputUdpOperations;
+class Udp : public InputBase {
+ public:
+ virtual int open(const std::string& name);
+ virtual int readFrame(uint8_t* buffer, size_t size);
+ virtual int setBitrate(int bitrate);
+ virtual int close();
+ private:
+ UdpSocket m_sock;
-struct dabInputUdpData {
- UdpSocket* socket;
- UdpPacket* packet;
- dabInputFifoStats stats;
+ // The content of the UDP packets gets written into the
+ // buffer, and the UDP packet boundaries disappear there.
+ std::vector<uint8_t> m_buffer;
};
+};
-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
diff --git a/src/dabInputZmq.cpp b/src/input/Zmq.cpp
index 790a961..a5601fa 100644
--- a/src/dabInputZmq.cpp
+++ b/src/input/Zmq.cpp
@@ -2,7 +2,7 @@
Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
Research Center Canada)
- Copyright (C) 2013, 2014 Matthias P. Braendli
+ Copyright (C) 2016 Matthias P. Braendli
http://www.opendigitalradio.org
ZeroMQ input. see www.zeromq.org for more info
@@ -39,17 +39,8 @@
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "dabInput.h"
-#include "dabInputZmq.h"
-#include "PcDebug.h"
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "input/Zmq.h"
-#ifdef HAVE_INPUT_ZEROMQ
-
-#include "zmq.hpp"
#include <cstdio>
#include <cstdlib>
#include <list>
@@ -58,22 +49,28 @@
#include <string>
#include <sstream>
#include <limits.h>
+#include "PcDebug.h"
+#include "Log.h"
#ifdef __MINGW32__
# define bzero(s, n) memset(s, 0, n)
#endif
+namespace Inputs {
+
using namespace std;
int readkey(string& keyfile, char* key)
{
- int fd = open(keyfile.c_str(), O_RDONLY);
- if (fd < 0)
- return fd;
- int ret = read(fd, key, CURVE_KEYLEN);
- close(fd);
- if (ret < 0) {
- return ret;
+ FILE* fd = fopen(keyfile.c_str(), "r");
+ if (fd == nullptr) {
+ return -1;
+ }
+
+ int ret = fread(key, CURVE_KEYLEN, 1, fd);
+ fclose(fd);
+ if (ret == 0) {
+ return -1;
}
/* It needs to be zero-terminated */
@@ -89,7 +86,7 @@ int readkey(string& keyfile, char* key)
* keys to the socket, and finally bind the socket
* to the new address
*/
-void DabInputZmqBase::rebind()
+void ZmqBase::rebind()
{
if (! m_zmq_sock_bound_to.empty()) {
try {
@@ -223,7 +220,7 @@ void DabInputZmqBase::rebind()
}
}
-int DabInputZmqBase::open(const std::string inputUri)
+int ZmqBase::open(const std::string& inputUri)
{
m_inputUri = inputUri;
@@ -236,20 +233,20 @@ int DabInputZmqBase::open(const std::string inputUri)
return 0;
}
-int DabInputZmqBase::close()
+int ZmqBase::close()
{
m_zmq_sock.close();
return 0;
}
-int DabInputZmqBase::setBitrate(int bitrate)
+int ZmqBase::setBitrate(int bitrate)
{
m_bitrate = bitrate;
return bitrate; // TODO do a nice check here
}
// size corresponds to a frame size. It is constant for a given bitrate
-int DabInputZmqBase::readFrame(void* buffer, int size)
+int ZmqBase::readFrame(uint8_t* buffer, size_t size)
{
int rc;
@@ -340,7 +337,7 @@ int DabInputZmqBase::readFrame(void* buffer, int size)
/******** MPEG input *******/
// Read a MPEG frame from the socket, and push to list
-int DabInputZmqMPEG::readFromSocket(size_t framesize)
+int ZmqMPEG::readFromSocket(size_t framesize)
{
bool messageReceived = false;
zmq::message_t msg;
@@ -410,7 +407,7 @@ int DabInputZmqMPEG::readFromSocket(size_t framesize)
// Read a AAC+ superframe from the socket, cut it into five frames,
// and push to list
-int DabInputZmqAAC::readFromSocket(size_t framesize)
+int ZmqAAC::readFromSocket(size_t framesize)
{
bool messageReceived;
zmq::message_t msg;
@@ -496,7 +493,7 @@ int DabInputZmqAAC::readFromSocket(size_t framesize)
/********* REMOTE CONTROL ***********/
-void DabInputZmqBase::set_parameter(const string& parameter,
+void ZmqBase::set_parameter(const string& parameter,
const string& value)
{
if (parameter == "buffer") {
@@ -576,7 +573,7 @@ void DabInputZmqBase::set_parameter(const string& parameter,
}
}
-const string DabInputZmqBase::get_parameter(const string& parameter) const
+const string ZmqBase::get_parameter(const string& parameter) const
{
stringstream ss;
if (parameter == "buffer") {
@@ -615,5 +612,5 @@ const string DabInputZmqBase::get_parameter(const string& parameter) const
}
-#endif
+};
diff --git a/src/dabInputZmq.h b/src/input/Zmq.h
index fdd0f1b..8d729e0 100644
--- a/src/dabInputZmq.h
+++ b/src/input/Zmq.h
@@ -2,7 +2,7 @@
Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications
Research Center Canada)
- Copyright (C) 2013, 2014 Matthias P. Braendli
+ Copyright (C) 2016 Matthias P. Braendli
http://www.opendigitalradio.org
ZeroMQ input. see www.zeromq.org for more info
@@ -41,48 +41,37 @@
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef DAB_INPUT_ZMQ_H
-#define DAB_INPUT_ZMQ_H
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#ifdef HAVE_INPUT_ZEROMQ
+#pragma once
#include <list>
#include <string>
#include <stdint.h>
#include "zmq.hpp"
-#include "dabInput.h"
+#include "input/inputs.h"
#include "ManagementServer.h"
+namespace Inputs {
+
/* The frame_buffer contains DAB logical frames as defined in
* TS 102 563, section 6.
* Five elements of this buffer make one AAC superframe (120ms audio)
*/
-// Number of elements to prebuffer before starting the pipeline
-#define INPUT_ZMQ_DEF_PREBUFFERING (5*4) // 480ms
-
-// Default frame_buffer size in number of elements
-#define INPUT_ZMQ_DEF_BUFFER_SIZE (5*8) // 960ms
-
// Minimum frame_buffer size in number of elements
// This is one AAC superframe, but you probably don't want to
// go that low anyway.
-#define INPUT_ZMQ_MIN_BUFFER_SIZE (5*1) // 120ms
+const size_t INPUT_ZMQ_MIN_BUFFER_SIZE = 5*1; // 120ms
// Maximum frame_buffer size in number of elements
// One minute is clearly way over what everybody would
// want.
-#define INPUT_ZMQ_MAX_BUFFER_SIZE (5*500) // 60s
+const size_t INPUT_ZMQ_MAX_BUFFER_SIZE = 5*500; // 60s
/* The ZeroMQ Curve key is 40 bytes long in Z85 representation
*
* But we need to store it as zero-terminated string.
*/
-#define CURVE_KEYLEN 40
+const size_t CURVE_KEYLEN = 40;
/* helper to invalidate a key */
#define INVALIDATE_KEY(k) memset(k, 0, CURVE_KEYLEN+1)
@@ -156,9 +145,9 @@ struct zmq_frame_header_t
#define ZMQ_FRAME_DATA(f) ( ((uint8_t*)f)+sizeof(zmq_frame_header_t) )
-class DabInputZmqBase : public DabInputBase, public RemoteControllable {
+class ZmqBase : public InputBase, public RemoteControllable {
public:
- DabInputZmqBase(const std::string name,
+ ZmqBase(const std::string name,
dab_input_zmq_config_t config)
: RemoteControllable(name),
m_zmq_context(1),
@@ -191,8 +180,8 @@ class DabInputZmqBase : public DabInputBase, public RemoteControllable {
INVALIDATE_KEY(m_curve_encoder_key);
}
- virtual int open(const std::string inputUri);
- virtual int readFrame(void* buffer, int size);
+ virtual int open(const std::string& inputUri);
+ virtual int readFrame(uint8_t* buffer, size_t size);
virtual int setBitrate(int bitrate);
virtual int close();
@@ -238,11 +227,11 @@ class DabInputZmqBase : public DabInputBase, public RemoteControllable {
size_t m_prebuf_current;
};
-class DabInputZmqMPEG : public DabInputZmqBase {
+class ZmqMPEG : public ZmqBase {
public:
- DabInputZmqMPEG(const std::string name,
+ ZmqMPEG(const std::string name,
dab_input_zmq_config_t config)
- : DabInputZmqBase(name, config) {
+ : ZmqBase(name, config) {
RC_ADD_PARAMETER(buffer,
"Size of the input buffer [mpeg frames]");
@@ -254,11 +243,11 @@ class DabInputZmqMPEG : public DabInputZmqBase {
virtual int readFromSocket(size_t framesize);
};
-class DabInputZmqAAC : public DabInputZmqBase {
+class ZmqAAC : public ZmqBase {
public:
- DabInputZmqAAC(const std::string name,
+ ZmqAAC(const std::string name,
dab_input_zmq_config_t config)
- : DabInputZmqBase(name, config) {
+ : ZmqBase(name, config) {
RC_ADD_PARAMETER(buffer,
"Size of the input buffer [aac superframes]");
@@ -270,7 +259,6 @@ class DabInputZmqAAC : public DabInputZmqBase {
virtual int readFromSocket(size_t framesize);
};
-#endif // HAVE_INPUT_ZMQ
+};
-#endif // DAB_INPUT_ZMQ_H
diff --git a/src/dabInput.cpp b/src/input/inputs.h
index 942e58d..bfb1fb6 100644
--- a/src/dabInput.cpp
+++ b/src/input/inputs.h
@@ -1,6 +1,11 @@
/*
Copyright (C) 2004, 2005, 2006, 2007, 2008, 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.
@@ -19,31 +24,29 @@
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "dabInput.h"
-#include "Log.h"
+#pragma once
-#include <string.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include "Log.h"
+#include "RemoteControl.h"
+#include <string>
-bool dabInputOperations::operator==(const dabInputOperations& ops)
-{
- return memcmp(this, &ops, sizeof(*this)) == 0;
-}
+namespace Inputs {
+/* New input object base */
+class InputBase {
+ public:
+ virtual int open(const std::string& name) = 0;
+ virtual int readFrame(uint8_t* buffer, size_t size) = 0;
+ virtual int setBitrate(int bitrate) = 0;
+ virtual int close() = 0;
-int dabInputSetbuf(void* args, int size)
-{
- return 0;
-}
+ virtual ~InputBase() {}
+ protected:
+ InputBase() {}
+};
+};
-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/mpeg.c b/src/mpeg.c
index f7aed34..a48f5bb 100644
--- a/src/mpeg.c
+++ b/src/mpeg.c
@@ -219,3 +219,29 @@ int readMpegFrame(int file, void* data, int size)
}
return framelength;
}
+
+int checkDabMpegFrame(void* data) {
+ mpegHeader* header = (mpegHeader*)data;
+ unsigned long* headerData = (unsigned long*)data;
+ if ((*headerData & 0x0f0ffcff) == 0x0004fcff) return 0;
+ if ((*headerData & 0x0f0ffcff) == 0x0004f4ff) return 0;
+ if (getMpegFrequency(header) != 48000) {
+ if (getMpegFrequency(header) != 24000) {
+ return MPEG_FREQUENCY;
+ }
+ }
+ if (header->padding != 0) {
+ return MPEG_PADDING;
+ }
+ if (header->emphasis != 0) {
+ return MPEG_EMPHASIS;
+ }
+ if (header->copyright != 0) {
+ return MPEG_COPYRIGHT;
+ }
+ if (header->original != 0) {
+ return MPEG_ORIGINAL;
+ }
+ return -1;
+}
+
diff --git a/src/mpeg.h b/src/mpeg.h
index aa7cfb6..15b9b80 100644
--- a/src/mpeg.h
+++ b/src/mpeg.h
@@ -75,6 +75,13 @@ ssize_t readData(int file, void* data, size_t size, unsigned int tries);
int readMpegHeader(int file, void* data, int size);
int readMpegFrame(int file, void* data, int size);
+#define MPEG_FREQUENCY -2
+#define MPEG_PADDING -3
+#define MPEG_COPYRIGHT -4
+#define MPEG_ORIGINAL -5
+#define MPEG_EMPHASIS -6
+int checkDabMpegFrame(void* data);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/prbs.cpp b/src/prbs.cpp
index 0ac3187..b0e3d6d 100644
--- a/src/prbs.cpp
+++ b/src/prbs.cpp
@@ -28,18 +28,18 @@
/*
* Generate a parity check for a 32-bit word.
*/
-static unsigned long parity_check(unsigned long prbs_accum)
+static uint32_t parity_check(uint32_t prbs_accum)
{
- unsigned long mask=1UL, parity=0UL;
- int i;
- for (i = 0; i < 32; ++i) {
- parity ^= ((prbs_accum & mask) != 0UL);
+ uint32_t mask = 1;
+ uint32_t parity = 0;
+ for (int i = 0; i < 32; ++i) {
+ parity ^= ((prbs_accum & mask) != 0);
mask <<= 1;
}
return parity;
}
-void PrbsGenerator::setup(long polynomial)
+void PrbsGenerator::setup(uint32_t polynomial)
{
this->polynomial = polynomial;
this->accum = 0;
@@ -65,7 +65,7 @@ void PrbsGenerator::gen_prbs_table()
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 256; ++j) {
- unsigned long prbs_accum = ((unsigned long)j << (i * 8));
+ uint32_t prbs_accum = ((uint32_t)j << (i * 8));
for (int k = 0; k < 8; ++k) {
prbs_accum = (prbs_accum << 1)
^ parity_check(prbs_accum & polynomial);
@@ -76,24 +76,23 @@ void PrbsGenerator::gen_prbs_table()
}
}
-unsigned long PrbsGenerator::update_prbs()
+uint32_t PrbsGenerator::update_prbs()
{
- unsigned char acc_lsb = 0;
- int i;
- for (i = 0; i < 4; ++i ) {
+ uint8_t acc_lsb = 0;
+ for (int i = 0; i < 4; ++i ) {
acc_lsb ^= prbs_table [i] [ (accum >> (i * 8) ) & 0xff ];
}
- return (accum << 8) ^ ((unsigned long)acc_lsb);
+ return (accum << 8) ^ ((uint32_t)acc_lsb);
}
void PrbsGenerator::gen_weight_table()
{
for (int i = 0; i < 256; ++i) {
- unsigned char mask = 1U;
- unsigned char ones_count = 0U;
+ uint8_t mask = 1;
+ uint8_t ones_count = 0;
for (int j = 0; j < 8; ++j) {
- ones_count += ((i & mask) != 0U);
+ ones_count += ((i & mask) != 0);
mask = mask << 1;
}
weight[i] = ones_count;
@@ -101,23 +100,23 @@ void PrbsGenerator::gen_weight_table()
}
size_t PrbsGenerator::error_count(
- unsigned char *rx_data,
- int rx_data_length)
+ uint8_t *rx_data,
+ size_t rx_data_length)
{
- unsigned long error_count = 0U;
- unsigned long prbs_accum = 0U;
+ uint32_t error_count = 0;
+ uint32_t prbs_accum = 0;
/* seed the PRBS accumulator */
- for (int i = 0; i < 4; ++i) {
+ for (int i = 0; i < 4; ++i) {
prbs_accum = (prbs_accum << 8) ^ (rx_data[i] ^ polarity_mask);
}
/* check the received data */
- for (int i = 0; i < rx_data_length; ++i) {
- unsigned char error_pattern = (unsigned char)
- ((prbs_accum >> 24)
- ^ (rx_data[i] ^ polarity_mask));
- if (error_pattern != 0U) {
+ for (size_t i = 0; i < rx_data_length; ++i) {
+ uint8_t error_pattern =
+ (prbs_accum >> 24) ^ (rx_data[i] ^ polarity_mask);
+
+ if (error_pattern != 0) {
error_count += weight[error_pattern];
}
prbs_accum = update_prbs();
@@ -126,19 +125,19 @@ size_t PrbsGenerator::error_count(
}
void PrbsGenerator::gen_sequence(
- unsigned char *tx_data,
- int tx_data_length,
- unsigned long polynomial)
+ uint8_t *tx_data,
+ size_t tx_data_length,
+ uint32_t polynomial)
{
- unsigned long prbs_accum = 0U;
+ uint32_t prbs_accum = 0;
while (prbs_accum < polynomial) {
prbs_accum <<= 1;
prbs_accum |= 1;
}
- while (tx_data_length-- > 0) {
+ for (size_t i = 0; i < tx_data_length; i++) {
prbs_accum = update_prbs();
- *(tx_data++) = (unsigned char)(prbs_accum & 0xff);
+ tx_data[i] = (uint8_t)(prbs_accum & 0xff);
}
}
diff --git a/src/prbs.h b/src/prbs.h
index 5b6b7c2..0c29965 100644
--- a/src/prbs.h
+++ b/src/prbs.h
@@ -30,7 +30,7 @@
class PrbsGenerator {
public:
- void setup(long polynomial);
+ void setup(uint32_t polynomial);
uint8_t step(void);
@@ -42,30 +42,30 @@ class PrbsGenerator {
void gen_prbs_table(void);
/* Update a 32-bit PRBS generator eight bits at a time. */
- unsigned long update_prbs(void);
+ uint32_t update_prbs(void);
/* Generate the weight table. */
void gen_weight_table(void);
/* Count the number of errors in a block of received data. */
size_t error_count(
- unsigned char *rx_data,
- int rx_data_length);
+ uint8_t *rx_data,
+ size_t rx_data_length);
void gen_sequence(
- unsigned char *tx_data,
- int tx_data_length,
- unsigned long polynomial);
+ uint8_t *tx_data,
+ size_t tx_data_length,
+ uint32_t polynomial);
// table of matrix products used to update a 32-bit PRBS generator
- unsigned long prbs_table [4] [256];
+ uint32_t prbs_table [4] [256];
// table of weights for 8-bit bytes
- unsigned char weight[256];
+ uint8_t weight[256];
// PRBS polynomial generator
- unsigned long polynomial;
+ uint32_t polynomial;
// PRBS generator polarity mask
- unsigned char polarity_mask;
+ uint8_t polarity_mask;
// PRBS accumulator
- unsigned long accum;
+ uint32_t accum;
};
diff --git a/src/utils.cpp b/src/utils.cpp
index 0399467..4431407 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -103,42 +103,16 @@ void header_message()
std::cerr << "Input URLs supported:" << std::endl <<
" prbs" <<
-#if defined(HAVE_INPUT_TEST)
- " test" <<
-#endif
-#if defined(HAVE_INPUT_UDP)
" udp" <<
-#endif
-#if defined(HAVE_INPUT_FIFO)
- " fifo" <<
-#endif
-#if defined(HAVE_INPUT_FILE)
" file" <<
-#endif
-#if defined(HAVE_INPUT_ZEROMQ)
" zmq" <<
-#endif
std::endl;
std::cerr << "Inputs format supported:" << std::endl <<
-#if defined(HAVE_FORMAT_RAW)
" raw" <<
-#endif
-#if defined(HAVE_FORMAT_BRIDGE)
- " bridge" <<
-#endif
-#if defined(HAVE_FORMAT_MPEG)
" mpeg" <<
-#endif
-#if defined(HAVE_FORMAT_PACKET)
" packet" <<
-#endif
-#if defined(HAVE_FORMAT_DMB)
- " dmb" <<
-#endif
-#if defined(HAVE_FORMAT_EPM)
" epm" <<
-#endif
std::endl;
std::cerr << "Output URLs supported:" << std::endl <<
@@ -465,3 +439,29 @@ void printEnsemble(const shared_ptr<dabEnsemble> ensemble)
printLinking(ensemble);
}
+long hexparse(const std::string& input)
+{
+ long value = 0;
+ errno = 0;
+
+ // Do not use strtol's base=0 because
+ // we do not want to accept octal.
+ if (input.find("0x") == 0) {
+ value = strtol(input.c_str() + 2, nullptr, 16);
+ }
+ else {
+ value = strtol(input.c_str(), nullptr, 10);
+ }
+
+ if ((value == LONG_MIN or value == LONG_MAX) and errno == ERANGE) {
+ throw out_of_range("hexparse: value out of range");
+ }
+ else if (value == 0 and errno != 0) {
+ stringstream ss;
+ ss << "hexparse: " << strerror(errno);
+ throw invalid_argument(ss.str());
+ }
+
+ return value;
+}
+
diff --git a/src/utils.h b/src/utils.h
index f65bba8..94712cd 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -26,9 +26,10 @@
You should have received a copy of the GNU General Public License
along with ODR-DabMux. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _UTILS_H
-#define _UTILS_H
+#pragma once
+#include <string>
+#include <vector>
#include <cstdio>
#include <memory>
#include "MuxElements.h"
@@ -78,5 +79,6 @@ void printEnsemble(const std::shared_ptr<dabEnsemble> ensemble);
/* Print detailed component information */
void printComponent(DabComponent* component);
-#endif
+
+long hexparse(const std::string& input);
diff --git a/src/zmqinput-keygen.c b/src/zmqinput-keygen.c
index 8bf61ac..ee0042e 100644
--- a/src/zmqinput-keygen.c
+++ b/src/zmqinput-keygen.c
@@ -25,6 +25,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <zmq_utils.h>
+#include <zmq.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>