/* * 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 #ifndef GPAC_DISABLE_STREAMING #include /* 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_*/