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