xref: /aosp_15_r20/external/openscreen/cast/streaming/sender_session.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CAST_STREAMING_SENDER_SESSION_H_
6 #define CAST_STREAMING_SENDER_SESSION_H_
7 
8 #include <memory>
9 #include <string>
10 #include <utility>
11 #include <vector>
12 
13 #include "cast/common/public/message_port.h"
14 #include "cast/streaming/answer_messages.h"
15 #include "cast/streaming/capture_configs.h"
16 #include "cast/streaming/capture_recommendations.h"
17 #include "cast/streaming/offer_messages.h"
18 #include "cast/streaming/remoting_capabilities.h"
19 #include "cast/streaming/rpc_messenger.h"
20 #include "cast/streaming/sender.h"
21 #include "cast/streaming/sender_packet_router.h"
22 #include "cast/streaming/session_config.h"
23 #include "cast/streaming/session_messenger.h"
24 #include "json/value.h"
25 #include "util/json/json_serialization.h"
26 
27 namespace openscreen {
28 namespace cast {
29 
30 class Environment;
31 class Sender;
32 
33 class SenderSession final {
34  public:
35   // Upon successful negotiation, a set of configured senders is constructed
36   // for handling audio and video. Note that either sender may be null.
37   struct ConfiguredSenders {
38     // In practice, we may have 0, 1, or 2 senders configured, depending
39     // on if the device supports audio and video, and if we were able to
40     // successfully negotiate a sender configuration.
41 
42     // If the sender is audio- or video-only, either of the senders
43     // may be nullptr. However, in the majority of cases they will be populated.
44     Sender* audio_sender = nullptr;
45     AudioCaptureConfig audio_config;
46 
47     Sender* video_sender = nullptr;
48     VideoCaptureConfig video_config;
49   };
50 
51   // This struct contains all of the information necessary to begin remoting
52   // after we receive the capabilities from the receiver.
53   struct RemotingNegotiation {
54     ConfiguredSenders senders;
55 
56     // The capabilities reported by the connected receiver. NOTE: SenderSession
57     // reports the capabilities as-is from the Receiver, so clients concerned
58     // about legacy devices, such as pre-1.27 Earth receivers should do
59     // a version check when using these capabilities to offer remoting.
60     RemotingCapabilities capabilities;
61   };
62 
63   // The embedder should provide a client for handling negotiation events.
64   // The client is required to implement a mirorring handler, and may choose
65   // to provide a remoting negotiation if it supports remoting.
66   // When the negotiation is complete, the appropriate |On*Negotiated| handler
67   // is called.
68   class Client {
69    public:
70     // Called when a new set of senders has been negotiated. This may be
71     // called multiple times during a session, once for every time Negotiate()
72     // is called on the SenderSession object. The negotiation call also includes
73     // capture recommendations that can be used by the sender to provide
74     // an optimal video stream for the receiver.
75     virtual void OnNegotiated(
76         const SenderSession* session,
77         ConfiguredSenders senders,
78         capture_recommendations::Recommendations capture_recommendations) = 0;
79 
80     // Called when a new set of remoting senders has been negotiated. Since
81     // remoting is an optional feature, the default behavior here is to leave
82     // this method unhandled.
OnRemotingNegotiated(const SenderSession * session,RemotingNegotiation negotiation)83     virtual void OnRemotingNegotiated(const SenderSession* session,
84                                       RemotingNegotiation negotiation) {}
85 
86     // Called whenever an error occurs. Ends the ongoing session, and the caller
87     // must call Negotiate() again if they wish to re-establish streaming.
88     virtual void OnError(const SenderSession* session, Error error) = 0;
89 
90    protected:
91     virtual ~Client();
92   };
93 
94   // The configuration information required to set up the session.
95   struct Configuration {
96     // The remote address of the receiver to connect to. NOTE: we do eventually
97     // set the remote endpoint on the |environment| object, but only after
98     // getting the port information from a successful ANSWER message.
99     IPAddress remote_address;
100 
101     // The client for notifying of successful negotiations and errors. Required.
102     Client* const client;
103 
104     // The cast environment used to access operating system resources, such
105     // as the UDP socket for RTP/RTCP messaging. Required.
106     Environment* environment;
107 
108     // The message port used to send streaming control protocol messages.
109     MessagePort* message_port;
110 
111     // The message source identifier (e.g. this sender).
112     std::string message_source_id;
113 
114     // The message destination identifier (e.g. the receiver we are connected
115     // to).
116     std::string message_destination_id;
117 
118     // Whether or not the android RTP value hack should be used (for legacy
119     // android devices). For more information, see https://crbug.com/631828.
120     bool use_android_rtp_hack = true;
121   };
122 
123   // The SenderSession assumes that the passed in client, environment, and
124   // message port persist for at least the lifetime of the SenderSession. If
125   // one of these classes needs to be reset, a new SenderSession should be
126   // created.
127   //
128   // |message_source_id| and |message_destination_id| are the local and remote
129   // ID, respectively, to use when sending or receiving control messages (e.g.,
130   // OFFERs or ANSWERs) over the |message_port|. |message_port|'s SetClient()
131   // method will be called.
132   explicit SenderSession(Configuration config);
133   SenderSession(const SenderSession&) = delete;
134   SenderSession(SenderSession&&) noexcept = delete;
135   SenderSession& operator=(const SenderSession&) = delete;
136   SenderSession& operator=(SenderSession&&) = delete;
137   ~SenderSession();
138 
139   // Starts a mirroring OFFER/ANSWER exchange with the already configured
140   // receiver over the message port. The caller should assume any configured
141   // senders become invalid when calling this method.
142   Error Negotiate(std::vector<AudioCaptureConfig> audio_configs,
143                   std::vector<VideoCaptureConfig> video_configs);
144 
145   // Remoting negotiation is actually very similar to mirroring negotiation--
146   // an OFFER/ANSWER exchange still occurs, however only one audio and video
147   // codec should be presented based on the encoding of the media element that
148   // should be remoted. Note: the codec fields in |audio_config| and
149   // |video_config| are ignored in favor of |kRemote|.
150   Error NegotiateRemoting(AudioCaptureConfig audio_config,
151                           VideoCaptureConfig video_config);
152 
153   // Get the current network usage (in bits per second). This includes all
154   // senders managed by this session, and is a best guess based on receiver
155   // feedback. Embedders may use this information to throttle capture devices.
156   int GetEstimatedNetworkBandwidth() const;
157 
158   // The RPC messenger for this session. NOTE: RPC messages may come at
159   // any time from the receiver, so subscriptions to RPC remoting messages
160   // should be done before calling |NegotiateRemoting|.
rpc_messenger()161   RpcMessenger* rpc_messenger() { return &rpc_messenger_; }
162 
163  private:
164   // We store the current negotiation, so that when we get an answer from the
165   // receiver we can line up the selected streams with the original
166   // configuration.
167   struct InProcessNegotiation {
168     // The offer, which should always be valid if we have an in process
169     // negotiation.
170     Offer offer;
171 
172     // The configs used to derive the offer.
173     std::vector<AudioCaptureConfig> audio_configs;
174     std::vector<VideoCaptureConfig> video_configs;
175 
176     // The answer message for this negotiation, which may be invalid if we
177     // haven't received an answer yet.
178     Answer answer;
179   };
180 
181   // The state of the session.
182   enum class State {
183     // Not sending content--may be in the middle of negotiation, or just
184     // waiting.
185     kIdle,
186 
187     // Currently mirroring content to a receiver.
188     kStreaming,
189 
190     // Currently remoting content to a receiver.
191     kRemoting
192   };
193 
194   // Reset the state and tear down the current negotiation/negotiated mirroring
195   // or remoting session. After reset, the SenderSession is still connected to
196   // the same |remote_address_|, and the |packet_router_| and sequence number
197   // will be unchanged.
198   void ResetState();
199 
200   // Uses the passed in configs and offer to send an OFFER/ANSWER negotiation
201   // and cache the new InProcessNavigation.
202   Error StartNegotiation(std::vector<AudioCaptureConfig> audio_configs,
203                          std::vector<VideoCaptureConfig> video_configs,
204                          Offer offer);
205 
206   // Specific message type handler methods.
207   void OnAnswer(ReceiverMessage message);
208   void OnCapabilitiesResponse(ReceiverMessage message);
209   void OnRpcMessage(ReceiverMessage message);
210   void HandleErrorMessage(ReceiverMessage message, const std::string& text);
211 
212   // Used by SpawnSenders to generate a sender for a specific stream.
213   std::unique_ptr<Sender> CreateSender(Ssrc receiver_ssrc,
214                                        const Stream& stream,
215                                        RtpPayloadType type);
216 
217   // Helper methods for spawning specific senders from the Answer message.
218   void SpawnAudioSender(ConfiguredSenders* senders,
219                         Ssrc receiver_ssrc,
220                         int send_index,
221                         int config_index);
222   void SpawnVideoSender(ConfiguredSenders* senders,
223                         Ssrc receiver_ssrc,
224                         int send_index,
225                         int config_index);
226 
227   // Spawn a set of configured senders from the currently stored negotiation.
228   ConfiguredSenders SpawnSenders(const Answer& answer);
229 
230   // Used by the RPC messenger to send outbound messages.
231   void SendRpcMessage(std::vector<uint8_t> message_body);
232 
233   // This session's configuration.
234   Configuration config_;
235 
236   // The session messenger, which uses the message port for sending control
237   // messages. For message formats, see
238   // cast/protocol/castv2/streaming_schema.json.
239   SenderSessionMessenger messenger_;
240 
241   // The RPC messenger, which uses the session messager for sending RPC messages
242   // and handles subscriptions to RPC messages.
243   RpcMessenger rpc_messenger_;
244 
245   // The packet router used for RTP/RTCP messaging across all senders.
246   SenderPacketRouter packet_router_;
247 
248   // Each negotiation has its own sequence number, and the receiver replies
249   // with the same sequence number that we send. Each message to the receiver
250   // advances our current sequence number.
251   int current_sequence_number_ = 0;
252 
253   // The current negotiation. If present, we are expected an ANSWER from
254   // the receiver. If not present, any provided ANSWERS are rejected.
255   std::unique_ptr<InProcessNegotiation> current_negotiation_;
256 
257   // The current state of the session. Note that the state is intentionally
258   // limited. |kStreaming| or |kRemoting| means that we are either starting
259   // a negotiation or actively sending to a receiver.
260   State state_ = State::kIdle;
261 
262   // If the negotiation has succeeded, we store the current audio and video
263   // senders used for this session. Either or both may be nullptr.
264   std::unique_ptr<Sender> current_audio_sender_;
265   std::unique_ptr<Sender> current_video_sender_;
266 };  // namespace cast
267 
268 }  // namespace cast
269 }  // namespace openscreen
270 
271 #endif  // CAST_STREAMING_SENDER_SESSION_H_
272