// PHZ // 2018-6-8 #ifndef XOP_MEDIA_SESSION_H #define XOP_MEDIA_SESSION_H #include #include #include #include #include #include #include #include #include "media.h" #include "H264Source.h" #include "H265Source.h" #include "VP8Source.h" #include "G711ASource.h" #include "AACSource.h" #include "MediaSource.h" #include "Socket.h" #include "RingBuffer.h" namespace xop { class RtpConnection; class MediaSession { public: using Ptr = std::shared_ptr; using NotifyConnectedCallback = std::function ; using NotifyDisconnectedCallback = std::function ; static MediaSession* CreateNew(std::string url_suffix="live"); virtual ~MediaSession(); bool AddSource(MediaChannelId channel_id, MediaSource* source); bool RemoveSource(MediaChannelId channel_id); bool StartMulticast(); void AddNotifyConnectedCallback(const NotifyConnectedCallback& callback); void AddNotifyDisconnectedCallback(const NotifyDisconnectedCallback& callback); std::string GetRtspUrlSuffix() const { return suffix_; } void SetRtspUrlSuffix(std::string& suffix) { suffix_ = suffix; } std::string GetSdpMessage(std::string ip, std::string session_name =""); MediaSource* GetMediaSource(MediaChannelId channel_id); bool HandleFrame(MediaChannelId channel_id, AVFrame frame); bool AddClient(SOCKET rtspfd, std::shared_ptr rtp_conn); void RemoveClient(SOCKET rtspfd); MediaSessionId GetMediaSessionId() { return session_id_; } uint32_t GetNumClient() const { return (uint32_t)clients_.size(); } bool IsMulticast() const { return is_multicast_; } std::string GetMulticastIp() const { return multicast_ip_; } uint16_t GetMulticastPort(MediaChannelId channel_id) const { if (channel_id >= MAX_MEDIA_CHANNEL) { return 0; } return multicast_port_[channel_id]; } private: friend class MediaSource; friend class RtspServer; MediaSession(std::string url_suffxx); MediaSessionId session_id_ = 0; std::string suffix_; std::string sdp_; std::vector> media_sources_; std::vector> buffer_; std::vector notify_connected_callbacks_; std::vector notify_disconnected_callbacks_; std::mutex mutex_; std::mutex map_mutex_; std::map> clients_; bool is_multicast_ = false; uint16_t multicast_port_[MAX_MEDIA_CHANNEL]; std::string multicast_ip_; std::atomic_bool has_new_client_; static std::atomic_uint last_session_id_; }; class MulticastAddr { public: static MulticastAddr& instance() { static MulticastAddr s_multi_addr; return s_multi_addr; } std::string GetAddr() { std::lock_guard lock(mutex_); std::string addr_str; struct sockaddr_in addr = { 0 }; std::random_device rd; for (int n = 0; n <= 10; n++) { uint32_t range = 0xE8FFFFFF - 0xE8000100; addr.sin_addr.s_addr = htonl(0xE8000100 + (rd()) % range); addr_str = inet_ntoa(addr.sin_addr); if (addrs_.find(addr_str) != addrs_.end()) { addr_str.clear(); } else { addrs_.insert(addr_str); break; } } return addr_str; } void Release(std::string addr) { std::lock_guard lock(mutex_); addrs_.erase(addr); } private: std::mutex mutex_; std::unordered_set addrs_; }; } #endif