1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Jean Le Feuvre
5  *			Copyright (c) Telecom ParisTech 2000-2012
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project
9  *
10  *  GPAC is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  GPAC is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; see the file COPYING.  If not, write to
22  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 
26 #ifndef	_GF_IETF_DEV_H_
27 #define _GF_IETF_DEV_H_
28 
29 #include <gpac/ietf.h>
30 
31 #ifndef GPAC_DISABLE_STREAMING
32 
33 /*
34 			RTP intern
35 */
36 
37 typedef struct
38 {
39 	/*version of the packet. Must be 2*/
40 	u8 Version;
41 	/*padding bits at the end of the payload*/
42 	u8 Padding;
43 	/*number of reports*/
44 	u8 Count;
45 	/*payload type of RTCP pck*/
46 	u8 PayloadType;
47 	/*The length of this RTCP packet in 32-bit words minus one including the header and any padding*/
48 	u16 Length;
49 	/*sync source identifier*/
50 	u32 SSRC;
51 } GF_RTCPHeader;
52 
53 
54 typedef struct __PRO_item
55 {
56 	struct __PRO_item *next;
57 	u32 pck_seq_num;
58 	void *pck;
59 	u32 size;
60 } GF_POItem;
61 
62 typedef struct __PO
63 {
64 	struct __PRO_item *in;
65 	u32 head_seqnum;
66 	u32 Count;
67 	u32 MaxCount;
68 	u32 IsInit;
69 	u32 MaxDelay, LastTime;
70 } GF_RTPReorder;
71 
72 /* creates new RTP reorderer
73 	@MaxCount: forces automatic packet flush. 0 means no flush
74 	@MaxDelay: is the max time in ms the queue will wait for a missing packet
75 */
76 GF_RTPReorder *gf_rtp_reorderer_new(u32 MaxCount, u32 MaxDelay);
77 void gf_rtp_reorderer_del(GF_RTPReorder *po);
78 /*reset the Queue*/
79 void gf_rtp_reorderer_reset(GF_RTPReorder *po);
80 
81 /*Adds a packet to the queue. Packet Data is memcopied*/
82 GF_Err gf_rtp_reorderer_add(GF_RTPReorder *po, const void * pck, u32 pck_size, u32 pck_seqnum);
83 /*gets the output of the queue. Packet Data IS YOURS to delete*/
84 void *gf_rtp_reorderer_get(GF_RTPReorder *po, u32 *pck_size, Bool force_flush);
85 
86 
87 /*the RTP channel with both RTP and RTCP sockets and buffers
88 each channel is identified by a control string given in RTSP Describe
89 this control string is used with Darwin
90 */
91 struct __tag_rtp_channel
92 {
93 	/*global transport info for the session*/
94 	GF_RTSPTransport net_info;
95 
96 	/*RTP CHANNEL*/
97 	GF_Socket *rtp;
98 	/*RTCP CHANNEL*/
99 	GF_Socket *rtcp;
100 
101 	/*RTP Packet reordering. Turned on/off during initialization. The library forces a 200 ms
102 	max latency at the reordering queue*/
103 	GF_RTPReorder *po;
104 
105 	/*RTCP report times*/
106 	u32 last_report_time;
107 	u32 next_report_time;
108 
109 	/*NAT keep-alive*/
110 	u32 last_nat_keepalive_time, nat_keepalive_time_period;
111 
112 
113 	/*the seq number of the first packet as signaled by the server if any, or first
114 	RTP SN received (RTP multicast)*/
115 	u32 rtp_first_SN;
116 	/*the TS of the associated first packet as signaled by the server if any, or first
117 	RTP TS received (RTP multicast)*/
118 	u32 rtp_time;
119 	/*NPT from the rtp_time*/
120 	u32 CurrentTime;
121 	/*num loops of pck sn*/
122 	u32 num_sn_loops;
123 	/*some mapping info - we should support # payloads*/
124 	u8 PayloadType;
125 	u32 TimeScale;
126 
127 	/*static buffer for RTP sending*/
128 	u8 *send_buffer;
129 	u32 send_buffer_size;
130 	u32 pck_sent_since_last_sr;
131 	u32 last_pck_ts;
132 	u32 last_pck_ntp_sec, last_pck_ntp_frac;
133 	u32 num_pck_sent, num_payload_bytes;
134 	u32 forced_ntp_sec, forced_ntp_frac;
135 
136 	Bool no_auto_rtcp;
137 	/*RTCP info*/
138 	char *s_name, *s_email, *s_location, *s_phone, *s_tool, *s_note, *s_priv;
139 //	s8 first_rtp_pck;
140 	s8 first_SR;
141 	u32 SSRC;
142 	u32 SenderSSRC;
143 
144 	u32 last_pck_sn;
145 	/*indicates if a packet loss is detected between current and previous packet*/
146 	Bool packet_loss;
147 
148 	char *CName;
149 
150 	u32 rtcp_bytes_sent;
151 	/*total pck rcv*/
152 	u32 tot_num_pck_rcv, tot_num_pck_expected;
153 	/*stats since last SR*/
154 	u32 last_num_pck_rcv, last_num_pck_expected, last_num_pck_loss;
155 	/*jitter compute*/
156 	u32 Jitter, ntp_init;
157 	s32 last_deviance;
158 	/*NTP of last SR*/
159 	u32 last_SR_NTP_sec, last_SR_NTP_frac;
160 	/*RTP time at last SR as indicated in SR*/
161 	u32 last_SR_rtp_time;
162 	/*payload info*/
163 	u32 total_pck, total_bytes;
164 
165 	GF_BitStream *bs_r, *bs_w;
166 	Bool no_select;
167 
168 	gf_rtp_tcp_callback send_interleave;
169 	void *interleave_cbk1, *interleave_cbk2;
170 };
171 
172 /*gets UTC in the channel RTP timescale*/
173 u32 gf_rtp_channel_time(GF_RTPChannel *ch);
174 /*gets time in 1/65536 seconds (for reports)*/
175 u32 gf_rtp_get_report_time();
176 /*updates the time for the next report (SR, RR)*/
177 void gf_rtp_get_next_report_time(GF_RTPChannel *ch);
178 
179 
180 /*
181 			RTSP intern
182 */
183 
184 #define GF_RTSP_DEFAULT_BUFFER		2048
185 #define GF_RTSP_VERSION		"RTSP/1.0"
186 
187 /*macros for RTSP command and response formmating*/
188 #define RTSP_WRITE_STEPALLOC	250
189 
190 #define RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, str)		\
191 	if (strlen((const char *) str)+pos >= buf_size) {	\
192 		buf_size += (u32) strlen((const char *) str);	\
193 		buf = (char *) gf_realloc(buf, buf_size);		\
194 	}	\
195 	strcpy(buf+pos, (const char *) str);		\
196 	pos += (u32) strlen((const char *) str); \
197 
198 #define RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, str)		\
199 	if (str){	\
200 		RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, str);	\
201 	}	\
202 
203 #define RTSP_WRITE_HEADER(buf, buf_size, pos, type, str)		\
204 	if( str ) {	\
205 	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, type);		\
206 	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, ": ");		\
207 	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, str);		\
208 	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, "\r\n");	\
209 	}	\
210 
211 #define RTSP_WRITE_INT(buf, buf_size, pos, d, sig)	{	\
212 	char temp[50]; \
213 	if (sig < 0) { \
214 		sprintf(temp, "%d", d);		\
215 	} else { \
216 		sprintf(temp, "%d", d);		\
217 	}	\
218 	RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, temp); \
219 	}
220 
221 #define RTSP_WRITE_HEX(buf, buf_size, pos, d, sig)	{	\
222 	char temp[50]; \
223 	sprintf(temp, "%X", d);		\
224 	RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, temp);\
225 	}
226 
227 #define RTSP_WRITE_FLOAT_WITHOUT_CHECK(buf, buf_size, pos, d) {		\
228 	char temp[50]; \
229 	sprintf(temp, "%.4f", d);		\
230 	RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, temp);\
231 	}
232 
233 #define RTSP_WRITE_FLOAT(buf, buf_size, pos, d)	{	\
234 	char temp[50]; \
235 	sprintf(temp, "%.4f", d);		\
236 	RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, temp); \
237 	}
238 
239 
240 typedef struct
241 {
242 	u8 rtpID;
243 	u8 rtcpID;
244 	void *ch_ptr;
245 } GF_TCPChan;
246 
247 /**************************************
248 		RTSP Session
249 ***************************************/
250 struct _tag_rtsp_session
251 {
252 	/*service name (extracted from URL) ex: news/latenight.mp4, vod.mp4 ...*/
253 	char *Service;
254 	/*server name (extracted from URL)*/
255 	char *Server;
256 	/*server port (extracted from URL)*/
257 	u16 Port;
258 
259 	/*if RTSP is on UDP*/
260 	u8 ConnectionType;
261 	/*TCP interleaving ID*/
262 	u8 InterID;
263 	/*http tunnel*/
264 	Bool HasTunnel;
265 	GF_Socket *http;
266 	char HTTP_Cookie[30];
267 	u32 CookieRadLen;
268 
269 	/*RTSP CHANNEL*/
270 	GF_Socket *connection;
271 	u32 SockBufferSize;
272 	/*needs connection*/
273 	u32 NeedConnection;
274 
275 	/*the RTSP sequence number*/
276 	u32 CSeq;
277 	/*this is for aggregated request in order to check SeqNum*/
278 	u32 NbPending;
279 
280 	/*RTSP sessionID, arbitrary length, alpha-numeric*/
281 	const char *last_session_id;
282 
283 	/*RTSP STATE machine*/
284 	u32 RTSP_State;
285 	char RTSPLastRequest[40];
286 
287 	/*current buffer from TCP if any*/
288 	u8 *tcp_buffer;
289 	u32 CurrentSize, CurrentPos;
290 
291 	/*RTSP interleaving*/
292 	GF_Err (*RTSP_SignalData)(GF_RTSPSession *sess, void *chan, u8 *buffer, u32 bufferSize, Bool IsRTCP);
293 
294 	/*buffer for pck reconstruction*/
295 	u8 *rtsp_pck_buf;
296 	u32 rtsp_pck_size;
297 	u32 pck_start, payloadSize;
298 
299 	/*all RTP channels in an interleaved RTP on RTSP session*/
300 	GF_List *TCPChannels;
301 	Bool interleaved;
302 };
303 
304 GF_RTSPSession *gf_rtsp_session_new(char *sURL, u16 DefaultPort);
305 
306 /*check connection status*/
307 GF_Err gf_rtsp_check_connection(GF_RTSPSession *sess);
308 /*send data on RTSP*/
309 GF_Err gf_rtsp_send_data(GF_RTSPSession *sess, u8 *buffer, u32 Size);
310 
311 /*
312 			Common RTSP tools
313 */
314 
315 /*locate body-start and body size in response/commands*/
316 void gf_rtsp_get_body_info(GF_RTSPSession *sess, u32 *body_start, u32 *body_size);
317 /*read TCP until a full command/response is received*/
318 GF_Err gf_rtsp_read_reply(GF_RTSPSession *sess);
319 /*fill the TCP buffer*/
320 GF_Err gf_rtsp_fill_buffer(GF_RTSPSession *sess);
321 /*force a fill on TCP buffer - used for de-interleaving and TCP-fragmented RTSP messages*/
322 GF_Err gf_rtsp_refill_buffer(GF_RTSPSession *sess);
323 /*parses a transport string and returns a transport structure*/
324 GF_RTSPTransport *gf_rtsp_transport_parse(u8 *buffer);
325 /*parsing of header for com and rsp*/
326 GF_Err gf_rtsp_parse_header(u8 *buffer, u32 BufferSize, u32 BodyStart, GF_RTSPCommand *com, GF_RTSPResponse *rsp);
327 void gf_rtsp_set_command_value(GF_RTSPCommand *com, char *Header, char *Value);
328 void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value);
329 /*deinterleave a data packet*/
330 GF_Err gf_rtsp_set_deinterleave(GF_RTSPSession *sess);
331 /*start session through HTTP tunnel (QTSS)*/
332 GF_Err gf_rtsp_http_tunnel_start(GF_RTSPSession *sess, char *UserAgent);
333 
334 
335 
336 
337 
338 /*
339 		RTP -> SL packetization tool
340 	You should ONLY modify the GF_SLHeader while packetizing, all the rest is private
341 	to the tool.
342 	Also note that AU start/end is automatically updated, therefore you should only
343 	set CTS-DTS-OCR-sequenceNumber (which is automatically incremented when splitting a payload)
344 	-padding-idle infos
345 	SL flags are computed on the fly, but you may wish to modify them in case of
346 	packet drop/... at the encoder side
347 
348 */
349 struct __tag_rtp_packetizer
350 {
351 	/*input packet sl header cfg. modify only if needed*/
352 	GF_SLHeader sl_header;
353 	u32 nb_aus;
354 	/*
355 
356 		PRIVATE _ DO NOT TOUCH
357 	*/
358 
359 //! @cond Doxygen_Suppress
360 
361 	/*RTP payload type (RFC type, NOT the RTP hdr payT)*/
362 	u32 rtp_payt;
363 	/*packetization flags*/
364 	u32 flags;
365 	/*Path MTU size without 12-bytes RTP header*/
366 	u32 Path_MTU;
367 	/*max packet duration in RTP TS*/
368 	u32 max_ptime;
369 
370 	/*payload type of RTP packets - only one payload type can be used in GPAC*/
371 	u8 PayloadType;
372 
373 	/*RTP header of current packet*/
374 	GF_RTPHeader rtp_header;
375 
376 	/*RTP packet handling callbacks*/
377 	void (*OnNewPacket)(void *cbk_obj, GF_RTPHeader *header);
378 	void (*OnPacketDone)(void *cbk_obj, GF_RTPHeader *header);
379 	void (*OnDataReference)(void *cbk_obj, u32 payload_size, u32 offset_from_orig);
380 	void (*OnData)(void *cbk_obj, u8 *data, u32 data_size, Bool is_header);
381 	void *cbk_obj;
382 
383 	/*********************************
384 		MPEG-4 Generic hinting
385 	*********************************/
386 
387 	/*SL to RTP map*/
388 	GP_RTPSLMap slMap;
389 	/*SL conf and state*/
390 	GF_SLConfig sl_config;
391 
392 	/*set to 1 if firstSL in RTP packet*/
393 	Bool first_sl_in_rtp;
394 	Bool has_AU_header;
395 	/*current info writers*/
396 	GF_BitStream *pck_hdr, *payload;
397 
398 	/*AU SN of last au*/
399 	u32 last_au_sn;
400 
401 	/*info for the current packet*/
402 	u32 auh_size, bytesInPacket;
403 
404 	/*********************************
405 			ISMACryp info
406 	*********************************/
407 	Bool force_flush, is_encrypted;
408 	u64 IV, first_AU_IV;
409 	char *key_indicator;
410 
411 	/*********************************
412 			AVC-H264 info
413 	*********************************/
414 	/*AVC non-IDR flag: set if all NAL in current packet are non-IDR (disposable)*/
415 	Bool avc_non_idr;
416 
417 	/*********************************
418 			AC3 info
419 	*********************************/
420 	/*ac3 ft flags*/
421 	u8 ac3_ft;
422 
423 	/*********************************
424 			HEVC-H265 info
425 	*********************************/
426 	/*HEVC Payload Header. It will be use in case of Aggreation Packet where we must add payload header for packet after having added of NALU to AP*/
427 	char hevc_payload_hdr[2];
428 
429 //! @endcond
430 
431 };
432 
433 /*packetization routines*/
434 GF_Err gp_rtp_builder_do_mpeg4(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
435 GF_Err gp_rtp_builder_do_h263(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
436 GF_Err gp_rtp_builder_do_amr(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
437 #ifndef GPAC_DISABLE_AV_PARSERS
438 GF_Err gp_rtp_builder_do_mpeg12_video(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
439 #endif
440 GF_Err gp_rtp_builder_do_mpeg12_audio(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
441 GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration, u8 descIndex);
442 GF_Err gp_rtp_builder_do_avc(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
443 GF_Err gp_rtp_builder_do_qcelp(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
444 GF_Err gp_rtp_builder_do_smv(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
445 GF_Err gp_rtp_builder_do_latm(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration);
446 GF_Err gp_rtp_builder_do_ac3(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
447 GF_Err gp_rtp_builder_do_hevc(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
448 GF_Err gp_rtp_builder_do_mp2t(GP_RTPPacketizer *builder, u8 *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);
449 
450 /*! RTP depacketization tool*/
451 struct __tag_rtp_depacketizer
452 {
453 	/*! depacketize routine*/
454 	void (*depacketize)(struct __tag_rtp_depacketizer *rtp, GF_RTPHeader *hdr, u8 *payload, u32 size);
455 
456 	/*! output packet sl header cfg*/
457 	GF_SLHeader sl_hdr;
458 
459 	/*! RTP payload type (RFC type, NOT the RTP hdr payT)*/
460 	u32 payt;
461 	/*! depacketization flags*/
462 	u32 flags;
463 
464 	//! RTP static map may be NULL
465 	const GF_RTPStaticMap *static_map;
466 
467 	/*! callback routine*/
468 	gf_rtp_packet_cbk on_sl_packet;
469 	/*! callback udta*/
470 	void *udta;
471 
472 	/*! SL <-> RTP map*/
473 	GP_RTPSLMap sl_map;
474 	/*! RTP clock rate*/
475 	u32 clock_rate;
476 
477 	//! clip rect X
478 	u32 x;
479 	//! clip rect Y
480 	u32 y;
481 	//! clip rect or full size width
482 	u32 w;
483 	//! clip rect or full size height
484 	u32 h;
485 
486 	/*! inter-packet reconstruction bitstream (for 3GP text and H264)*/
487 	GF_BitStream *inter_bs;
488 
489 	/*! H264/AVC config*/
490 	u32 h264_pck_mode;
491 
492 	/*3GP text reassembler state*/
493 	/*! number of 3GPP text fragments*/
494 	u8 nb_txt_frag;
495 	/*! current 3GPP text fragments*/
496 	u8 cur_txt_frag;
497 	/*! current 3GPP text sample desc index*/
498 	u8 sidx;
499 	/*! 3GPP text total sample text len*/
500 	u8 txt_len;
501 	/*! number of 3GPP text modifiers*/
502 	u8 nb_mod_frag;
503 
504 	/*! ISMACryp scheme*/
505 	u32 isma_scheme;
506 	/*! ISMACryp key*/
507 	char *key;
508 };
509 
510 #endif /*GPAC_DISABLE_STREAMING*/
511 
512 #endif	/*_GF_IETF_DEV_H_*/
513 
514