1 // PHZ 2 // 2018-6-8 3 4 #ifndef XOP_MEDIA_SESSION_H 5 #define XOP_MEDIA_SESSION_H 6 7 #include <memory> 8 #include <string> 9 #include <vector> 10 #include <mutex> 11 #include <atomic> 12 #include <random> 13 #include <cstdint> 14 #include <unordered_set> 15 #include "media.h" 16 #include "H264Source.h" 17 #include "H265Source.h" 18 #include "G711ASource.h" 19 #include "AACSource.h" 20 #include "MediaSource.h" 21 #include "net/Socket.h" 22 #include "net/RingBuffer.h" 23 24 namespace xop 25 { 26 27 class RtpConnection; 28 29 class MediaSession 30 { 31 public: 32 using Ptr = std::shared_ptr<MediaSession>; 33 using NotifyConnectedCallback = std::function<void (MediaSessionId sessionId, const std::string &peer_ip, uint16_t peer_port)> ; 34 using NotifyDisconnectedCallback = std::function<void (MediaSessionId sessionId, const std::string &peer_ip, uint16_t peer_port)> ; 35 36 static MediaSession* CreateNew(std::string url_suffix="live"); 37 virtual ~MediaSession(); 38 39 bool AddSource(MediaChannelId channel_id, MediaSource* source); 40 bool RemoveSource(MediaChannelId channel_id); 41 42 bool StartMulticast(); 43 44 void AddNotifyConnectedCallback(const NotifyConnectedCallback& callback); 45 void AddNotifyDisconnectedCallback(const NotifyDisconnectedCallback& callback); 46 GetRtspUrlSuffix()47 std::string GetRtspUrlSuffix() const 48 { return suffix_; } 49 SetRtspUrlSuffix(std::string & suffix)50 void SetRtspUrlSuffix(std::string& suffix) 51 { suffix_ = suffix; } 52 53 std::string GetSdpMessage(std::string ip, std::string session_name =""); 54 55 MediaSource* GetMediaSource(MediaChannelId channel_id); 56 57 bool HandleFrame(MediaChannelId channel_id, AVFrame frame); 58 59 bool AddClient(SOCKET rtspfd, std::shared_ptr<RtpConnection> rtp_conn); 60 void RemoveClient(SOCKET rtspfd); 61 GetMediaSessionId()62 MediaSessionId GetMediaSessionId() 63 { return session_id_; } 64 GetNumClient()65 uint32_t GetNumClient() const 66 { return (uint32_t)clients_.size(); } 67 IsMulticast()68 bool IsMulticast() const 69 { return is_multicast_; } 70 GetMulticastIp()71 std::string GetMulticastIp() const 72 { return multicast_ip_; } 73 GetMulticastPort(MediaChannelId channel_id)74 uint16_t GetMulticastPort(MediaChannelId channel_id) const 75 { 76 if (channel_id >= MediaChannelId(MAX_MEDIA_CHANNEL)) { 77 return 0; 78 } 79 return multicast_port_[channel_id]; 80 } 81 82 private: 83 friend class MediaSource; 84 friend class RtspServer; 85 MediaSession(std::string url_suffxx); 86 87 MediaSessionId session_id_ = 0; 88 std::string suffix_; 89 std::string sdp_; 90 91 std::vector<std::unique_ptr<MediaSource>> media_sources_; 92 std::vector<RingBuffer<AVFrame>> buffer_; 93 94 std::vector<NotifyConnectedCallback> notify_connected_callbacks_; 95 std::vector<NotifyDisconnectedCallback> notify_disconnected_callbacks_; 96 std::mutex mutex_; 97 std::mutex map_mutex_; 98 std::map<SOCKET, std::weak_ptr<RtpConnection>> clients_; 99 100 bool is_multicast_ = false; 101 uint16_t multicast_port_[MAX_MEDIA_CHANNEL]; 102 std::string multicast_ip_; 103 std::atomic_bool has_new_client_; 104 105 static std::atomic_uint last_session_id_; 106 }; 107 108 class MulticastAddr 109 { 110 public: instance()111 static MulticastAddr& instance() 112 { 113 static MulticastAddr s_multi_addr; 114 return s_multi_addr; 115 } 116 GetAddr()117 std::string GetAddr() 118 { 119 std::lock_guard<std::mutex> lock(mutex_); 120 std::string addr_str; 121 struct sockaddr_in addr = {}; 122 std::random_device rd; 123 124 for (int n = 0; n <= 10; n++) { 125 uint32_t range = 0xE8FFFFFF - 0xE8000100; 126 addr.sin_addr.s_addr = htonl(0xE8000100 + (rd()) % range); 127 addr_str = inet_ntoa(addr.sin_addr); 128 129 if (addrs_.find(addr_str) != addrs_.end()) { 130 addr_str.clear(); 131 } 132 else { 133 addrs_.insert(addr_str); 134 break; 135 } 136 } 137 138 return addr_str; 139 } 140 Release(std::string addr)141 void Release(std::string addr) { 142 std::lock_guard<std::mutex> lock(mutex_); 143 addrs_.erase(addr); 144 } 145 146 private: 147 std::mutex mutex_; 148 std::unordered_set<std::string> addrs_; 149 }; 150 151 } 152 153 #endif 154