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/offer_messages.h" 17 #include "cast/streaming/sender.h" 18 #include "cast/streaming/sender_packet_router.h" 19 #include "cast/streaming/session_config.h" 20 #include "cast/streaming/session_messager.h" 21 #include "json/value.h" 22 #include "util/json/json_serialization.h" 23 24 namespace openscreen { 25 namespace cast { 26 27 namespace capture_recommendations { 28 struct Recommendations; 29 } 30 31 class Environment; 32 class Sender; 33 34 class SenderSession final { 35 public: 36 // Upon successful negotiation, a set of configured senders is constructed 37 // for handling audio and video. Note that either sender may be null. 38 struct ConfiguredSenders { 39 // In practice, we may have 0, 1, or 2 senders configured, depending 40 // on if the device supports audio and video, and if we were able to 41 // successfully negotiate a sender configuration. 42 43 // If the sender is audio- or video-only, either of the senders 44 // may be nullptr. However, in the majority of cases they will be populated. 45 Sender* audio_sender; 46 AudioCaptureConfig audio_config; 47 48 Sender* video_sender; 49 VideoCaptureConfig video_config; 50 }; 51 52 // The embedder should provide a client for handling the negotiation. 53 // When the negotiation is complete, the OnNegotiated callback is called. 54 class Client { 55 public: 56 // Called when a new set of senders has been negotiated. This may be 57 // called multiple times during a session, once for every time Negotiate() 58 // is called on the SenderSession object. The negotation call also includes 59 // capture recommendations that can be used by the sender to provide 60 // an optimal video stream for the receiver. 61 virtual void OnNegotiated( 62 const SenderSession* session, 63 ConfiguredSenders senders, 64 capture_recommendations::Recommendations capture_recommendations) = 0; 65 66 // Called whenever an error occurs. Ends the ongoing session, and the caller 67 // must call Negotiate() again if they wish to re-establish streaming. 68 virtual void OnError(const SenderSession* session, Error error) = 0; 69 70 protected: 71 virtual ~Client(); 72 }; 73 74 // The SenderSession assumes that the passed in client, environment, and 75 // message port persist for at least the lifetime of the SenderSession. If 76 // one of these classes needs to be reset, a new SenderSession should be 77 // created. 78 SenderSession(IPAddress remote_address, 79 Client* const client, 80 Environment* environment, 81 MessagePort* message_port); 82 SenderSession(const SenderSession&) = delete; 83 SenderSession(SenderSession&&) = delete; 84 SenderSession& operator=(const SenderSession&) = delete; 85 SenderSession& operator=(SenderSession&&) = delete; 86 ~SenderSession(); 87 88 // Starts an OFFER/ANSWER exchange with the already configured receiver 89 // over the message port. The caller should assume any configured senders 90 // become invalid when calling this method. 91 Error Negotiate(std::vector<AudioCaptureConfig> audio_configs, 92 std::vector<VideoCaptureConfig> video_configs); 93 94 private: 95 // We store the current negotiation, so that when we get an answer from the 96 // receiver we can line up the selected streams with the original 97 // configuration. 98 struct Negotiation { 99 Offer offer; 100 101 std::vector<AudioCaptureConfig> audio_configs; 102 std::vector<VideoCaptureConfig> video_configs; 103 }; 104 105 // Specific message type handler methods. 106 void OnAnswer(SessionMessager::Message message); 107 108 // Used by SpawnSenders to generate a sender for a specific stream. 109 std::unique_ptr<Sender> CreateSender(Ssrc receiver_ssrc, 110 const Stream& stream, 111 RtpPayloadType type); 112 113 // Helper methods for spawning specific senders from the Answer message. 114 void SpawnAudioSender(ConfiguredSenders* senders, 115 Ssrc receiver_ssrc, 116 int send_index, 117 int config_index); 118 void SpawnVideoSender(ConfiguredSenders* senders, 119 Ssrc receiver_ssrc, 120 int send_index, 121 int config_index); 122 123 // Spawn a set of configured senders from the currently stored negotiation. 124 ConfiguredSenders SpawnSenders(const Answer& answer); 125 126 // The sender ID of the Receiver for this session. 127 std::string receiver_sender_id_; 128 129 // The remote address of the receiver we are communicating with. Used 130 // for both TLS and UDP traffic. 131 const IPAddress remote_address_; 132 133 // The embedder is expected to provide us a client for notifications about 134 // negotiations and errors, a valid cast environment, and a messaging 135 // port for communicating to the Receiver over TLS. 136 Client* const client_; 137 Environment* const environment_; 138 SessionMessager messager_; 139 140 // The packet router used for messaging across all senders. 141 SenderPacketRouter packet_router_; 142 143 // Each negotiation has its own sequence number, and the receiver replies 144 // with the same sequence number that we send. Each message to the receiver 145 // advances our current sequence number. 146 int current_sequence_number_ = 0; 147 148 // The current negotiation. If present, we are expected an ANSWER from 149 // the receiver. If not present, any provided ANSWERS are rejected. 150 std::unique_ptr<Negotiation> current_negotiation_; 151 152 // If the negotiation has succeeded, we store the current audio and video 153 // senders used for this session. Either or both may be nullptr. 154 std::unique_ptr<Sender> current_audio_sender_; 155 std::unique_ptr<Sender> current_video_sender_; 156 }; // namespace cast 157 158 } // namespace cast 159 } // namespace openscreen 160 161 #endif // CAST_STREAMING_SENDER_SESSION_H_ 162