summaryrefslogtreecommitdiff
path: root/include/gpac/internal/ietf_dev.h
blob: b24e4c8db36478d3f40df9e7e4f6fab1c9df5a45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
/*
 *			GPAC - Multimedia Framework C SDK
 *
 *			Authors: Jean Le Feuvre
 *			Copyright (c) Telecom ParisTech 2000-2012
 *					All rights reserved
 *
 *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
 *
 *  GPAC is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  GPAC is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; see the file COPYING.  If not, write to
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#ifndef	_GF_IETF_DEV_H_
#define _GF_IETF_DEV_H_

#include <gpac/ietf.h>

#ifndef GPAC_DISABLE_STREAMING

#include <gpac/thread.h>

/*
			RTP intern
*/

typedef struct
{
	/*version of the packet. Must be 2*/
	u8 Version;
	/*padding bits at the end of the payload*/
	u8 Padding;
	/*number of reports*/
	u8 Count;
	/*payload type of RTCP pck*/
	u8 PayloadType;
	/*The length of this RTCP packet in 32-bit words minus one including the header and any padding*/
	u16 Length;
	/*sync source identifier*/
	u32 SSRC;
} GF_RTCPHeader;


typedef struct __PRO_item
{
	struct __PRO_item *next;
	u32 pck_seq_num;
	void *pck;
	u32 size;
} GF_POItem;

typedef struct __PO
{
	struct __PRO_item *in;
	u32 head_seqnum;
	u32 Count;
	u32 MaxCount;
	u32 IsInit;
	u32 MaxDelay, LastTime;
} GF_RTPReorder;

/* creates new RTP reorderer
	@MaxCount: forces automatic packet flush. 0 means no flush
	@MaxDelay: is the max time in ms the queue will wait for a missing packet
*/
GF_RTPReorder *gf_rtp_reorderer_new(u32 MaxCount, u32 MaxDelay);
void gf_rtp_reorderer_del(GF_RTPReorder *po);
/*reset the Queue*/
void gf_rtp_reorderer_reset(GF_RTPReorder *po);

/*Adds a packet to the queue. Packet Data is memcopied*/
GF_Err gf_rtp_reorderer_add(GF_RTPReorder *po, const void * pck, u32 pck_size, u32 pck_seqnum);
/*gets the output of the queue. Packet Data IS YOURS to delete*/
void *gf_rtp_reorderer_get(GF_RTPReorder *po, u32 *pck_size);


/*the RTP channel with both RTP and RTCP sockets and buffers
each channel is identified by a control string given in RTSP Describe
this control string is used with Darwin
*/
struct __tag_rtp_channel
{
	/*global transport info for the session*/
	GF_RTSPTransport net_info;

	/*RTP CHANNEL*/
	GF_Socket *rtp;
	/*RTCP CHANNEL*/
	GF_Socket *rtcp;

	/*RTP Packet reordering. Turned on/off during initialization. The library forces a 200 ms
	max latency at the reordering queue*/
	GF_RTPReorder *po;

	/*RTCP report times*/
	u32 last_report_time;
	u32 next_report_time;

	/*NAT keep-alive*/
	u32 last_nat_keepalive_time, nat_keepalive_time_period;


	/*the seq number of the first packet as signaled by the server if any, or first
	RTP SN received (RTP multicast)*/
	u32 rtp_first_SN;
	/*the TS of the associated first packet as signaled by the server if any, or first
	RTP TS received (RTP multicast)*/
	u32 rtp_time;
	/*NPT from the rtp_time*/
	u32 CurrentTime;
	/*num loops of pck sn*/
	u32 num_sn_loops;
	/*some mapping info - we should support # payloads*/
	u8 PayloadType;
	u32 TimeScale;

	/*static buffer for RTP sending*/
	char *send_buffer;
	u32 send_buffer_size;
	u32 pck_sent_since_last_sr;
	u32 last_pck_ts;
	u32 last_pck_ntp_sec, last_pck_ntp_frac;
	u32 num_pck_sent, num_payload_bytes;
	u32 forced_ntp_sec, forced_ntp_frac;

