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_;