RAVENNAKIT
Loading...
Searching...
No Matches
ravenna_sender.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2/*
3 * Project: RAVENNAKIT (RAVENNA / AES67 / ST2110-30 SDK)
4 * Copyright (c) 2024-2025 Sound on Digital
5 *
6 * This file is part of RAVENNAKIT.
7 *
8 * RAVENNAKIT is dual-licensed:
9 * 1) Under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version (the "AGPL License"); and
12 * 2) Under a commercial license from Sound on Digital, for customers who
13 * cannot (or do not wish to) comply with the AGPL License terms.
14 *
15 * If you obtained this file under the AGPL License, you may redistribute it
16 * and/or modify it under the terms of the AGPL License. See the LICENSE
17 * file in the project root for details.
18 *
19 * For commercial licensing, support, and other inquiries, please visit:
20 *
21 * https://ravennakit.com
22 *
23 */
24
25#pragma once
26
37
38#include <boost/uuid/uuid.hpp>
39
40namespace rav {
41
43 public:
46 static constexpr uint32_t k_buffer_num_packets = 30;
47
50 static constexpr uint32_t k_max_num_frames = 4096;
51
54
59 struct Destination {
61 boost::asio::ip::udp::endpoint endpoint {};
62 bool enabled {};
63
64 friend bool operator==(const Destination& lhs, const Destination& rhs) {
65 return std::tie(lhs.interface_by_rank, lhs.endpoint, lhs.enabled) == std::tie(rhs.interface_by_rank, rhs.endpoint, rhs.enabled);
66 }
67
68 friend bool operator!=(const Destination& lhs, const Destination& rhs) {
69 return !(lhs == rhs);
70 }
71 };
72
73 /*
74 * Defines the configuration for the sender.
75 */
77 std::string session_name;
78 std::vector<Destination> destinations;
79 uint8_t ttl {};
80 uint8_t payload_type {};
83 bool enabled {};
84 };
85
86 class Subscriber {
87 public:
88 virtual ~Subscriber() = default;
89
90 virtual void ravenna_sender_configuration_updated(const Id sender_id, const Configuration& configuration) {
91 std::ignore = sender_id;
92 std::ignore = configuration;
93 }
94 };
95
97 rtp::AudioSender& rtp_audio_sender, dnssd::Advertiser* advertiser, rtsp::Server& rtsp_server, ptp::Instance& ptp_instance, Id id,
98 uint32_t session_id, NetworkInterfaceConfig network_interface_config
99 );
100
101 ~RavennaSender() override;
102
103 RavennaSender(const RavennaSender& other) = delete;
104 RavennaSender& operator=(const RavennaSender& other) = delete;
105
106 RavennaSender(RavennaSender&& other) noexcept = delete;
107 RavennaSender& operator=(RavennaSender&& other) noexcept = delete;
108
112 [[nodiscard]] Id get_id() const;
113
117 [[nodiscard]] const boost::uuids::uuid& get_uuid() const;
118
122 [[nodiscard]] uint32_t get_session_id() const;
123
128 [[nodiscard]] tl::expected<void, std::string> set_configuration(Configuration config);
129
133 [[nodiscard]] const Configuration& get_configuration() const;
134
140 [[nodiscard]] bool subscribe(Subscriber* subscriber);
141
147 [[nodiscard]] bool unsubscribe(const Subscriber* subscriber);
148
153 void set_nmos_node(nmos::Node* nmos_node);
154
159 void set_nmos_device_id(const boost::uuids::uuid& device_id);
160
165 [[nodiscard]] float get_signaled_ptime() const;
166
170 [[nodiscard]] uint32_t get_framecount() const;
171
177
183
188 [[nodiscard]] tl::expected<sdp::SessionDescription, std::string> generate_sdp() const;
189
193 boost::json::object to_boost_json() const;
194
200 [[nodiscard]] tl::expected<void, std::string> restore_from_json(const boost::json::value& json);
201
205 [[nodiscard]] const nmos::SourceAudio& get_nmos_source() const;
206
210 [[nodiscard]] const nmos::FlowAudioRaw& get_nmos_flow() const;
211
215 [[nodiscard]] const nmos::Sender& get_nmos_sender() const;
216
217 // rtsp_server::handler overrides
218 void on_request(rtsp::Connection::RequestEvent event) const override;
219
220 // ptp::Instance::Subscriber overrides
221 void ptp_parent_changed(const ptp::ParentDs& parent) override;
222
223 private:
224 rtp::AudioSender& rtp_audio_sender_;
225 dnssd::Advertiser* advertiser_ {nullptr};
226 rtsp::Server& rtsp_server_;
227 ptp::Instance& ptp_instance_;
228 nmos::Node* nmos_node_ {nullptr};
229
230 Id id_;
231 uint32_t session_id_ {};
232 Configuration configuration_;
233 std::string rtsp_path_by_name_;
234 std::string rtsp_path_by_id_;
235 Id advertisement_id_;
236 int32_t clock_domain_ {};
237 ptp::ClockIdentity grandmaster_identity_;
238 NetworkInterfaceConfig network_interface_config_;
239
240 nmos::SourceAudio nmos_source_;
241 nmos::FlowAudioRaw nmos_flow_;
242 nmos::Sender nmos_sender_;
243
244 SubscriberList<Subscriber> subscribers_;
245 std::string status_message_;
246
250 void send_announce() const;
251 void update_nmos();
252 void update_advertisement();
253 void generate_auto_addresses_if_needed(bool notify_subscribers);
254 bool generate_auto_addresses_if_needed(std::vector<Destination>& destinations) const;
255 void restart_streaming() const;
256 tl::expected<void, rav::nmos::ApiError> handle_patch_request(const boost::json::value& patch_request);
257 void register_dnssd_session_advertisement();
258};
259
260void tag_invoke(const boost::json::value_from_tag&, boost::json::value& jv, const RavennaSender::Destination& destination);
261
262RavennaSender::Destination tag_invoke(const boost::json::value_to_tag<RavennaSender::Destination>&, const boost::json::value& jv);
263
264void tag_invoke(const boost::json::value_from_tag&, boost::json::value& jv, const RavennaSender::Configuration& config);
265
266RavennaSender::Configuration tag_invoke(const boost::json::value_to_tag<RavennaSender::Configuration>&, const boost::json::value& jv);
267
268} // namespace rav
A class which represents a unique identifier.
Definition id.hpp:38
virtual ~Subscriber()=default
virtual void ravenna_sender_configuration_updated(const Id sender_id, const Configuration &configuration)
bool subscribe(Subscriber *subscriber)
Subscribes to the sender.
RavennaSender & operator=(const RavennaSender &other)=delete
static constexpr uint32_t k_max_num_frames
The max number of frames to feed into the sender (using send_audio_data_realtime).
void on_request(rtsp::Connection::RequestEvent event) const override
Called when a request is received.
const Configuration & get_configuration() const
const nmos::SourceAudio & get_nmos_source() const
void set_advertiser(dnssd::Advertiser *advertiser)
Sets given advertiser, updating the advertisement where necessary.
tl::expected< void, std::string > set_configuration(Configuration config)
Updates the configuration of the sender.
RavennaSender(const RavennaSender &other)=delete
RavennaSender(rtp::AudioSender &rtp_audio_sender, dnssd::Advertiser *advertiser, rtsp::Server &rtsp_server, ptp::Instance &ptp_instance, Id id, uint32_t session_id, NetworkInterfaceConfig network_interface_config)
const boost::uuids::uuid & get_uuid() const
void set_nmos_device_id(const boost::uuids::uuid &device_id)
Sets the NMOS device ID for the receiver.
uint32_t get_session_id() const
void set_network_interface_config(NetworkInterfaceConfig network_interface_config)
Sets the network interface config for the receiver.
const nmos::FlowAudioRaw & get_nmos_flow() const
static constexpr auto k_supported_encodings
List of supported audio encodings for the sender.
~RavennaSender() override
uint32_t get_framecount() const
tl::expected< sdp::SessionDescription, std::string > generate_sdp() const
Generates and returns the SDP as string.
bool unsubscribe(const Subscriber *subscriber)
Unsubscribes from the sender.
static constexpr uint32_t k_buffer_num_packets
The number of packet buffers available for sending.
RavennaSender(RavennaSender &&other) noexcept=delete
float get_signaled_ptime() const
void ptp_parent_changed(const ptp::ParentDs &parent) override
Called when the parent of the PTP instance changes.
RavennaSender & operator=(RavennaSender &&other) noexcept=delete
void set_nmos_node(nmos::Node *nmos_node)
Sets the NMOS node for the receiver.
tl::expected< void, std::string > restore_from_json(const boost::json::value &json)
Restores the sender from a JSON representation.
boost::json::object to_boost_json() const
const nmos::Sender & get_nmos_sender() const
Represents packet time as specified in AES67-2023 Section 7.2.
Base class for all dnssd advertiser implementations.
Implements the NMOS node as defined in the NMOS specifications.
Definition nmos_node.hpp:55
Represents a PTP instance as defined in IEEE 1588-2019.
Baseclass for other classes which need to handle requests for specific paths.
Server for accepting RTSP connections.
void tag_invoke(const boost::json::value_from_tag &, boost::json::value &jv, const RavennaReceiver::Configuration &config)
std::vector< Destination > destinations
The destination of where a stream of packets should go.
friend bool operator==(const Destination &lhs, const Destination &rhs)
boost::asio::ip::udp::endpoint endpoint
friend bool operator!=(const Destination &lhs, const Destination &rhs)
Describes a sender.
Describes an audio source.
Represents the parent data set as described in IEEE1588-2019: 8.2.3.