	Bool no_auto_rtcp;
	/*RTCP info*/
	char *s_name, *s_email, *s_location, *s_phone, *s_tool, *s_note, *s_priv;
//	s8 first_rtp_pck;
	s8 first_SR;
	u32 SSRC;
	u32 SenderSSRC;

	u32 last_pck_sn;
	/*indicates if a packet loss is detected between current and previous packet*/
	Bool packet_loss;

	char *CName;

	u32 rtcp_bytes_sent;
	/*total pck rcv*/
	u32 tot_num_pck_rcv, tot_num_pck_expected;
	/*stats since last SR*/
	u32 last_num_pck_rcv, last_num_pck_expected, last_num_pck_loss;
	/*jitter compute*/
	u32 Jitter, ntp_init;
	s32 last_deviance;
	/*NTP of last SR*/
	u32 last_SR_NTP_sec, last_SR_NTP_frac;
	/*RTP time at last SR as indicated in SR*/
	u32 last_SR_rtp_time;
	/*payload info*/
	u32 total_pck, total_bytes;
};

/*gets UTC in the channel RTP timescale*/
u32 gf_rtp_channel_time(GF_RTPChannel *ch);
/*gets time in 1/65536 seconds (for reports)*/
u32 gf_rtp_get_report_time();
/*updates the time for the next report (SR, RR)*/
void gf_rtp_get_next_report_time(GF_RTPChannel *ch);


/*
			RTSP intern
*/

#define GF_RTSP_DEFAULT_BUFFER		2048
#define GF_RTSP_VERSION		"RTSP/1.0"

/*macros for RTSP command and response formmating*/
#define RTSP_WRITE_STEPALLOC	250

#define RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, str)		\
	if (strlen((const char *) str)+pos >= buf_size) {	\
		buf_size += RTSP_WRITE_STEPALLOC;	\
		buf = (char *) gf_realloc(buf, buf_size);		\
	}	\
	strcpy(buf+pos, (const char *) str);		\
	pos += (u32) strlen((const char *) str); \
 
#define RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, str)		\
	if (str){	\
		RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, str);	\
	}	\
	
#define RTSP_WRITE_HEADER(buf, buf_size, pos, type, str)		\
	if( str ) {	\
	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, type);		\
	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, ": ");		\
	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, str);		\
	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, "\r\n");	\
	}	\
 
#define RTSP_WRITE_INT(buf, buf_size, pos, d, sig)		\
	if (sig < 0) { \
		sprintf(temp, "%d", d);		\
	} else { \
		sprintf(temp, "%d", d);		\
	}	\
	RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, temp);

#define RTSP_WRITE_FLOAT_WITHOUT_CHECK(buf, buf_size, pos, d)		\
	sprintf(temp, "%.4f", d);		\
	RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, temp);

#define RTSP_WRITE_FLOAT(buf, buf_size, pos, d)		\
	sprintf(temp, "%.4f", d);		\
	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, temp);

/*default packet size, but resize on the fly if needed*/
#define RTSP_PCK_SIZE			6000
#define RTSP_TCP_BUF_SIZE		0x10000ul


typedef struct
{
	u8 rtpID;
	u8 rtcpID;
	void *ch_ptr;
} GF_TCPChan;

/**************************************
		RTSP Session
***************************************/
struct _tag_rtsp_session
{
	/*service name (extracted from URL) ex: news/latenight.mp4, vod.mp4 ...*/
	char *Service;
	/*server name (extracted from URL)*/
	char *Server;
	/*server port (extracted from URL)*/
	u16 Port;

	/*if RTSP is on UDP*/
	u8 ConnectionType;
	/*TCP interleaving ID*/
	u8 InterID;
	/*http tunnel*/
	Bool HasTunnel;
	GF_Socket *http;
	char HTTP_Cookie[30];
	u32 CookieRadLen;

