#ifndef TGCALLS_CONTENT_NEGOTIATION_H #define TGCALLS_CONTENT_NEGOTIATION_H #include #include "pc/channel_manager.h" #include "pc/media_session.h" #include "pc/session_description.h" #include "p2p/base/transport_description_factory.h" #include "v2/Signaling.h" namespace tgcalls { class ContentNegotiationContext { public: struct NegotiationContents { uint32_t exchangeId = 0; std::vector contents; }; struct PendingOutgoingOffer { uint32_t exchangeId = 0; }; struct PendingOutgoingChannel { cricket::MediaDescriptionOptions description; uint32_t ssrc = 0; std::vector ssrcGroups; PendingOutgoingChannel(cricket::MediaDescriptionOptions &&description_) : description(std::move(description_)) { } }; struct OutgoingChannel { std::string id; signaling::MediaContent content; OutgoingChannel(std::string id_, signaling::MediaContent content_) : id(id_), content(content_) { } }; struct CoordinatedState { std::vector outgoingContents; std::vector incomingContents; }; public: ContentNegotiationContext(bool isOutgoing, rtc::UniqueRandomIdGenerator *uniqueRandomIdGenerator); ~ContentNegotiationContext(); void copyCodecsFromChannelManager(cricket::ChannelManager *channelManager, bool randomize); std::string addOutgoingChannel(signaling::MediaContent::Type mediaType); void removeOutgoingChannel(std::string const &id); std::unique_ptr getPendingOffer(); std::unique_ptr setRemoteNegotiationContent(std::unique_ptr &&remoteNegotiationContent); std::unique_ptr coordinatedState() const; absl::optional outgoingChannelSsrc(std::string const &id) const; private: std::string takeNextOutgoingChannelId(); std::unique_ptr currentSessionDescriptionFromCoordinatedState(); std::unique_ptr getAnswer(std::unique_ptr &&offer); void setAnswer(std::unique_ptr &&answer); private: bool _isOutgoing = false; rtc::UniqueRandomIdGenerator *_uniqueRandomIdGenerator = nullptr; std::unique_ptr _transportDescriptionFactory; std::unique_ptr _sessionDescriptionFactory; std::vector _channelIdOrder; std::vector _rtpAudioExtensions; std::vector _rtpVideoExtensions; std::vector _outgoingChannelDescriptions; bool _needNegotiation = false; std::vector _outgoingChannels; std::vector _incomingChannels; std::unique_ptr _pendingOutgoingOffer; int _nextOutgoingChannelId = 0; }; } // namespace tgcalls #endif