From d7dfb9bf8b404a434c8b867dcba43ec3efa28f3c Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Mon, 23 Sep 2019 15:32:45 +0200 Subject: Make EDI input buffer configurable --- doc/example.mux | 9 +++++++++ src/ConfigParser.cpp | 5 ++++- src/input/Edi.cpp | 4 +++- src/input/Edi.h | 22 ++++++++++++++++++---- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/doc/example.mux b/doc/example.mux index 3c5df5c..3c24c37 100644 --- a/doc/example.mux +++ b/doc/example.mux @@ -185,6 +185,15 @@ subchannels { ; timestamped takes into account the TIST inside EDI and inserts the encoded ; audio frame into the ETI frame with the same timestamp buffer-management prebuffering + + ; Maximum size of input buffer, in AAC frames (24ms) + ; when this buffer size is reached, some frames will be + ; discarded to get the size again below this value. + buffer 40 + + ; At startup or after an underrun, the buffer is filled to this + ; amount of AAC frames before streaming starts. + prebuffering 20 } sub-ri { ; This is our DAB+ programme, using a ZeroMQ input diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index d45cfef..063e4ec 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -956,7 +956,10 @@ static void setup_subchannel_from_ptree(shared_ptr& subchan, } } else if (proto == "edi") { - auto inedi = make_shared(subchanuid); + Inputs::dab_input_edi_config_t config; + config.buffer_size = pt.get("buffer", config.buffer_size); + config.prebuffering = pt.get("prebuffering", config.prebuffering); + auto inedi = make_shared(subchanuid, config); rcs.enrol(inedi.get()); subchan->input = inedi; } diff --git a/src/input/Edi.cpp b/src/input/Edi.cpp index 98e8e9c..ec0f17b 100644 --- a/src/input/Edi.cpp +++ b/src/input/Edi.cpp @@ -44,11 +44,13 @@ namespace Inputs { constexpr bool VERBOSE = false; constexpr size_t TCP_BLOCKSIZE = 2048; -Edi::Edi(const std::string& name) : +Edi::Edi(const std::string& name, const dab_input_edi_config_t& config) : RemoteControllable(name), m_tcp_receive_server(TCP_BLOCKSIZE), m_sti_writer(), m_sti_decoder(m_sti_writer, VERBOSE), + m_max_frames_overrun(config.buffer_size), + m_num_frames_prebuffering(config.prebuffering), m_name(name), m_stats(name) { diff --git a/src/input/Edi.h b/src/input/Edi.h index 0a44139..6f8c013 100644 --- a/src/input/Edi.h +++ b/src/input/Edi.h @@ -40,6 +40,22 @@ namespace Inputs { +struct dab_input_edi_config_t +{ + /* The size of the internal buffer, measured in number + * of elements. + * + * Each element corresponds to one frame, i.e. 24ms + */ + size_t buffer_size; + + /* The amount of prebuffering to do before we start streaming + * + * Same units as buffer_size + */ + size_t prebuffering; +}; + /* * Receives EDI from UDP or TCP in a separate thread and pushes that data * into the STIDecoder. Complete frames are then put into a queue for the consumer. @@ -48,7 +64,7 @@ namespace Inputs { */ class Edi : public InputBase, public RemoteControllable { public: - Edi(const std::string& name); + Edi(const std::string& name, const dab_input_edi_config_t& config); Edi(const Edi&) = delete; Edi& operator=(const Edi&) = delete; ~Edi(); @@ -79,8 +95,7 @@ class Edi : public InputBase, public RemoteControllable { std::atomic m_running = ATOMIC_VAR_INIT(false); ThreadsafeQueue m_frames; - std::mutex m_rc_params_mutex; - // InputBase defines bufferManagement, which must also be guarded by that mutex + // InputBase defines bufferManagement // Used in timestamp-based buffer management EdiDecoder::sti_frame_t m_pending_sti_frame; @@ -101,7 +116,6 @@ class Edi : public InputBase, public RemoteControllable { * Parameter 'prebuffering' inside RC. */ std::atomic m_num_frames_prebuffering = ATOMIC_VAR_INIT(10); - std::string m_name; InputStat m_stats; }; -- cgit v1.2.3