1 /** @file RtpMuxStream.h */
2 #ifndef _RtpMuxStream_h_
3 #define _RtpMuxStream_h_
4 
5 #include "AmRtpStream.h"
6 #include "singleton.h"
7 #include "rtp/rtp.h"
8 #define MAX_RTP_HDR_LEN 64
9 #define MAX_MUX_QUEUE_SIZE 4096 // way too much over MTU anyway
10 
11 #define MAX_RTP_PACKET_LEN 512 // way too long - restricted by max mux frame length
12 
13 #define MUX_PERIODIC_SETUP_FRAME_MS  500
14 #define MUX_SETUP_FRAME_REPEAT       3
15 
16 #define RESYNC_MAX_DELAY 10*8000   // TS resync assumed if out of that window
17 
18 #define DEFAULT_TS_INCREMENT 160
19 #include <map>
20 #include <string>
21 
22 #include "crc4.h"
23 
24 #define RTP_MUX_HDR_TYPE_SETUP      0
25 #define RTP_MUX_HDR_TYPE_COMPRESSED 1
26 
27 #define RTP_MUX_HDR_TS_MULTIPLIER_40  0
28 #define RTP_MUX_HDR_TS_MULTIPLIER_160 1
29 
30 #define RTP_MUX_HDR_TS_MULTIPLIER_LOW  40
31 #define RTP_MUX_HDR_TS_MULTIPLIER_HIGH 160
32 
33 /**
34  * \brief RTP Mux data header type
35  */
36 typedef struct {
37 #if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN))
38     u_int16 t:1;         /* type  */
39     u_int16 sid:7;       /* stream id */
40 #else
41     u_int16 sid:7;       /* stream id */
42     u_int16 t:1;         /* typem */
43 #endif
44     u_int16 len:8;        /* length */
45 } rtp_mux_hdr_t;
46 
47 typedef struct {
48 #if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN))
49     u_int16 t:1;         /* type   = 0*/
50     u_int16 sid:7;       /* stream id */
51     u_int16 len:8;       /* length */
52     u_int16 dstport;     /* dstport */
53     u_int16 u:1;         /* ts_inc multiplier  */
54     u_int16 ts_inc:7;    /* ts_increment */
55 #else
56     u_int16 sid:7;       /* stream id */
57     u_int16 t:1;         /* typem */
58     u_int16 len:8;        /* length */
59     u_int16 dstport;     /* dstport */
60     u_int16 ts_inc:7;    /* ts_increment */
61     u_int16 u:1;         /* ts_inc multiplier  */
62 #endif
63 } rtp_mux_hdr_setup_t;
64 
65 
66 typedef struct {
67 #if (defined(__BYTE_ORDER) && (__BYTE_ORDER == __BIG_ENDIAN))
68     u_int16 t:1;         /* type   = 1*/
69     u_int16 sid:7;       /* stream id */
70     u_int16 len:8;       /* length */
71     u_int16 m:1;         /* marker  */
72     u_int16 sn_lsb:3;    /* SN lsb */
73     u_int16 ts_crc4:4;   /* TS CRC-4 */
74 #else
75     u_int16 sid:7;       /* stream id */
76     u_int16 t:1;         /* type = 1 */
77     u_int16 len:8;       /* length */
78     u_int16 ts_crc4:4;   /* TS CRC-4 */
79     u_int16 sn_lsb:3;    /* SN lsb */
80     u_int16 m:1;         /* marker  */
81 #endif
82 } rtp_mux_hdr_compressed_t;
83 
84 using std::string;
85 
86 struct MuxStreamState {
87   u_int16 dstport;
88   u_int16 ts_increment;
89   unsigned char rtp_hdr[MAX_RTP_HDR_LEN];
90   u_int16 rtp_hdr_len;
91 
92   size_t setup_frame_ctr;
93   unsigned  int last_mux_packet_id;
94 
95   u_int32_t last_setup_frame_ts;
96 
MuxStreamStateMuxStreamState97   MuxStreamState()
98   : dstport(0), ts_increment(DEFAULT_TS_INCREMENT), rtp_hdr_len(0), setup_frame_ctr(0), last_mux_packet_id(0) { }
99 
100 };
101 
102 /** incoming */
103 class AmRtpMuxStream
104 : public AmRtpStream
105 
106 {
107   MuxStreamState recv_streamstates[256];
108 
109  public:
110   AmRtpMuxStream();
111   ~AmRtpMuxStream();
112 
113   void recvPacket(int fd, unsigned char* pkt, size_t len);
114 };
115 
116 /** outgoing queue for one MUX channel */
117 struct MuxStreamQueue {
118   string remote_ip;
119   unsigned short remote_port;
120   int l_sd;
121   struct sockaddr_storage r_saddr;
122   struct sockaddr_storage l_saddr;
123 
124   //      port          stream_id
125   std::map<unsigned short, unsigned char> stream_ids;
126   //      stream_id     state
127   std::map<unsigned char, MuxStreamState> streamstates;
128 
129   unsigned char buf[MAX_MUX_QUEUE_SIZE];
130   unsigned char* end_ptr;
131 
132   u_int32_t oldest_frame;
133   bool oldest_frame_i;
134 
135   // counts up with every packet sent; for send code to determine whether queue still unsent
136   unsigned  int mux_packet_id;
137 
138   int sendQueue(bool force = false);
139 
140   bool is_setup;
141   int init(const string& _remote_ip, unsigned short _remote_port);
142   void close();
143 
144 public:
145   MuxStreamQueue();
146   int send(unsigned char* buffer, unsigned int b_size, const string& _remote_ip, unsigned short _remote_port, unsigned short rtp_dst_port);
147   void close(const string& _remote_ip, unsigned short _remote_port, unsigned short rtp_dst_port);
148 };
149 
150 class _AmRtpMuxSender {
151   /** buffer of outgoing packets for each RTP MUX destination */
152   std::map<string, MuxStreamQueue> send_queues;
153   /** protects the above - fixme: possibly use lock striping */
154   AmMutex send_queues_mut;
155 
156  public:
_AmRtpMuxSender()157   _AmRtpMuxSender() { }
158   int send(unsigned char* buffer, unsigned int b_size, const string& remote_ip, unsigned short remote_port, unsigned short rtp_dst_port);
159   void close(const string& remote_ip, unsigned short remote_port, unsigned short rtp_dst_port);
160 };
161 
162 typedef singleton<_AmRtpMuxSender> AmRtpMuxSender;
163 
164 #endif
165