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