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/answer_messages.h" 15 #include "cast/streaming/capture_configs.h" 16 #include "cast/streaming/offer_messages.h" 17 #include "cast/streaming/receiver_packet_router.h" 18 #include "cast/streaming/sender_message.h" 19 #include "cast/streaming/session_config.h" 20 #include "cast/streaming/session_messager.h" 21 #include "util/json/json_serialization.h" 22 23 namespace openscreen { 24 namespace cast { 25 26 class Environment; 27 class Receiver; 28 29 class ReceiverSession final : public Environment::SocketSubscriber { 30 public: 31 // Upon successful negotiation, a set of configured receivers is constructed 32 // for handling audio and video. Note that either receiver may be null. 33 struct ConfiguredReceivers { 34 // In practice, we may have 0, 1, or 2 receivers configured, depending 35 // on if the device supports audio and video, and if we were able to 36 // successfully negotiate a receiver configuration. 37 38 // NOTES ON LIFETIMES: The audio and video Receiver pointers are owned by 39 // ReceiverSession, not the Client, and references to these pointers must be 40 // cleared before a call to Client::OnReceiversDestroying() returns. 41 42 // If the receiver is audio- or video-only, or we failed to negotiate 43 // an acceptable session configuration with the sender, then either of the 44 // receivers may be nullptr. In this case, the associated config is default 45 // initialized and should be ignored. 46 Receiver* audio_receiver; 47 AudioCaptureConfig audio_config; 48 49 Receiver* video_receiver; 50 VideoCaptureConfig video_config; 51 }; 52 53 // The embedder should provide a client for handling connections. 54 // When a connection is established, the OnMirroringNegotiated callback is 55 // called. 56 class Client { 57 public: 58 enum ReceiversDestroyingReason { kEndOfSession, kRenegotiated }; 59 60 // Called when a new set of receivers has been negotiated. This may be 61 // called multiple times during a session, as renegotiations occur. 62 virtual void OnMirroringNegotiated(const ReceiverSession* session, 63 ConfiguredReceivers receivers) = 0; 64 65 // Called immediately preceding the destruction of this session's receivers. 66 // If |reason| is |kEndOfSession|, OnMirroringNegotiated() will never be 67 // called again; if it is |kRenegotiated|, OnMirroringNegotiated() will be 68 // called again soon with a new set of Receivers to use. 69 // 70 // Before returning, the implementation must ensure that all references to 71 // the Receivers, from the last call to OnMirroringNegotiated(), have been 72 // cleared. 73 virtual void OnReceiversDestroying(const ReceiverSession* session, 74 ReceiversDestroyingReason reason) = 0; 75 76 virtual void OnError(const ReceiverSession* session, Error error) = 0; 77 78 protected: 79 virtual ~Client(); 80 }; 81 82 // Note: embedders are required to implement the following 83 // codecs to be Cast V2 compliant: H264, VP8, AAC, Opus. 84 struct Preferences { 85 Preferences(); 86 Preferences(std::vector<VideoCodec> video_codecs, 87 std::vector<AudioCodec> audio_codecs); 88 Preferences(std::vector<VideoCodec> video_codecs, 89 std::vector<AudioCodec> audio_codecs, 90 std::unique_ptr<Constraints> constraints, 91 std::unique_ptr<DisplayDescription> description); 92 93 Preferences(Preferences&&) noexcept; 94 Preferences(const Preferences&) = delete; 95 Preferences& operator=(Preferences&&) noexcept; 96 Preferences& operator=(const Preferences&) = delete; 97 98 std::vector<VideoCodec> video_codecs{VideoCodec::kVp8, VideoCodec::kH264}; 99 std::vector<AudioCodec> audio_codecs{AudioCodec::kOpus, AudioCodec::kAac}; 100 101 // The embedder has the option of directly specifying the display 102 // information and video/audio constraints that will be passed along to 103 // senders during the offer/answer exchange. If nullptr, these are ignored. 104 std::unique_ptr<Constraints> constraints; 105 std::unique_ptr<DisplayDescription> display_description; 106 }; 107 108 ReceiverSession(Client* const client, 109 Environment* environment, 110 MessagePort* message_port, 111 Preferences preferences); 112 ReceiverSession(const ReceiverSession&) = delete; 113 ReceiverSession(ReceiverSession&&) noexcept = delete; 114 ReceiverSession& operator=(const ReceiverSession&) = delete; 115 ReceiverSession& operator=(ReceiverSession&&) = delete; 116 ~ReceiverSession(); 117 session_id()118 const std::string& session_id() const { return session_id_; } 119 120 // Environment::SocketSubscriber event callbacks. 121 void OnSocketReady() override; 122 void OnSocketInvalid(Error error) override; 123 124 private: 125 struct SessionProperties { 126 std::unique_ptr<AudioStream> selected_audio; 127 std::unique_ptr<VideoStream> selected_video; 128 int sequence_number; 129 130 // To be valid either the audio or video must be selected, and we must 131 // have a sequence number we can reference. 132 bool IsValid() const; 133 }; 134 135 // Specific message type handler methods. 136 void OnOffer(SenderMessage message); 137 138 // Creates receivers and sends an appropriate Answer message using the 139 // session properties. 140 void InitializeSession(const SessionProperties& properties); 141 142 // Used by SpawnReceivers to generate a receiver for a specific stream. 143 std::unique_ptr<Receiver> ConstructReceiver(const Stream& stream); 144 145 // Creates a set of configured receivers from a given pair of audio and 146 // video streams. NOTE: either audio or video may be null, but not both. 147 ConfiguredReceivers SpawnReceivers(const SessionProperties& properties); 148 149 // Callers of this method should ensure at least one stream is non-null. 150 Answer ConstructAnswer(const SessionProperties& properties); 151 152 // Handles resetting receivers and notifying the client. 153 void ResetReceivers(Client::ReceiversDestroyingReason reason); 154 155 // Sends an error answer reply and notifies the client of the error. 156 void SendErrorAnswerReply(int sequence_number, const char* message); 157 158 Client* const client_; 159 Environment* const environment_; 160 const Preferences preferences_; 161 // The sender_id of this session. 162 const std::string session_id_; 163 ReceiverSessionMessager messager_; 164 165 // In some cases, the session initialization may be pending waiting for the 166 // UDP socket to be ready. In this case, the receivers and the answer 167 // message will not be configured and sent until the UDP socket has finished 168 // binding. 169 std::unique_ptr<SessionProperties> pending_session_; 170 171 bool supports_wifi_status_reporting_ = false; 172 ReceiverPacketRouter packet_router_; 173 174 std::unique_ptr<Receiver> current_audio_receiver_; 175 std::unique_ptr<Receiver> current_video_receiver_; 176 }; 177 178 } // namespace cast 179 } // namespace openscreen 180 181 #endif // CAST_STREAMING_RECEIVER_SESSION_H_ 182