1 // Copyright 2019 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_RECEIVER_SESSION_H_ 6 #define CAST_STREAMING_RECEIVER_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/capture_configs.h" 15 #include "cast/streaming/constants.h" 16 #include "cast/streaming/offer_messages.h" 17 #include "cast/streaming/receiver_packet_router.h" 18 #include "cast/streaming/resolution.h" 19 #include "cast/streaming/rpc_messenger.h" 20 #include "cast/streaming/sender_message.h" 21 #include "cast/streaming/session_config.h" 22 #include "cast/streaming/session_messenger.h" 23 24 namespace openscreen { 25 namespace cast { 26 27 class Environment; 28 class Receiver; 29 30 // This class is responsible for listening for streaming requests from Cast 31 // Sender devices, then negotiating capture constraints and instantiating audio 32 // and video Receiver objects. 33 // The owner of this session is expected to provide a client for 34 // updates, an environment for getting UDP socket information (as well as 35 // other OS dependencies), and a set of preferences to be used for 36 // negotiation. 37 // 38 // NOTE: In some cases, the session initialization may be pending waiting for 39 // the UDP socket to be ready. In this case, the receivers and the answer 40 // message will not be configured and sent until the UDP socket has finished 41 // binding. 42 class ReceiverSession final : public Environment::SocketSubscriber { 43 public: 44 // Upon successful negotiation, a set of configured receivers is constructed 45 // for handling audio and video. Note that either receiver may be null. 46 struct ConfiguredReceivers { 47 // In practice, we may have 0, 1, or 2 receivers configured, depending 48 // on if the device supports audio and video, and if we were able to 49 // successfully negotiate a receiver configuration. 50 51 // NOTES ON LIFETIMES: The audio and video Receiver pointers are owned by 52 // ReceiverSession, not the Client, and references to these pointers must be 53 // cleared before a call to Client::OnReceiversDestroying() returns. 54 55 // If the receiver is audio- or video-only, or we failed to negotiate 56 // an acceptable session configuration with the sender, then either of the 57 // receivers may be nullptr. In this case, the associated config is default 58 // initialized and should be ignored. 59 Receiver* audio_receiver; 60 AudioCaptureConfig audio_config; 61 62 Receiver* video_receiver; 63 VideoCaptureConfig video_config; 64 }; 65 66 // This struct contains all of the information necessary to begin remoting 67 // once we get a remoting request from a Sender. 68 struct RemotingNegotiation { 69 // The configured receivers set to be used for handling audio and 70 // video streams. Unlike in the general streaming case, when we are remoting 71 // we don't know the codec and other information about the stream until 72 // the sender provices that information through the 73 // DemuxerStreamInitializeCallback RPC method. 74 ConfiguredReceivers receivers; 75 76 // The RPC messenger to be used for subscribing to remoting proto messages. 77 // Unlike the SenderSession API, the RPC messenger is negotiation specific. 78 // The messenger is torn down when |OnReceiversDestroying| is called, and 79 // is owned by the ReceiverSession. 80 RpcMessenger* messenger; 81 }; 82 83 // The embedder should provide a client for handling connections. 84 // When a connection is established, the OnNegotiated callback is called. 85 class Client { 86 public: 87 // Currently we only care about the session ending or being renegotiated, 88 // which means that we don't have to tear down as much state. 89 enum ReceiversDestroyingReason { kEndOfSession, kRenegotiated }; 90 91 // Called when a set of streaming receivers has been negotiated. Both this 92 // and |OnRemotingNegotiated| may be called repeatedly as negotiations occur 93 // through the life of a session. 94 virtual void OnNegotiated(const ReceiverSession* session, 95 ConfiguredReceivers receivers) = 0; 96 97 // Called when a set of remoting receivers has been negotiated. This will 98 // only be called if |RemotingPreferences| are provided as part of 99 // constructing the ReceiverSession object. OnRemotingNegotiated(const ReceiverSession * session,RemotingNegotiation negotiation)100 virtual void OnRemotingNegotiated(const ReceiverSession* session, 101 RemotingNegotiation negotiation) {} 102 103 // Called immediately preceding the destruction of this session's receivers. 104 // If |reason| is |kEndOfSession|, OnNegotiated() will never be called 105 // again; if it is |kRenegotiated|, OnNegotiated() will be called again 106 // soon with a new set of Receivers to use. 107 // 108 // Before returning, the implementation must ensure that all references to 109 // the Receivers, from the last call to OnNegotiated(), have been cleared. 110 virtual void OnReceiversDestroying(const ReceiverSession* session, 111 ReceiversDestroyingReason reason) = 0; 112 113 // Called whenever an error that the client may care about occurs. 114 // Recoverable errors are usually logged by the receiver session instead 115 // of reported here. 116 virtual void OnError(const ReceiverSession* session, Error error) = 0; 117 118 // Called to verify whether a given codec parameter is supported by 119 // this client. If not overriden, this always assumes true. 120 // This method is used only for secondary matching, e.g. 121 // if you don't add VideoCodec::kHevc to the VideoCaptureConfig, then 122 // supporting codec parameter "hev1.1.6.L153.B0" does not matter. 123 // 124 // The codec parameter support callback is optional, however if provided 125 // then any offered streams that have a non-empty codec parameter field must 126 // match. If a stream does not have a codec parameter, this callback will 127 // not be called. SupportsCodecParameter(const std::string & parameter)128 virtual bool SupportsCodecParameter(const std::string& parameter) { 129 return true; 130 } 131 132 protected: 133 virtual ~Client(); 134 }; 135 136 // Information about the display the receiver is attached to. 137 struct Display { 138 // Returns true if all configurations supported by |other| are also 139 // supported by this instance. 140 bool IsSupersetOf(const Display& other) const; 141 142 // The display limitations of the actual screen, used to provide upper 143 // bounds on streams. For example, we will never 144 // send 60FPS if it is going to be displayed on a 30FPS screen. 145 // Note that we may exceed the display width and height for standard 146 // content sizes like 720p or 1080p. 147 Dimensions dimensions; 148 149 // Whether the embedder is capable of scaling content. If set to false, 150 // the sender will manage the aspect ratio scaling. 151 bool can_scale_content = false; 152 }; 153 154 // Codec-specific audio limits for playback. 155 struct AudioLimits { 156 // Returns true if all configurations supported by |other| are also 157 // supported by this instance. 158 bool IsSupersetOf(const AudioLimits& other) const; 159 160 // Whether or not these limits apply to all codecs. 161 bool applies_to_all_codecs = false; 162 163 // Audio codec these limits apply to. Note that if |applies_to_all_codecs| 164 // is true this field is ignored. 165 AudioCodec codec; 166 167 // Maximum audio sample rate. 168 int max_sample_rate = kDefaultAudioSampleRate; 169 170 // Maximum audio channels, default is currently stereo. 171 int max_channels = kDefaultAudioChannels; 172 173 // Minimum and maximum bitrates. Generally capture is done at the maximum 174 // bit rate, since audio bandwidth is much lower than video for most 175 // content. 176 int min_bit_rate = kDefaultAudioMinBitRate; 177 int max_bit_rate = kDefaultAudioMaxBitRate; 178 179 // Max playout delay in milliseconds. 180 std::chrono::milliseconds max_delay = kDefaultMaxDelayMs; 181 }; 182 183 // Codec-specific video limits for playback. 184 struct VideoLimits { 185 // Returns true if all configurations supported by |other| are also 186 // supported by this instance. 187 bool IsSupersetOf(const VideoLimits& other) const; 188 189 // Whether or not these limits apply to all codecs. 190 bool applies_to_all_codecs = false; 191 192 // Video codec these limits apply to. Note that if |applies_to_all_codecs| 193 // is true this field is ignored. 194 VideoCodec codec; 195 196 // Maximum pixels per second. Value is the standard amount of pixels 197 // for 1080P at 30FPS. 198 int max_pixels_per_second = 1920 * 1080 * 30; 199 200 // Maximum dimensions. Minimum dimensions try to use the same aspect 201 // ratio and are generated from the spec. 202 Dimensions max_dimensions = {1920, 1080, {kDefaultFrameRate, 1}}; 203 204 // Minimum and maximum bitrates. Default values are based on default min and 205 // max dimensions, embedders that support different display dimensions 206 // should strongly consider setting these fields. 207 int min_bit_rate = kDefaultVideoMinBitRate; 208 int max_bit_rate = kDefaultVideoMaxBitRate; 209 210 // Max playout delay in milliseconds. 211 std::chrono::milliseconds max_delay = kDefaultMaxDelayMs; 212 }; 213 214 // This struct is used to provide preferences for setting up and running 215 // remoting streams. These properties are based on the current control 216 // protocol and allow remoting with current senders. 217 struct RemotingPreferences { 218 // Returns true if all configurations supported by |other| are also 219 // supported by this instance. 220 bool IsSupersetOf(const RemotingPreferences& other) const; 221 222 // Current remoting senders take an "all or nothing" support for audio 223 // codec support. While Opus and AAC support is handled in our Preferences' 224 // |audio_codecs| property, support for the following codecs must be 225 // enabled or disabled all together: 226 // MP3 227 // PCM, including Mu-Law, S16BE, S24BE, and ALAW variants 228 // Ogg Vorbis 229 // FLAC 230 // AMR, including narrow band (NB) and wide band (WB) variants 231 // GSM Mobile Station (MS) 232 // EAC3 (Dolby Digital Plus) 233 // ALAC (Apple Lossless) 234 // AC-3 (Dolby Digital) 235 // These properties are tied directly to what Chrome supports. See: 236 // https://source.chromium.org/chromium/chromium/src/+/master:media/base/audio_codecs.h 237 bool supports_chrome_audio_codecs = false; 238 239 // Current remoting senders assume that the receiver supports 4K for all 240 // video codecs supplied in |video_codecs|, or none of them. 241 bool supports_4k = false; 242 }; 243 244 // Note: embedders are required to implement the following 245 // codecs to be Cast V2 compliant: H264, VP8, AAC, Opus. 246 struct Preferences { 247 Preferences(); 248 Preferences(std::vector<VideoCodec> video_codecs, 249 std::vector<AudioCodec> audio_codecs); 250 Preferences(std::vector<VideoCodec> video_codecs, 251 std::vector<AudioCodec> audio_codecs, 252 std::vector<AudioLimits> audio_limits, 253 std::vector<VideoLimits> video_limits, 254 std::unique_ptr<Display> description); 255 256 Preferences(Preferences&&) noexcept; 257 Preferences(const Preferences&); 258 Preferences& operator=(Preferences&&) noexcept; 259 Preferences& operator=(const Preferences&); 260 261 // Returns true if all configurations supported by |other| are also 262 // supported by this instance. 263 bool IsSupersetOf(const Preferences& other) const; 264 265 // Audio and video codec preferences. Should be supplied in order of 266 // preference, e.g. in this example if we get both VP8 and H264 we will 267 // generally select the VP8 offer. If a codec is omitted from these fields 268 // it will never be selected in the OFFER/ANSWER negotiation. 269 std::vector<VideoCodec> video_codecs{VideoCodec::kVp8, VideoCodec::kH264}; 270 std::vector<AudioCodec> audio_codecs{AudioCodec::kOpus, AudioCodec::kAac}; 271 272 // Optional limitation fields that help the sender provide a delightful 273 // cast experience. Although optional, highly recommended. 274 // NOTE: embedders that wish to apply the same limits for all codecs can 275 // pass a vector of size 1 with the |applies_to_all_codecs| field set to 276 // true. 277 std::vector<AudioLimits> audio_limits; 278 std::vector<VideoLimits> video_limits; 279 std::unique_ptr<Display> display_description; 280 281 // Libcast remoting support is opt-in: embedders wishing to field remoting 282 // offers may provide a set of remoting preferences, or leave nullptr for 283 // all remoting OFFERs to be rejected in favor of continuing streaming. 284 std::unique_ptr<RemotingPreferences> remoting; 285 }; 286 287 ReceiverSession(Client* const client, 288 Environment* environment, 289 MessagePort* message_port, 290 Preferences preferences); 291 ReceiverSession(const ReceiverSession&) = delete; 292 ReceiverSession(ReceiverSession&&) noexcept = delete; 293 ReceiverSession& operator=(const ReceiverSession&) = delete; 294 ReceiverSession& operator=(ReceiverSession&&) = delete; 295 ~ReceiverSession(); 296 session_id()297 const std::string& session_id() const { return session_id_; } 298 299 // Environment::SocketSubscriber event callbacks. 300 void OnSocketReady() override; 301 void OnSocketInvalid(Error error) override; 302 303 private: 304 // In some cases, such as waiting for the UDP socket to be bound, we 305 // may have a pending session that cannot start yet. This class provides 306 // all necessary info to instantiate a session. 307 struct SessionProperties { 308 // The cast mode the OFFER was sent for. 309 CastMode mode; 310 311 // The selected audio and video streams from the original OFFER message. 312 std::unique_ptr<AudioStream> selected_audio; 313 std::unique_ptr<VideoStream> selected_video; 314 315 // The sequence number of the OFFER that produced these properties. 316 int sequence_number; 317 318 // To be valid either the audio or video must be selected, and we must 319 // have a sequence number we can reference. 320 bool IsValid() const; 321 }; 322 323 // Specific message type handler methods. 324 void OnOffer(SenderMessage message); 325 void OnCapabilitiesRequest(SenderMessage message); 326 void OnRpcMessage(SenderMessage message); 327 328 // Selects streams from an offer based on its configuration, and sets 329 // them in the session properties. 330 void SelectStreams(const Offer& offer, SessionProperties* properties); 331 332 // Creates receivers and sends an appropriate Answer message using the 333 // session properties. 334 void InitializeSession(const SessionProperties& properties); 335 336 // Used by SpawnReceivers to generate a receiver for a specific stream. 337 std::unique_ptr<Receiver> ConstructReceiver(const Stream& stream); 338 339 // Creates a set of configured receivers from a given pair of audio and 340 // video streams. NOTE: either audio or video may be null, but not both. 341 ConfiguredReceivers SpawnReceivers(const SessionProperties& properties); 342 343 // Creates an ANSWER object. Assumes at least one stream is not nullptr. 344 Answer ConstructAnswer(const SessionProperties& properties); 345 346 // Creates a ReceiverCapability version 2 object. This will be deprecated 347 // as part of https://issuetracker.google.com/184429130. 348 ReceiverCapability CreateRemotingCapabilityV2(); 349 350 // Handles resetting receivers and notifying the client. 351 void ResetReceivers(Client::ReceiversDestroyingReason reason); 352 353 // Sends an error answer reply and notifies the client of the error. 354 void SendErrorAnswerReply(int sequence_number, const char* message); 355 356 Client* const client_; 357 Environment* const environment_; 358 const Preferences preferences_; 359 360 // The sender_id of this session. 361 const std::string session_id_; 362 363 // The session messenger used for the lifetime of this session. 364 ReceiverSessionMessenger messenger_; 365 366 // The packet router to be used for all Receivers spawned by this session. 367 ReceiverPacketRouter packet_router_; 368 369 // Any session pending while the UDP socket is being bound. 370 std::unique_ptr<SessionProperties> pending_session_; 371 372 // The negotiated receivers we own, clients are notified of destruction 373 // through |Client::OnReceiversDestroying|. 374 std::unique_ptr<Receiver> current_audio_receiver_; 375 std::unique_ptr<Receiver> current_video_receiver_; 376 377 // If remoting, we store the RpcMessenger used by the embedder to send RPC 378 // messages from the remoting protobuf specification. 379 std::unique_ptr<RpcMessenger> rpc_messenger_; 380 }; 381 382 } // namespace cast 383 } // namespace openscreen 384 385 #endif // CAST_STREAMING_RECEIVER_SESSION_H_ 386