diff options
Diffstat (limited to 'src/DabMultiplexer.cpp')
-rw-r--r-- | src/DabMultiplexer.cpp | 96 |
1 files changed, 48 insertions, 48 deletions
diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index 9ff28a3..2bd8d74 100644 --- a/src/DabMultiplexer.cpp +++ b/src/DabMultiplexer.cpp @@ -134,24 +134,23 @@ void DabMultiplexer::prepare(bool require_tai_clock) throw MuxInitException(); } - /* TODO: - * In a SFN, when reconfiguring the ensemble, the multiplexer - * has to be restarted (odr-dabmux doesn't support reconfiguration). - * Ideally, we must be able to restart transmission s.t. the receiver - * synchronisation is preserved. + /* Ensure edi_time and TIST represent current time. Keep + * a granularity of 24ms, which corresponds to the + * duration of an ETI frame, to get nicer timestamps. */ using Sec = chrono::seconds; - const auto now = chrono::time_point_cast<Sec>(chrono::system_clock::now()); - - edi_time = chrono::system_clock::to_time_t(now); - - // We define that when the time is multiple of six seconds, the timestamp - // (PPS offset) is 0. This ensures consistency of TIST even across a - // mux restart + const auto now = chrono::system_clock::now(); + edi_time = chrono::system_clock::to_time_t(chrono::time_point_cast<Sec>(now)); + auto offset = now - chrono::time_point_cast<Sec>(now); + if (offset >= chrono::seconds(1)) { + throw std::logic_error("Invalid startup offset calculation for TIST! " + + to_string(chrono::duration_cast<chrono::milliseconds>(offset).count()) + + " ms"); + } timestamp = 0; - edi_time -= (edi_time % 6); - while (edi_time < chrono::system_clock::to_time_t(now)) { + while (offset >= chrono::milliseconds(24)) { increment_timestamp(); + offset -= chrono::milliseconds(24); } // Try to load offset once @@ -284,13 +283,13 @@ void DabMultiplexer::prepare_services_components() component->subchId, component->serviceId); throw MuxInitException(); } - if ((*subchannel)->type != subchannel_type_t::Packet) continue; - component->packet.id = cur_packetid++; + if ((*subchannel)->type == subchannel_type_t::Packet) { + component->packet.id = cur_packetid++; + } rcs.enrol(component.get()); } - } void DabMultiplexer::prepare_data_inputs() @@ -308,10 +307,8 @@ void DabMultiplexer::prepare_data_inputs() (*subchannel)->startAddress = (*(subchannel - 1))->startAddress + (*(subchannel - 1))->getSizeCu(); } - if ((*subchannel)->input->open((*subchannel)->inputUri) == -1) { - perror((*subchannel)->inputUri.c_str()); - throw MuxInitException(); - } + + (*subchannel)->input->open((*subchannel)->inputUri); // TODO Check errors int subch_bitrate = (*subchannel)->input->setBitrate( (*subchannel)->bitrate); @@ -376,12 +373,23 @@ void DabMultiplexer::mux_frame(std::vector<std::shared_ptr<DabOutput> >& outputs // For EDI, save ETI(LI) Management data into a TAG Item DETI edi::TagDETI edi_tagDETI; - edi::TagStarPTR edi_tagStarPtr; + edi::TagStarPTR edi_tagStarPtr("DETI"); map<DabSubchannel*, edi::TagESTn> edi_subchannelToTag; // The above Tag Items will be assembled into a TAG Packet edi::TagPacket edi_tagpacket(edi_conf.tagpacket_alignment); + const bool tist_enabled = m_pt.get("general.tist", false); + + int tai_utc_offset = 0; + if (tist_enabled and m_tai_clock_required) { + try { + tai_utc_offset = m_clock_tai.get_offset(); + } + catch (const std::runtime_error& e) { + etiLog.level(error) << "Could not get UTC-TAI offset for EDI timestamp"; + } + } update_dab_time(); // Initialise the ETI frame @@ -583,8 +591,9 @@ void DabMultiplexer::mux_frame(std::vector<std::shared_ptr<DabOutput> >& outputs edi::TagESTn& tag = edi_subchannelToTag[subchannel.get()]; int sizeSubchannel = subchannel->getSizeByte(); - int result = subchannel->input->readFrame( - &etiFrame[index], sizeSubchannel); + // no need to check enableTist because we always increment the timestamp + int result = subchannel->readFrame(&etiFrame[index], + sizeSubchannel, edi_time + m_tist_offset, tai_utc_offset, timestamp); if (result < 0) { etiLog.log(info, @@ -637,34 +646,25 @@ void DabMultiplexer::mux_frame(std::vector<std::shared_ptr<DabOutput> >& outputs edi_tagDETI.tsta = 0xffffff; } - const bool tist_enabled = m_pt.get("general.tist", false); - if (tist_enabled and m_tai_clock_required) { - try { - const auto tai_utc_offset = m_clock_tai.get_offset(); - edi_tagDETI.set_edi_time(edi_time + m_tist_offset, tai_utc_offset); - edi_tagDETI.atstf = true; - - for (auto output : outputs) { - shared_ptr<OutputMetadata> md_utco = - make_shared<OutputMetadataUTCO>(edi_tagDETI.utco); - output->setMetadata(md_utco); - - shared_ptr<OutputMetadata> md_edi_time = - make_shared<OutputMetadataEDITime>(edi_tagDETI.seconds); - output->setMetadata(md_edi_time); - - shared_ptr<OutputMetadata> md_dlfc = - make_shared<OutputMetadataDLFC>(currentFrame % 5000); - output->setMetadata(md_dlfc); - } - } - catch (const std::runtime_error& e) { - etiLog.level(error) << "Could not get UTC-TAI offset for EDI timestamp"; + edi_tagDETI.set_edi_time(edi_time + m_tist_offset, tai_utc_offset); + edi_tagDETI.atstf = true; + + for (auto output : outputs) { + shared_ptr<OutputMetadata> md_utco = + make_shared<OutputMetadataUTCO>(edi_tagDETI.utco); + output->setMetadata(md_utco); + + shared_ptr<OutputMetadata> md_edi_time = + make_shared<OutputMetadataEDITime>(edi_tagDETI.seconds); + output->setMetadata(md_edi_time); + + shared_ptr<OutputMetadata> md_dlfc = + make_shared<OutputMetadataDLFC>(currentFrame % 5000); + output->setMetadata(md_dlfc); } } - /* Coding of the TIST, according to ETS 300 799 Annex C Bit number b0(MSb)..b6 b7..b9 b10..b17 b18..b20 b21..b23(LSb) |