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