	/*RTSP CHANNEL*/
	GF_Socket *connection;
	u32 SockBufferSize;
	/*needs connection*/
	u32 NeedConnection;

	/*the RTSP sequence number*/
	u32 CSeq;
	/*this is for aggregated request in order to check SeqNum*/
	u32 NbPending;

	/*RTSP sessionID, arbitrary length, alpha-numeric*/
	const char *last_session_id;

	/*RTSP STATE machine*/
	u32 RTSP_State;
	char RTSPLastRequest[40];

	/*current buffer from TCP if any*/
	char TCPBuffer[RTSP_TCP_BUF_SIZE];
	u32 CurrentSize, CurrentPos;

	/*RTSP interleaving*/
	GF_Err (*RTSP_SignalData)(GF_RTSPSession *sess, void *chan, char *buffer, u32 bufferSize, Bool IsRTCP);

	/*buffer for pck reconstruction*/
	char *rtsp_pck_buf;
	u32 rtsp_pck_size;
	u32 pck_start, payloadSize;

	/*all RTP channels in an interleaved RTP on RTSP session*/
	GF_List *TCPChannels;
	/*thread-safe, full duplex library for PLAY and RECORD*/
	GF_Mutex *mx;

	char *MobileIP;
};

GF_RTSPSession *gf_rtsp_session_new(char *sURL, u16 DefaultPort);

/*check connection status*/
GF_Err gf_rtsp_check_connection(GF_RTSPSession *sess);
/*send data on RTSP*/
GF_Err gf_rtsp_send_data(GF_RTSPSession *sess, char *buffer, u32 Size);

/*
			Common RTSP tools
*/

/*locate body-start and body size in response/commands*/
void gf_rtsp_get_body_info(GF_RTSPSession *sess, u32 *body_start, u32 *body_size);
/*read TCP until a full command/response is received*/
GF_Err gf_rtsp_read_reply(GF_RTSPSession *sess);
/*fill the TCP buffer*/
GF_Err gf_rtsp_fill_buffer(GF_RTSPSession *sess);
/*force a fill on TCP buffer - used for de-interleaving and TCP-fragmented RTSP messages*/
GF_Err gf_rtsp_refill_buffer(GF_RTSPSession *sess);
/*parses a transport string and returns a transport structure*/
GF_RTSPTransport *gf_rtsp_transport_parse(char *buffer);
/*parsing of header for com and rsp*/
GF_Err gf_rtsp_parse_header(char *buffer, u32 BufferSize, u32 BodyStart, GF_RTSPCommand *com, GF_RTSPResponse *rsp);
void gf_rtsp_set_command_value(GF_RTSPCommand *com, char *Header, char *Value);
void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value);
/*deinterleave a data packet*/
GF_Err gf_rtsp_set_deinterleave(GF_RTSPSession *sess);
/*start session through HTTP tunnel (QTSS)*/
GF_Err gf_rtsp_http_tunnel_start(GF_RTSPSession *sess, char *UserAgent);


/*packetization routines*/
GF_Err gp_rtp_builder_do_mpeg4(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
GF_Err gp_rtp_builder_do_h263(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
GF_Err gp_rtp_builder_do_amr(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
#ifndef GPAC_DISABLE_AV_PARSERS
GF_Err gp_rtp_builder_do_mpeg12_video(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
#endif
GF_Err gp_rtp_builder_do_mpeg12_audio(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration, u8 descIndex);
GF_Err gp_rtp_builder_do_avc(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
GF_Err gp_rtp_builder_do_qcelp(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
GF_Err gp_rtp_builder_do_smv(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
GF_Err gp_rtp_builder_do_latm(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration);
GF_Err gp_rtp_builder_do_dims(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration);
GF_Err gp_rtp_builder_do_ac3(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
GF_Err gp_rtp_builder_do_hevc(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);

#endif /*GPAC_DISABLE_STREAMING*/

#endif	/*_GF_IETF_DEV_H_*/