uvgRTP
media_stream.hh
1 #pragma once
2 
3 #include <unordered_map>
4 #include <memory>
5 
6 #include "holepuncher.hh"
7 #include "pkt_dispatch.hh"
8 #include "rtcp.hh"
9 #include "socket.hh"
10 #include "srtp/srtcp.hh"
11 #include "srtp/srtp.hh"
12 #include "util.hh"
13 
14 #include "formats/media.hh"
15 
16 namespace uvgrtp {
17 
18  class media_stream {
19  public:
21  media_stream(std::string addr, int src_port, int dst_port, rtp_format_t fmt, int flags);
22  media_stream(std::string remote_addr, std::string local_addr, int src_port, int dst_port, rtp_format_t fmt, int flags);
23  ~media_stream();
24 
25  /* Initialize traditional RTP session
26  * Allocate Connection/Reader/Writer objects and initialize them
27  *
28  * Return RTP_OK on success
29  * Return RTP_MEMORY_ERROR if allocation failed
30  *
31  * Other error return codes are defined in {conn,writer,reader}.hh */
32  rtp_error_t init();
33 
34  /* Initialize Secure RTP session
35  * Allocate Connection/Reader/Writer objects and initialize them
36  *
37  * Return RTP_OK on success
38  * Return RTP_MEMORY_ERROR if allocation failed
39  *
40  * TODO document all error codes!
41  *
42  * Other error return codes are defined in {conn,writer,reader,srtp}.hh */
43  rtp_error_t init(uvgrtp::zrtp *zrtp);
45 
46  /* Add key for user-managed SRTP session
47  *
48  * For user-managed SRTP session, the media stream is not started
49  * until SRTP key has been added and all calls to push_frame() will fail
50  *
51  * Currently uvgRTP only supports key length of 16 bytes (128 bits)
52  * and salt length of 14 bytes (112 bits).
53  * If the key/salt is longer, it is implicitly truncated to correct length
54  * and if the key/salt is shorter a memory violation may occur
55  *
56  * Return RTP_OK on success
57  * Return RTP_INVALID_VALUE if "key" or "salt" is invalid
58  * Return RTP_NOT_SUPPORTED if user-managed SRTP was not specified in create_stream() */
59  rtp_error_t add_srtp_ctx(uint8_t *key, uint8_t *salt);
60 
84  rtp_error_t push_frame(uint8_t *data, size_t data_len, int flags);
85  rtp_error_t push_frame(uint8_t *data, size_t data_len, uint32_t ts, int flags);
86  rtp_error_t push_frame(std::unique_ptr<uint8_t[]> data, size_t data_len, int flags);
87  rtp_error_t push_frame(std::unique_ptr<uint8_t[]> data, size_t data_len, uint32_t ts, int flags);
88 
103  uvgrtp::frame::rtp_frame *pull_frame();
104 
119  uvgrtp::frame::rtp_frame *pull_frame(size_t timeout);
120 
130  rtp_error_t install_receive_hook(void *arg, void (*hook)(void *, uvgrtp::frame::rtp_frame *));
131 
133  /* If system call dispatcher is enabled and calling application has special requirements
134  * for the deallocation of a frame, it may install a deallocation hook which is called
135  * when SCD has processed the frame
136  *
137  * Return RTP_OK on success
138  * Return RTP_INVALID_VALUE if "hook" is nullptr */
139  rtp_error_t install_deallocation_hook(void (*hook)(void *));
140 
141  /* If needed, a notification hook can be installed to uvgRTP that can be used as
142  * an information side channel to the internal state of the library.
143  *
144  * When uvgRTP encouters a situation it doesn't know how to react to,
145  * it calls the notify hook with certain notify reason number (src/util.hh).
146  * Upon receiving a notification, application may ignore it or act on it somehow
147  *
148  * Currently only one notification type is supported and only receiver uses notifications
149  *
150  * "arg" is optional argument that is passed to hook when it is called. It may be nullptr
151  *
152  * Return RTP_OK on success
153  * Return RTP_INVALID_VALUE if "hook" is nullptr */
154  rtp_error_t install_notify_hook(void *arg, void (*hook)(void *, int));
156 
167  rtp_error_t configure_ctx(int flag, ssize_t value);
168 
170  /* Setter and getter for media-specific config that can be used f.ex with Opus */
171  void set_media_config(void *config);
172  void *get_media_config();
173 
174  /* Get unique key of the media stream
175  * Used by session to index media streams */
176  uint32_t get_key();
178 
192 
193  private:
194  /* Initialize the connection by initializing the socket
195  * and binding ourselves to specified interface and creating
196  * an outgoing address */
197  rtp_error_t init_connection();
198 
199  uint32_t key_;
200 
201  uvgrtp::srtp *srtp_;
202  uvgrtp::srtcp *srtcp_;
203  uvgrtp::socket *socket_;
204  uvgrtp::rtp *rtp_;
205  uvgrtp::rtcp *rtcp_;
206 
207  sockaddr_in addr_out_;
208  std::string addr_;
209  std::string laddr_;
210  int src_port_;
211  int dst_port_;
212  rtp_format_t fmt_;
213  int flags_;
214 
215  /* Media context config (SCD etc.) */
216  rtp_ctx_conf_t ctx_config_;
217 
218  /* Media config f.ex. for Opus */
219  void *media_config_;
220 
221  /* Has the media stream been initialized */
222  bool initialized_;
223 
224  /* Primary handler keys for the RTP packet dispatcher */
225  uint32_t rtp_handler_key_;
226  uint32_t zrtp_handler_key_;
227 
228  /* RTP packet dispatcher for the receiver */
229  uvgrtp::pkt_dispatcher *pkt_dispatcher_;
230  std::thread *dispatcher_thread_;
231 
232  /* Media object associated with this media stream. */
233  uvgrtp::formats::media *media_;
234 
235  /* Thread that keeps the holepunched connection open for unidirectional streams */
236  uvgrtp::holepuncher *holepuncher_;
237  };
238 };
239 
240 namespace uvg_rtp = uvgrtp;
Definition: media_stream.hh:18
uvgrtp::rtcp * get_rtcp()
Get pointer to the RTCP object of the media stream.
uvgrtp::frame::rtp_frame * pull_frame(size_t timeout)
Poll a frame for a specified time from the media stream object.
rtp_error_t install_receive_hook(void *arg, void(*hook)(void *, uvgrtp::frame::rtp_frame *))
rtp_error_t push_frame(uint8_t *data, size_t data_len, int flags)
rtp_error_t configure_ctx(int flag, ssize_t value)
Configure the media stream, see RTP_CTX_CONFIGURATION_FLAGS for more details.
uvgrtp::frame::rtp_frame * pull_frame()
Poll a frame indefinetily from the media stream object.
Definition: rtcp.hh:74