From b084bd07570cd031cbba4cc0617418883d82a9c7 Mon Sep 17 00:00:00 2001 From: Samuel Hunt Date: Thu, 8 Jan 2026 16:13:19 +0000 Subject: Priority based FIC scheduler capable of >40 services --- src/ConfigParser.cpp | 5 +++++ src/DabMultiplexer.cpp | 32 ++++++++++++++++++++++++++++---- src/DabMultiplexer.h | 15 ++++++++++++++- src/MuxElements.h | 2 ++ src/utils.cpp | 3 +++ 5 files changed, 52 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 8f4052c..4e20dea 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -55,6 +55,7 @@ #include #include #include +#include "fig/FIGSchedulerType.h" using namespace std; using boost::property_tree::ptree; @@ -532,6 +533,10 @@ static void parse_general(ptree& pt, ensemble->reconfig_counter = pt_ensemble.get("reconfig-counter", ensemble->reconfig_counter); } + // FIG scheduler type selection + std::string fic_scheduler_str = pt_general.get("fic-scheduler", "classic"); + ensemble->fic_scheduler = FIC::parse_scheduler_type(fic_scheduler_str); + string lto_auto = pt_ensemble.get("local-time-offset", ""); if (lto_auto == "auto") { ensemble->lto_auto = true; diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index 7a8ac97..32ed2b3 100644 --- a/src/DabMultiplexer.cpp +++ b/src/DabMultiplexer.cpp @@ -158,8 +158,7 @@ DabMultiplexer::DabMultiplexer(DabMultiplexerConfig& config) : m_config(config), m_time(), ensemble(std::make_shared()), - m_clock_tai(split_pipe_separated_string(m_config.pt.get("general.tai_clock_bulletins", ""))), - fig_carousel(ensemble, [&]() { return m_time.get_milliseconds_seconds(); }) + m_clock_tai(split_pipe_separated_string(m_config.pt.get("general.tai_clock_bulletins", ""))) { RC_ADD_PARAMETER(frames, "Show number of frames generated [read-only]"); RC_ADD_PARAMETER(tist_offset, "Configured tist-offset"); @@ -185,6 +184,20 @@ void DabMultiplexer::prepare(bool require_tai_clock) { parse_ptree(m_config.pt, ensemble); + /* Create the appropriate FIG carousel based on config. + * This must happen after parse_ptree() which sets ensemble->fic_scheduler + */ + m_scheduler_type = ensemble->fic_scheduler; + auto time_func = [&]() { return m_time.get_milliseconds_seconds(); }; + + if (m_scheduler_type == FIC::FIGSchedulerType::Priority) { + etiLog.level(info) << "Using priority-based FIG scheduler"; + m_fig_carousel_priority.reset(new FIC::FIGCarouselPriority(ensemble, time_func)); + } else { + etiLog.level(info) << "Using classic FIG scheduler"; + m_fig_carousel_classic.reset(new FIC::FIGCarousel(ensemble, time_func)); + } + rcs.enrol(this); rcs.enrol(ensemble.get()); @@ -489,6 +502,17 @@ void DabMultiplexer::reload_linkagesets() } } +/* Helper method for FIG carousel write_fibs - abstracts the scheduler type */ +size_t DabMultiplexer::fig_carousel_write_fibs(uint8_t* buf, uint64_t current_frame, bool fib3_present) +{ + if (m_fig_carousel_priority) { + return m_fig_carousel_priority->write_fibs(buf, current_frame, fib3_present); + } else if (m_fig_carousel_classic) { + return m_fig_carousel_classic->write_fibs(buf, current_frame, fib3_present); + } + return 0; +} + /* Each call creates one ETI frame */ void DabMultiplexer::mux_frame(std::vector >& outputs) { @@ -709,9 +733,9 @@ void DabMultiplexer::mux_frame(std::vector >& outputs edi_tagDETI.fic_data = &etiFrame[index]; edi_tagDETI.fic_length = FICL * 4; - // Insert all FIBs + // Insert all FIBs using the selected scheduler const bool fib3_present = (ensemble->transmission_mode == TransmissionMode_e::TM_III); - index += fig_carousel.write_fibs(&etiFrame[index], currentFrame, fib3_present); + index += fig_carousel_write_fibs(&etiFrame[index], currentFrame, fib3_present); /********************************************************************** ****** Input Data Reading ******************************************* diff --git a/src/DabMultiplexer.h b/src/DabMultiplexer.h index 620e65d..afb308f 100644 --- a/src/DabMultiplexer.h +++ b/src/DabMultiplexer.h @@ -32,6 +32,8 @@ #include "dabOutput/dabOutput.h" #include "edioutput/Transport.h" #include "fig/FIGCarousel.h" +#include "fig/FIGCarouselPriority.h" +#include "fig/FIGSchedulerType.h" #include "MuxElements.h" #include "RemoteControl.h" #include "ClockTAI.h" @@ -130,5 +132,16 @@ class DabMultiplexer : public RemoteControllable { bool m_tai_clock_required = false; ClockTAI m_clock_tai; - FIC::FIGCarousel fig_carousel; + /* FIG Carousel - supports classic and priority schedulers + * + * Only one of these will be instantiated based on config. + * The scheduler type is determined by ensemble->fic_scheduler + * which is set during config parsing in prepare(). + */ + FIC::FIGSchedulerType m_scheduler_type = FIC::FIGSchedulerType::Classic; + std::unique_ptr m_fig_carousel_classic; + std::unique_ptr m_fig_carousel_priority; + + /* Helper method for FIG carousel write_fibs */ + size_t fig_carousel_write_fibs(uint8_t* buf, uint64_t current_frame, bool fib3_present); }; diff --git a/src/MuxElements.h b/src/MuxElements.h index 8ba103f..ab05ce3 100644 --- a/src/MuxElements.h +++ b/src/MuxElements.h @@ -40,6 +40,7 @@ #include "dabOutput/dabOutput.h" #include "input/inputs.h" #include "RemoteControl.h" +#include "fig/FIGSchedulerType.h" // For FIGSchedulerType enum // Protection levels and bitrates for UEP. const unsigned char ProtectionLevelTable[64] = { @@ -410,6 +411,7 @@ class dabEnsemble : public RemoteControllable { std::vector > linkagesets; std::vector frequency_information; std::vector service_other_ensemble; + FIC::FIGSchedulerType fic_scheduler = FIC::FIGSchedulerType::Classic; vec_sp_sci sci_entries; }; diff --git a/src/utils.cpp b/src/utils.cpp index 7ea6293..127ba78 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -31,6 +31,7 @@ #include #include "utils.h" #include "fig/FIG0structs.h" +#include "fig/FIGSchedulerType.h" using namespace std; @@ -496,6 +497,8 @@ void printEnsemble(const shared_ptr& ensemble) break; } + etiLog.level(info) << " FIC sched: " << FIC::scheduler_type_to_string(ensemble->fic_scheduler); + if (ensemble->lto_auto) { time_t now = time(nullptr); struct tm ltime; -- cgit v1.2.3