From 371090e7b93ef05b754399a0752b91c82ab59e61 Mon Sep 17 00:00:00 2001 From: Andrea Bondavalli Date: Thu, 4 Jun 2020 09:14:17 -0700 Subject: [PATCH] Changes to SessionManager class to handle notifications for source updates triggered when the PTP GMID clock changes or the driver sample rate changes. SessionManager allows the registration of source update observers and delivers via callbacks the above notifications. RTSP server modified to register to source update notifications and to send updates to clients via ANNOUNCE method. --- daemon/rtsp_server.cpp | 8 +++--- daemon/rtsp_server.hpp | 13 +++++++--- daemon/session_manager.cpp | 51 +++++++++++++++++++++++++++++++++----- daemon/session_manager.hpp | 7 +++++- 4 files changed, 65 insertions(+), 14 deletions(-) diff --git a/daemon/rtsp_server.cpp b/daemon/rtsp_server.cpp index 0d9df3f..3dbe06b 100644 --- a/daemon/rtsp_server.cpp +++ b/daemon/rtsp_server.cpp @@ -21,9 +21,9 @@ using boost::asio::ip::tcp; -bool RtspServer::add_source(uint8_t id, - const std::string& name, - const std::string& sdp) { +bool RtspServer::update_source(uint8_t id, + const std::string& name, + const std::string& sdp) { bool ret = false; BOOST_LOG_TRIVIAL(debug) << "rtsp_server:: added source " << name; std::lock_guard lock(mutex_); @@ -88,7 +88,7 @@ bool RtspSession::announce(uint8_t id, << sdp; BOOST_LOG_TRIVIAL(info) - << "rtsp_server:: " << "ANNOUNCE for source " << id << " sent to " + << "rtsp_server:: " << "ANNOUNCE for source " << name << " sent to " << socket_.remote_endpoint(); send_response(ss.str()); diff --git a/daemon/rtsp_server.hpp b/daemon/rtsp_server.hpp index 903ade3..c0c4239 100644 --- a/daemon/rtsp_server.hpp +++ b/daemon/rtsp_server.hpp @@ -101,7 +101,14 @@ class RtspServer { session_manager_->add_source_observer( SessionManager::ObserverType::add_source, - std::bind(&RtspServer::add_source, this, + std::bind(&RtspServer::update_source, this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3)); + + session_manager_->add_source_observer( + SessionManager::ObserverType::update_source, + std::bind(&RtspServer::update_source, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); @@ -117,8 +124,8 @@ class RtspServer { } private: - /* a new source has been added or updated */ - bool add_source(uint8_t id, const std::string& name, const std::string& sdp); + /* a source was updated */ + bool update_source(uint8_t id, const std::string& name, const std::string& sdp); void accept(); std::mutex mutex_; diff --git a/daemon/session_manager.cpp b/daemon/session_manager.cpp index 56986ea..0cd4f4f 100644 --- a/daemon/session_manager.cpp +++ b/daemon/session_manager.cpp @@ -428,6 +428,9 @@ void SessionManager::add_source_observer(ObserverType type, Observer cb) { case ObserverType::remove_source: remove_source_observers.push_back(cb); break; + case ObserverType::update_source: + update_source_observers.push_back(cb); + break; } } @@ -916,6 +919,20 @@ size_t SessionManager::process_sap() { return sdp_len_sum; } +void SessionManager::on_update_sources() { + // trigger sources SDP file update + std::shared_lock sources_lock(sources_mutex_); + for (auto const& [id, info]: sources_) { + for (auto cb : update_source_observers) { + cb(id, info.stream.m_cName, get_source_sdp_(id, info)); + } + } +} + +void SessionManager::on_ptp_status_locked() { + // set sample rate, this may require seconds + (void)driver_->set_sample_rate(driver_->get_current_sample_rate()); +} using namespace std::chrono; using second_t = duration >; @@ -927,6 +944,7 @@ bool SessionManager::worker() { auto ptp_timepoint = steady_clock::now(); int sap_interval = 1; int ptp_interval = 0; + uint32_t sample_rate = driver_->get_current_sample_rate(); sap_.set_multicast_interface(config_->get_ip_addr_str()); @@ -950,10 +968,16 @@ bool SessionManager::worker() { "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", pui64GMID[0], pui64GMID[1], pui64GMID[2], pui64GMID[3], pui64GMID[4], pui64GMID[5], pui64GMID[6], pui64GMID[7]); + + bool ptp_changed_gmid = false; + bool ptp_changed_to_locked = false; // update PTP clock status - std::unique_lock ptp_lock(ptp_mutex_); + ptp_mutex_.lock(); // update status - ptp_status_.gmid = ptp_clock_id; + if (ptp_status_.gmid != ptp_clock_id) { + ptp_status_.gmid = ptp_clock_id; + ptp_changed_gmid = true; + } ptp_status_.jitter = ptp_status.i32Jitter; std::string new_ptp_status; switch (ptp_status.nPTPLockStatus) { @@ -967,15 +991,30 @@ bool SessionManager::worker() { new_ptp_status = "locked"; break; } + if (ptp_status_.status != new_ptp_status) { BOOST_LOG_TRIVIAL(info) << "session_manager:: new PTP clock status " << new_ptp_status; ptp_status_.status = new_ptp_status; if (new_ptp_status == "locked") { - // set sample rate, this may require seconds - (void)driver_->set_sample_rate(driver_->get_current_sample_rate()); - } - } + ptp_changed_to_locked = true; + } + } + // end update PTP clock status + ptp_mutex_.unlock(); + + + if (ptp_changed_to_locked) { + on_ptp_status_locked(); + } + + if (ptp_changed_gmid || + sample_rate != driver_->get_current_sample_rate()) { + /* master clock id changed or sample rate changed + * we need to update all the sources */ + sample_rate = driver_->get_current_sample_rate(); + on_update_sources(); + } } ptp_interval = 10; } diff --git a/daemon/session_manager.hpp b/daemon/session_manager.hpp index 11c88c2..0e7b944 100644 --- a/daemon/session_manager.hpp +++ b/daemon/session_manager.hpp @@ -134,7 +134,7 @@ class SessionManager { std::error_code remove_source(uint32_t id); uint8_t get_source_id(const std::string& name) const; - enum class ObserverType { add_source, remove_source }; + enum class ObserverType{ add_source, remove_source, update_source }; using Observer = std::function; void add_source_observer(ObserverType type, Observer cb); @@ -165,6 +165,10 @@ class SessionManager { void on_add_sink(const StreamSink& sink, const StreamInfo& info); void on_remove_sink(const StreamInfo& info); + void on_ptp_status_locked(); + + void on_update_sources(); + std::string get_removed_source_sdp_(uint32_t id, uint32_t src_addr) const; std::string get_source_sdp_(uint32_t id, const StreamInfo& info) const; StreamSource get_source_(uint8_t id, const StreamInfo& info) const; @@ -209,6 +213,7 @@ class SessionManager { std::list add_source_observers; std::list remove_source_observers; + std::list update_source_observers; SAP sap_{config_->get_sap_mcast_addr()}; IGMP igmp_;