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