--- /dev/null
+/*\r
+ * GPAC - Multimedia Framework C SDK\r
+ *\r
+ * Copyright (c) Jean Le Feuvre 2000-2005\r
+ * All rights reserved\r
+ *\r
+ * This file is part of GPAC / IETF RTP/RTSP/SDP sub-project\r
+ *\r
+ * GPAC is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU Lesser General Public License as published by\r
+ * the Free Software Foundation; either version 2, or (at your option)\r
+ * any later version.\r
+ * \r
+ * GPAC is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU Lesser General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU Lesser General Public\r
+ * License along with this library; see the file COPYING. If not, write to\r
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. \r
+ *\r
+ */\r
+\r
+#ifndef _GF_IETF_DEV_H_\r
+#define _GF_IETF_DEV_H_\r
+\r
+#include <gpac/ietf.h>\r
+#include <gpac/thread.h>\r
+\r
+/*\r
+ RTP intern\r
+*/\r
+\r
+typedef struct\r
+{\r
+ /*version of the packet. Must be 2*/\r
+ u8 Version;\r
+ /*padding bits at the end of the payload*/\r
+ u8 Padding;\r
+ /*number of reports*/\r
+ u8 Count;\r
+ /*payload type of RTCP pck*/\r
+ u8 PayloadType;\r
+ /*The length of this RTCP packet in 32-bit words minus one including the header and any padding*/\r
+ u16 Length;\r
+ /*sync source identifier*/\r
+ u32 SSRC;\r
+} GF_RTCPHeader; \r
+\r
+\r
+typedef struct __PRO_item\r
+{\r
+ struct __PRO_item *next;\r
+ u32 pck_seq_num;\r
+ void *pck;\r
+ u32 size;\r
+} GF_POItem;\r
+\r
+typedef struct __PO\r
+{\r
+ struct __PRO_item *in;\r
+ u32 head_seqnum;\r
+ u32 Count;\r
+ u32 MaxCount;\r
+ u32 IsInit;\r
+ u32 MaxDelay, LastTime;\r
+} GF_RTPReorder;\r
+\r
+/* creates new RTP reorderer\r
+ @MaxCount: forces automatic packet flush. 0 means no flush\r
+ @MaxDelay: is the max time in ms the queue will wait for a missing packet\r
+*/\r
+GF_RTPReorder *gf_rtp_reorderer_new(u32 MaxCount, u32 MaxDelay);\r
+void gf_rtp_reorderer_del(GF_RTPReorder *po);\r
+/*reset the Queue*/\r
+void gf_rtp_reorderer_reset(GF_RTPReorder *po);\r
+\r
+/*Adds a packet to the queue. Packet Data is memcopied*/\r
+GF_Err gf_rtp_reorderer_add(GF_RTPReorder *po, void *pck, u32 pck_size, u32 pck_seqnum);\r
+/*gets the output of the queue. Packet Data IS YOURS to delete*/\r
+void *gf_rtp_reorderer_get(GF_RTPReorder *po, u32 *pck_size);\r
+\r
+\r
+/*the RTP channel with both RTP and RTCP sockets and buffers\r
+each channel is identified by a control string given in RTSP Describe\r
+this control string is used with Darwin\r
+*/\r
+struct __tag_rtp_channel\r
+{\r
+ /*global transport info for the session*/\r
+ GF_RTSPTransport net_info;\r
+ \r
+ /*RTP CHANNEL*/\r
+ GF_Socket *rtp;\r
+ /*RTCP CHANNEL*/\r
+ GF_Socket *rtcp;\r
+ \r
+ /*RTP Packet reordering. Turned on/off during initialization. The library forces a 200 ms\r
+ max latency at the reordering queue*/\r
+ GF_RTPReorder *po;\r
+\r
+ /*RTCP report times*/\r
+ u32 last_report_time;\r
+ u32 next_report_time;\r
+\r
+ /*NAT keep-alive*/\r
+ u32 last_nat_keepalive_time, nat_keepalive_time_period;\r
+\r
+ \r
+ /*the seq number of the first packet as signaled by the server if any, or first\r
+ RTP SN received (RTP multicast)*/\r
+ u32 rtp_first_SN;\r
+ /*the TS of the associated first packet as signaled by the server if any, or first\r
+ RTP TS received (RTP multicast)*/\r
+ u32 rtp_time;\r
+ /*NPT from the rtp_time*/\r
+ u32 CurrentTime;\r
+ /*num loops of pck sn*/\r
+ u32 num_sn_loops;\r
+ /*some mapping info - we should support # payloads*/\r
+ u8 PayloadType;\r
+ u32 TimeScale;\r
+\r
+ /*static buffer for RTP sending*/\r
+ char *send_buffer;\r
+ u32 send_buffer_size;\r
+ u32 pck_sent_since_last_sr;\r
+ u32 last_pck_ts;\r
+ u32 last_pck_ntp_sec, last_pck_ntp_frac;\r
+ u32 num_pck_sent, num_payload_bytes;\r
+\r
+ /*RTCP info*/\r
+ char *s_name, *s_email, *s_location, *s_phone, *s_tool, *s_note, *s_priv;\r
+// s8 first_rtp_pck;\r
+ s8 first_SR;\r
+ u32 SSRC;\r
+ u32 SenderSSRC;\r
+\r
+ u32 last_pck_sn;\r
+\r
+ char *CName;\r
+\r
+ u32 rtcp_bytes_sent;\r
+ /*total pck rcv*/\r
+ u32 tot_num_pck_rcv, tot_num_pck_expected;\r
+ /*stats since last SR*/\r
+ u32 last_num_pck_rcv, last_num_pck_expected, last_num_pck_loss;\r
+ /*jitter compute*/\r
+ u32 Jitter, ntp_init;\r
+ s32 last_deviance; \r
+ /*NTP of last SR*/\r
+ u32 last_SR_NTP_sec, last_SR_NTP_frac;\r
+ /*RTP time at last SR as indicated in SR*/\r
+ u32 last_SR_rtp_time;\r
+ /*payload info*/\r
+ u32 total_pck, total_bytes;\r
+};\r
+\r
+/*gets UTC in the channel RTP timescale*/\r
+u32 gf_rtp_channel_time(GF_RTPChannel *ch);\r
+/*gets time in 1/65536 seconds (for reports)*/\r
+u32 gf_rtp_get_report_time();\r
+/*updates the time for the next report (SR, RR)*/\r
+void gf_rtp_get_next_report_time(GF_RTPChannel *ch);\r
+\r
+\r
+/*\r
+ RTSP intern\r
+*/\r
+\r
+#define GF_RTSP_DEFAULT_BUFFER 2048\r
+#define GF_RTSP_VERSION "RTSP/1.0"\r
+\r
+/*macros for RTSP command and response formmating*/\r
+#define RTSP_WRITE_STEPALLOC 250\r
+\r
+#define RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, str) \\r
+ if (str) { \\r
+ if (strlen((const char *) str)+pos >= buf_size) { \\r
+ buf_size += RTSP_WRITE_STEPALLOC; \\r
+ buf = (char *) realloc(buf, buf_size); \\r
+ } \\r
+ strcpy(buf+pos, (const char *) str); \\r
+ pos += strlen((const char *) str); \\r
+ }\\r
+\r
+#define RTSP_WRITE_HEADER(buf, buf_size, pos, type, str) \\r
+ if (str) { \\r
+ RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, type); \\r
+ RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, ": "); \\r
+ RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, str); \\r
+ RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, "\r\n"); \\r
+ } \\r
+\r
+#define RTSP_WRITE_INT(buf, buf_size, pos, d, sig) \\r
+ if (sig) { \\r
+ sprintf(temp, "%d", d); \\r
+ } else { \\r
+ sprintf(temp, "%u", d); \\r
+ } \\r
+ RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, temp);\r
+\r
+#define RTSP_WRITE_FLOAT(buf, buf_size, pos, d) \\r
+ sprintf(temp, "%.4f", d); \\r
+ RTSP_WRITE_ALLOC_STR(buf, buf_size, pos, temp);\r
+\r
+/*default packet size, but resize on the fly if needed*/\r
+#define RTSP_PCK_SIZE 6000\r
+#define RTSP_TCP_BUF_SIZE 0x10000ul\r
+\r
+\r
+typedef struct\r
+{\r
+ u8 rtpID;\r
+ u8 rtcpID;\r
+ void *ch_ptr;\r
+} GF_TCPChan;\r
+\r
+/**************************************\r
+ RTSP Session\r
+***************************************/\r
+struct _tag_rtsp_session\r
+{\r
+ /*service name (extracted from URL) ex: news/latenight.mp4, vod.mp4 ...*/\r
+ char *Service; \r
+ /*server name (extracted from URL)*/\r
+ char *Server;\r
+ /*server port (extracted from URL)*/\r
+ u16 Port;\r
+\r
+ /*if RTSP is on UDP*/\r
+ u8 ConnectionType;\r
+ /*TCP interleaving ID*/\r
+ u8 InterID;\r
+ /*http tunnel*/\r
+ Bool HasTunnel;\r
+ GF_Socket *http;\r
+ char HTTP_Cookie[30];\r
+ u32 CookieRadLen;\r
+\r
+ /*RTSP CHANNEL*/\r
+ GF_Socket *connection;\r
+ u32 SockBufferSize;\r
+ /*needs connection*/\r
+ u32 NeedConnection;\r
+\r
+ /*the RTSP sequence number*/\r
+ u32 CSeq;\r
+ /*this is for aggregated request in order to check SeqNum*/\r
+ u32 NbPending;\r
+\r
+ /*RTSP sessionID, arbitrary length, alpha-numeric*/\r
+ const char *last_session_id;\r
+\r
+ /*RTSP STATE machine*/\r
+ u32 RTSP_State;\r
+ char RTSPLastRequest[40];\r
+\r
+ /*current buffer from TCP if any*/\r
+ char TCPBuffer[RTSP_TCP_BUF_SIZE];\r
+ u32 CurrentSize, CurrentPos;\r
+\r
+ /*RTSP interleaving*/\r
+ GF_Err (*RTSP_SignalData)(GF_RTSPSession *sess, void *chan, char *buffer, u32 bufferSize, Bool IsRTCP);\r
+ \r
+ /*buffer for pck reconstruction*/\r
+ char *rtsp_pck_buf;\r
+ u32 rtsp_pck_size;\r
+ u32 pck_start, payloadSize;\r
+\r
+ /*all RTP channels in an interleaved RTP on RTSP session*/\r
+ GF_List *TCPChannels;\r
+ /*thread-safe, full duplex library for PLAY and RECORD*/\r
+ GF_Mutex *mx;\r
+\r
+ char *MobileIP; \r
+};\r
+\r
+GF_RTSPSession *gf_rtsp_session_new(char *sURL, u16 DefaultPort);\r
+\r
+/*check connection status*/\r
+GF_Err gf_rtsp_check_connection(GF_RTSPSession *sess);\r
+/*send data on RTSP*/\r
+GF_Err gf_rtsp_send_data(GF_RTSPSession *sess, char *buffer, u32 Size);\r
+\r
+/* \r
+ Common RTSP tools\r
+*/\r
+\r
+/*locate body-start and body size in response/commands*/\r
+void gf_rtsp_get_body_info(GF_RTSPSession *sess, u32 *body_start, u32 *body_size);\r
+/*read TCP until a full command/response is received*/\r
+GF_Err gf_rtsp_read_reply(GF_RTSPSession *sess);\r
+/*fill the TCP buffer*/\r
+GF_Err gf_rtsp_fill_buffer(GF_RTSPSession *sess);\r
+/*force a fill on TCP buffer - used for de-interleaving and TCP-fragmented RTSP messages*/\r
+GF_Err gf_rtsp_refill_buffer(GF_RTSPSession *sess);\r
+/*parses a transport string and returns a transport structure*/\r
+GF_RTSPTransport *gf_rtsp_transport_parse(char *buffer);\r
+/*parsing of header for com and rsp*/\r
+GF_Err gf_rtsp_parse_header(char *buffer, u32 BufferSize, u32 BodyStart, GF_RTSPCommand *com, GF_RTSPResponse *rsp);\r
+void gf_rtsp_set_command_value(GF_RTSPCommand *com, char *Header, char *Value);\r
+void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value);\r
+/*deinterleave a data packet*/\r
+GF_Err gf_rtsp_set_deinterleave(GF_RTSPSession *sess);\r
+/*start session through HTTP tunnel (QTSS)*/\r
+GF_Err gf_rtsp_http_tunnel_start(GF_RTSPSession *sess, char *UserAgent);\r
+\r
+\r
+/*packetization routines*/\r
+GF_Err gp_rtp_builder_do_mpeg4(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);\r
+GF_Err gp_rtp_builder_do_h263(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);\r
+GF_Err gp_rtp_builder_do_amr(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);\r
+GF_Err gp_rtp_builder_do_mpeg12_video(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);\r
+GF_Err gp_rtp_builder_do_mpeg12_audio(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);\r
+GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration, u8 descIndex);\r
+GF_Err gp_rtp_builder_do_avc(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);\r
+GF_Err gp_rtp_builder_do_qcelp(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);\r
+GF_Err gp_rtp_builder_do_smv(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);\r
+GF_Err gp_rtp_builder_do_latm(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration); \r
+GF_Err gp_rtp_builder_do_dims(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration);\r
+GF_Err gp_rtp_builder_do_ac3(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize);\r
+\r
+\r
+#endif /*_GF_IETF_DEV_H_*/\r
+\r