Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2021
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / RTP/RTSP input filter
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 : #include "in_rtp.h"
27 :
28 :
29 : #ifndef GPAC_DISABLE_STREAMING
30 :
31 6 : void rtpin_stream_ack_connect(GF_RTPInStream *stream, GF_Err e)
32 : {
33 : /*in case the channel has been disconnected while SETUP was issued&processed. We also could
34 : clean up the command stack*/
35 : if (!stream->opid) return;
36 :
37 : if (e != GF_OK || !stream->rtp_ch) return;
38 : }
39 :
40 32 : GF_Err rtpin_stream_init(GF_RTPInStream *stream, Bool ResetOnly)
41 : {
42 32 : gf_rtp_depacketizer_reset(stream->depacketizer, !ResetOnly);
43 :
44 32 : if (!ResetOnly) {
45 : GF_Err e;
46 : const char *ip_ifce = NULL;
47 20 : if (!stream->rtpin->interleave) {
48 19 : ip_ifce = stream->rtpin->ifce;
49 : }
50 20 : if (stream->rtp_ch->rtp)
51 0 : gf_sk_group_unregister(stream->rtpin->sockgroup, stream->rtp_ch->rtp);
52 20 : if (stream->rtp_ch->rtcp)
53 0 : gf_sk_group_unregister(stream->rtpin->sockgroup, stream->rtp_ch->rtcp);
54 :
55 20 : e = gf_rtp_initialize(stream->rtp_ch, stream->rtpin->block_size, GF_FALSE, 0, stream->rtpin->reorder_len, stream->rtpin->reorder_delay, (char *)ip_ifce);
56 20 : if (e) return e;
57 :
58 20 : if (stream->rtp_ch->rtp)
59 19 : gf_sk_group_register(stream->rtpin->sockgroup, stream->rtp_ch->rtp);
60 20 : if (stream->rtp_ch->rtcp)
61 19 : gf_sk_group_register(stream->rtpin->sockgroup, stream->rtp_ch->rtcp);
62 :
63 : }
64 : //just reset the sockets
65 32 : gf_rtp_reset_buffers(stream->rtp_ch);
66 32 : return GF_OK;
67 : }
68 :
69 14 : void rtpin_stream_reset_queue(GF_RTPInStream *stream)
70 : {
71 14 : if (!stream->pck_queue) return;
72 20 : while (gf_list_count(stream->pck_queue)) {
73 6 : GF_FilterPacket *pck = gf_list_pop_back(stream->pck_queue);
74 6 : gf_filter_pck_discard(pck);
75 : }
76 : }
77 :
78 21 : void rtpin_stream_del(GF_RTPInStream *stream)
79 : {
80 21 : if (stream->rtsp) {
81 6 : if (stream->status == RTP_Running) {
82 0 : rtpin_rtsp_teardown(stream->rtsp, stream);
83 0 : stream->status = RTP_Disconnected;
84 : }
85 6 : rtpin_remove_stream(stream->rtpin, stream);
86 : } else {
87 15 : rtpin_find_stream(stream->rtpin, stream->opid, 0, NULL, GF_TRUE);
88 : }
89 :
90 21 : if (stream->depacketizer) gf_rtp_depacketizer_del(stream->depacketizer);
91 21 : if (stream->rtp_ch) gf_rtp_del(stream->rtp_ch);
92 21 : if (stream->control) gf_free(stream->control);
93 21 : if (stream->session_id) gf_free(stream->session_id);
94 21 : if (stream->buffer) gf_free(stream->buffer);
95 21 : if (stream->pck_queue) {
96 7 : rtpin_stream_reset_queue(stream);
97 7 : gf_list_del(stream->pck_queue);
98 : }
99 21 : gf_free(stream);
100 21 : }
101 :
102 395 : static void rtpin_stream_queue_pck(GF_RTPInStream *stream, GF_FilterPacket *pck, u64 cts)
103 : {
104 : //get all packets in queue, dispatch all packets with a cts less than the cts of the packet being queued
105 : //if this is teh first packet in the RTP packet
106 : //This is only used for MPEG4, and we are sure we only have [AU(n),AU(n+i)..], [AU(n+j), AU(n+k) ...]
107 : //with i,j,k >0
108 746 : while (stream->first_in_rtp_pck) {
109 : u64 prev_cts;
110 426 : GF_FilterPacket *prev = gf_list_get(stream->pck_queue, 0);
111 426 : if (!prev) break;
112 351 : prev_cts = gf_filter_pck_get_cts(prev);
113 351 : if (prev_cts>cts) break;
114 351 : gf_list_rem(stream->pck_queue, 0);
115 351 : gf_filter_pck_send(prev);
116 : }
117 395 : stream->first_in_rtp_pck = GF_FALSE;
118 395 : gf_list_add(stream->pck_queue, pck);
119 395 : }
120 :
121 1468 : static void rtp_sl_packet_cbk(void *udta, u8 *payload, u32 size, GF_SLHeader *hdr, GF_Err e)
122 : {
123 : u64 cts, dts;
124 : s64 diff;
125 : GF_FilterPacket *pck;
126 : u8 *pck_data;
127 : GF_RTPInStream *stream = (GF_RTPInStream *)udta;
128 :
129 :
130 1468 : if (!stream->rtcp_init) {
131 39 : if (!stream->rtcp_check_start) {
132 2 : GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] No RTCP packet received yet, synchronization might be wrong for a while\n"));
133 2 : stream->rtcp_check_start = gf_sys_clock();
134 : }
135 37 : else if (gf_sys_clock() - stream->rtcp_check_start <= stream->rtpin->rtcp_timeout) {
136 37 : GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] No RTCP packet received yet, synchronization might be wrong for a while\n"));
137 : } else {
138 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] Timeout for RTCP: no SR recevied after %d ms - sync may be broken\n", stream->rtpin->rtcp_timeout));
139 0 : stream->rtcp_init = GF_TRUE;
140 : }
141 : }
142 :
143 1468 : if (stream->rtpin->first_packet_drop && (hdr->packetSequenceNumber >= stream->rtpin->first_packet_drop) ) {
144 0 : if (! ( (hdr->packetSequenceNumber - stream->rtpin->first_packet_drop) % stream->rtpin->frequency_drop) )
145 0 : return;
146 : }
147 :
148 1468 : cts = hdr->compositionTimeStamp;
149 1468 : dts = hdr->decodingTimeStamp;
150 :
151 1468 : hdr->seekFlag = 0;
152 1468 : hdr->compositionTimeStamp += stream->ts_adjust;
153 1468 : if (stream->first_rtp_ts) {
154 : assert(hdr->compositionTimeStamp >= stream->first_rtp_ts - 1);
155 1115 : hdr->compositionTimeStamp -= stream->first_rtp_ts - 1;
156 : }
157 :
158 1468 : if (hdr->decodingTimeStamp) {
159 559 : hdr->decodingTimeStamp += stream->ts_adjust;
160 559 : if (stream->first_rtp_ts) {
161 : assert(hdr->decodingTimeStamp >= stream->first_rtp_ts - 1);
162 258 : hdr->decodingTimeStamp -= stream->first_rtp_ts - 1;
163 : }
164 : }
165 :
166 1468 : pck = gf_filter_pck_new_alloc(stream->opid, size, &pck_data);
167 1468 : if (!pck) return;
168 :
169 1468 : memcpy(pck_data, payload, size);
170 1468 : if (hdr->decodingTimeStampFlag)
171 0 : gf_filter_pck_set_dts(pck, hdr->decodingTimeStamp);
172 :
173 1468 : gf_filter_pck_set_cts(pck, hdr->compositionTimeStamp);
174 :
175 1468 : diff = (s64) hdr->compositionTimeStamp - (s64) stream->prev_cts;
176 1468 : if ((stream->rtpin->max_sleep>0) && stream->prev_cts && diff) {
177 729 : if (diff<0) diff = -diff;
178 729 : if (!stream->min_dur_rtp || (diff < stream->min_dur_rtp)) {
179 19 : u64 dur = diff;
180 19 : dur *= 1000;
181 19 : dur /= stream->rtp_ch->TimeScale;
182 19 : stream->min_dur_rtp = (u32) dur;
183 19 : if (dur > stream->rtpin->max_sleep) dur = stream->rtpin->max_sleep;
184 19 : if (!stream->rtpin->min_frame_dur_ms || ( (u32) dur < stream->rtpin->min_frame_dur_ms)) {
185 19 : stream->rtpin->min_frame_dur_ms = (u32) dur;
186 : }
187 : }
188 : }
189 1468 : stream->prev_cts = (u32) hdr->compositionTimeStamp;
190 :
191 1468 : gf_filter_pck_set_sap(pck, hdr->randomAccessPointFlag ? GF_FILTER_SAP_1 :GF_FILTER_SAP_NONE);
192 1468 : if (hdr->au_duration)
193 88 : gf_filter_pck_set_duration(pck, hdr->au_duration);
194 :
195 1468 : if (hdr->samplerate && (hdr->samplerate != stream->sr)) {
196 1 : stream->sr = hdr->samplerate;
197 1 : gf_filter_pid_set_property(stream->opid, GF_PROP_PID_SAMPLE_RATE, &PROP_UINT(stream->sr));
198 : }
199 1468 : if (hdr->channels && (hdr->channels != stream->nb_ch)) {
200 1 : stream->nb_ch = hdr->channels;
201 1 : gf_filter_pid_set_property(stream->opid, GF_PROP_PID_NUM_CHANNELS, &PROP_UINT(stream->nb_ch));
202 : }
203 1468 : gf_filter_pck_set_framing(pck, hdr->accessUnitStartFlag, hdr->accessUnitEndFlag);
204 :
205 1468 : if (stream->rtp_ch->packet_loss)
206 0 : gf_filter_pck_set_corrupted(pck, 1);
207 :
208 : #if 0 //not yet implemented
209 : if (hdr->seekFlag)
210 : gf_filter_pck_set_seek_flag(pck, GF_TRUE);
211 : #endif
212 :
213 1468 : if (stream->depacketizer->sl_map.IndexDeltaLength) {
214 395 : rtpin_stream_queue_pck(stream, pck, hdr->compositionTimeStamp);
215 : } else {
216 1073 : gf_filter_pck_send(pck);
217 : }
218 :
219 1468 : hdr->compositionTimeStamp = cts;
220 1468 : hdr->decodingTimeStamp = dts;
221 : }
222 :
223 0 : GF_RTPInStream *rtpin_stream_new_satip(GF_RTPIn *rtp, const char *server_ip)
224 : {
225 : GF_RTSPTransport trans;
226 : GF_RTPInStream *tmp;
227 0 : GF_SAFEALLOC(tmp, GF_RTPInStream);
228 0 : if (!tmp) return NULL;
229 0 : tmp->rtpin = rtp;
230 0 : tmp->buffer = gf_malloc(sizeof(char) * rtp->block_size);
231 :
232 : /*create an RTP channel*/
233 0 : tmp->rtp_ch = gf_rtp_new();
234 0 : tmp->control = gf_strdup("*");
235 :
236 : memset(&trans, 0, sizeof(GF_RTSPTransport));
237 0 : trans.Profile = "RTP/AVP";
238 0 : trans.source = (char *) server_ip;
239 0 : trans.IsUnicast = GF_TRUE;
240 : trans.client_port_first = 0;
241 : trans.client_port_last = 0;
242 : trans.port_first = 0;
243 : trans.port_last = 0;
244 :
245 0 : if (gf_rtp_setup_transport(tmp->rtp_ch, &trans, NULL) != GF_OK) {
246 0 : rtpin_stream_del(tmp);
247 0 : return NULL;
248 : }
249 :
250 0 : gf_rtp_setup_payload(tmp->rtp_ch, 33, 90000);
251 :
252 0 : if (rtp->disable_rtcp) tmp->flags |= RTP_ENABLE_RTCP;
253 :
254 : /*setup NAT keep-alive*/
255 0 : gf_rtp_enable_nat_keepalive(tmp->rtp_ch, rtp->nat_keepalive ? rtp->nat_keepalive : 30000);
256 :
257 0 : tmp->range_start = 0;
258 0 : tmp->range_end = 0;
259 :
260 0 : return tmp;
261 : }
262 :
263 1 : GF_RTPInStream *rtpin_stream_new_standalone(GF_RTPIn *rtp, const char *flow_ip, u32 port)
264 : {
265 : GF_RTSPTransport trans;
266 : GF_RTPInStream *tmp;
267 1 : GF_SAFEALLOC(tmp, GF_RTPInStream);
268 1 : if (!tmp) return NULL;
269 1 : tmp->rtpin = rtp;
270 1 : tmp->buffer = gf_malloc(sizeof(char) * rtp->block_size);
271 :
272 : /*create an RTP channel*/
273 1 : tmp->rtp_ch = gf_rtp_new();
274 :
275 : memset(&trans, 0, sizeof(GF_RTSPTransport));
276 1 : trans.Profile = "RTP/AVP";
277 1 : trans.source = (char *) flow_ip;
278 1 : trans.IsUnicast = gf_sk_is_multicast_address(flow_ip);
279 1 : trans.client_port_first = port;
280 1 : trans.client_port_last = port+1;
281 1 : trans.port_first = port;
282 1 : trans.port_last = port+1;
283 :
284 1 : if (gf_rtp_setup_transport(tmp->rtp_ch, &trans, NULL) != GF_OK) {
285 0 : rtpin_stream_del(tmp);
286 0 : return NULL;
287 : }
288 :
289 : // gf_rtp_setup_payload(tmp->rtp_ch, 33, 90000);
290 :
291 1 : if (rtp->disable_rtcp) tmp->flags |= RTP_ENABLE_RTCP;
292 :
293 : /*setup NAT keep-alive*/
294 1 : gf_rtp_enable_nat_keepalive(tmp->rtp_ch, rtp->nat_keepalive ? rtp->nat_keepalive : 30000);
295 1 : tmp->range_start = 0;
296 1 : tmp->range_end = 0;
297 1 : return tmp;
298 : }
299 :
300 20 : GF_RTPInStream *rtpin_stream_new(GF_RTPIn *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, GF_RTPInStream *input_stream)
301 : {
302 : GF_RTSPRange *range;
303 : GF_RTPInStream *tmp;
304 : GF_RTPMap *map;
305 : u32 i, ESID, ODID;
306 : Bool force_bcast = GF_FALSE;
307 : Double Start, End;
308 : u16 rvc_predef = 0;
309 : char *rvc_config_att = NULL;
310 : GF_X_Attribute *att;
311 : char *ctrl;
312 : GF_SDPConnection *conn;
313 : GF_RTSPTransport trans;
314 : u32 mid, prev_stream, base_stream;
315 :
316 : //extract all relevant info from the GF_SDPMedia
317 : Start = 0.0;
318 : End = -1.0;
319 : ODID = 0;
320 : ESID = 0;
321 : ctrl = NULL;
322 : range = NULL;
323 20 : mid = prev_stream = base_stream = 0;
324 20 : i=0;
325 70 : while ((att = (GF_X_Attribute*)gf_list_enum(media->Attributes, &i))) {
326 30 : if (!stricmp(att->Name, "control")) ctrl = att->Value;
327 24 : else if (!stricmp(att->Name, "gpac-broadcast")) force_bcast = GF_TRUE;
328 39 : else if (!stricmp(att->Name, "mpeg4-esid") && att->Value) ESID = atoi(att->Value);
329 9 : else if (!stricmp(att->Name, "mpeg4-odid") && att->Value) ODID = atoi(att->Value);
330 9 : else if (!stricmp(att->Name, "range") && !range) range = gf_rtsp_range_parse(att->Value);
331 9 : else if (!stricmp(att->Name, "rvc-config-predef") && att->Value) {
332 0 : rvc_predef = atoi(att->Value);
333 9 : } else if (!stricmp(att->Name, "rvc-config")) {
334 0 : rvc_config_att = att->Value;
335 9 : } else if (!stricmp(att->Name, "mid")) {
336 0 : sscanf(att->Value, "L%d", &mid);
337 9 : } else if (!stricmp(att->Name, "depend")) {
338 : char buf[3000];
339 : memset(buf, 0, 3000);
340 0 : sscanf(att->Value, "%*d lay L%d %*s %2999s", &base_stream, buf);
341 0 : if (!strlen(buf))
342 0 : sscanf(att->Value, "%*d lay %2999s", buf);
343 0 : sscanf(buf, "L%d", &prev_stream);
344 : }
345 : }
346 :
347 20 : if (range) {
348 0 : Start = range->start;
349 0 : End = range->end;
350 0 : gf_rtsp_range_del(range);
351 : }
352 :
353 : /*check connection*/
354 20 : conn = sdp->c_connection;
355 20 : if (conn && (!conn->host || !strcmp(conn->host, "0.0.0.0"))) conn = NULL;
356 :
357 14 : if (!conn) conn = (GF_SDPConnection*)gf_list_get(media->Connections, 0);
358 20 : if (conn && (!conn->host || !strcmp(conn->host, "0.0.0.0"))) conn = NULL;
359 :
360 20 : if (!conn) {
361 : /*RTSP RFC recommends an empty "c= " line but some server don't send it. Use session info (o=)*/
362 6 : if (!sdp->o_net_type || !sdp->o_add_type || strcmp(sdp->o_net_type, "IN")) return NULL;
363 6 : if (strcmp(sdp->o_add_type, "IP4") && strcmp(sdp->o_add_type, "IP6")) return NULL;
364 : } else {
365 14 : if (strcmp(conn->net_type, "IN")) return NULL;
366 14 : if (strcmp(conn->add_type, "IP4") && strcmp(conn->add_type, "IP6")) return NULL;
367 : }
368 : /*do we support transport*/
369 20 : if (strcmp(media->Profile, "RTP/AVP") && strcmp(media->Profile, "RTP/AVP/TCP")
370 0 : && strcmp(media->Profile, "RTP/SAVP") && strcmp(media->Profile, "RTP/SAVP/TCP")
371 : ) return NULL;
372 :
373 : /*check RTP map. For now we only support 1 RTPMap*/
374 20 : if (gf_list_count(media->RTPMaps) > 1) return NULL;
375 :
376 : /*check payload type*/
377 20 : map = (GF_RTPMap*)gf_list_get(media->RTPMaps, 0);
378 20 : if (!map) {
379 0 : if (!media->fmt_list) return NULL;
380 0 : if (strchr(media->fmt_list, ' ')) return NULL;
381 : }
382 :
383 : /*this is an ESD-URL setup, we likely have namespace conflicts so overwrite given ES_ID
384 : by the app one (client side), but keep control (server side) if provided*/
385 20 : if (input_stream) {
386 0 : ESID = input_stream->ES_ID;
387 0 : if (!ctrl) ctrl = input_stream->control;
388 : tmp = input_stream;
389 : } else {
390 20 : tmp = rtpin_find_stream(rtp, NULL, ESID, NULL, GF_FALSE);
391 20 : if (tmp) return NULL;
392 :
393 20 : GF_SAFEALLOC(tmp, GF_RTPInStream);
394 20 : if (!tmp) return NULL;
395 20 : tmp->rtpin = rtp;
396 20 : tmp->buffer = gf_malloc(sizeof(char) * rtp->block_size);
397 : }
398 :
399 : /*create an RTP channel*/
400 20 : tmp->rtp_ch = gf_rtp_new();
401 20 : if (ctrl) tmp->control = gf_strdup(ctrl);
402 20 : tmp->ES_ID = ESID;
403 20 : tmp->OD_ID = ODID;
404 20 : tmp->mid = mid;
405 20 : tmp->prev_stream = prev_stream;
406 20 : tmp->base_stream = base_stream;
407 :
408 : memset(&trans, 0, sizeof(GF_RTSPTransport));
409 20 : trans.Profile = media->Profile;
410 20 : trans.source = conn ? conn->host : sdp->o_address;
411 20 : trans.IsUnicast = gf_sk_is_multicast_address(trans.source) ? GF_FALSE : GF_TRUE;
412 20 : if (!trans.IsUnicast) {
413 0 : trans.port_first = media->PortNumber;
414 0 : trans.port_last = media->PortNumber + 1;
415 0 : trans.TTL = conn ? conn->TTL : 0;
416 : } else {
417 20 : trans.client_port_first = media->PortNumber;
418 20 : trans.client_port_last = media->PortNumber + 1;
419 20 : trans.port_first = trans.client_port_first;
420 20 : trans.port_last = trans.client_port_last;
421 : }
422 :
423 20 : if (gf_rtp_setup_transport(tmp->rtp_ch, &trans, NULL) != GF_OK) {
424 0 : rtpin_stream_del(tmp);
425 0 : return NULL;
426 : }
427 : /*setup depacketizer*/
428 20 : tmp->depacketizer = gf_rtp_depacketizer_new(media, 0, rtp_sl_packet_cbk, tmp);
429 20 : if (!tmp->depacketizer) {
430 1 : GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] Failed to create RTP depacketizer for payload type %d/%s - ignoring stream)\n", map ? map->PayloadType : 0, media->fmt_list ? media->fmt_list : ""));
431 1 : rtpin_stream_del(tmp);
432 1 : return NULL;
433 : }
434 : /*setup channel*/
435 19 : gf_rtp_setup_payload(tmp->rtp_ch, map ? map->PayloadType : tmp->depacketizer->payt, tmp->depacketizer->clock_rate);
436 :
437 19 : if (tmp->depacketizer->sl_map.IndexDeltaLength) {
438 7 : tmp->pck_queue = gf_list_new();
439 : }
440 :
441 : // tmp->status = NM_Disconnected;
442 :
443 19 : if (!rtp->disable_rtcp) tmp->flags |= RTP_ENABLE_RTCP;
444 :
445 : /*setup NAT keep-alive*/
446 19 : if (rtp->nat_keepalive) gf_rtp_enable_nat_keepalive(tmp->rtp_ch, rtp->nat_keepalive);
447 :
448 19 : tmp->range_start = Start;
449 19 : tmp->range_end = End;
450 19 : if (End != -1.0) tmp->flags |= RTP_HAS_RANGE;
451 :
452 19 : if (force_bcast) tmp->flags |= RTP_FORCE_BROADCAST;
453 :
454 19 : if (rvc_predef) {
455 0 : tmp->depacketizer->sl_map.rvc_predef = rvc_predef ;
456 19 : } else if (rvc_config_att) {
457 : char *rvc_data=NULL;
458 : u32 rvc_size=0;
459 : Bool is_gz = GF_FALSE;
460 0 : if (!strncmp(rvc_config_att, "data:application/rvc-config+xml", 32) && strstr(rvc_config_att, "base64") ) {
461 0 : char *data = strchr(rvc_config_att, ',');
462 0 : if (data) {
463 0 : rvc_size = (u32) strlen(data) * 3 / 4 + 1;
464 0 : rvc_data = (char*)gf_malloc(sizeof(char) * rvc_size);
465 0 : rvc_size = gf_base64_decode(data, (u32) strlen(data), rvc_data, rvc_size);
466 0 : rvc_data[rvc_size] = 0;
467 : }
468 0 : if (!strncmp(rvc_config_att, "data:application/rvc-config+xml+gz", 35)) is_gz = GF_TRUE;
469 0 : } else if (!strnicmp(rvc_config_att, "http://", 7) || !strnicmp(rvc_config_att, "https://", 8) ) {
470 : return NULL;
471 : }
472 0 : if (rvc_data) {
473 0 : if (is_gz) {
474 : #ifdef GPAC_DISABLE_ZLIB
475 : GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("Error: no zlib support - RVC not supported in RTP\n"));
476 : gf_free(rvc_data);
477 : return NULL;
478 : #else
479 0 : gf_gz_decompress_payload(rvc_data, rvc_size, &tmp->depacketizer->sl_map.rvc_config, &tmp->depacketizer->sl_map.rvc_config_size);
480 0 : gf_free(rvc_data);
481 : #endif
482 : } else {
483 0 : tmp->depacketizer->sl_map.rvc_config = rvc_data;
484 0 : tmp->depacketizer->sl_map.rvc_config_size = rvc_size;
485 : }
486 : }
487 : }
488 :
489 : return tmp;
490 : }
491 :
492 52 : static void rtpin_stream_update_stats(GF_RTPInStream *stream)
493 : {
494 : u32 time;
495 : Float bps;
496 52 : if (!stream->rtp_ch) return;
497 :
498 52 : gf_filter_pid_set_info_str(stream->opid, "nets:loss", &PROP_FLOAT( gf_rtp_get_loss(stream->rtp_ch) ) );
499 52 : if (stream->rtsp && (stream->flags & RTP_INTERLEAVED)) {
500 3 : gf_filter_pid_set_info_str(stream->opid, "nets:interleaved", &PROP_UINT( gf_rtsp_get_session_port(stream->rtsp->session) ) );
501 3 : gf_filter_pid_set_info_str(stream->opid, "nets:rtpid", &PROP_UINT( gf_rtp_get_low_interleave_id(stream->rtp_ch) ) );
502 3 : gf_filter_pid_set_info_str(stream->opid, "nets:rctpid", &PROP_UINT( gf_rtp_get_hight_interleave_id(stream->rtp_ch) ) );
503 :
504 : } else {
505 49 : gf_filter_pid_set_info_str(stream->opid, "nets:rtpp", &PROP_UINT( stream->rtp_ch->net_info.client_port_first ) );
506 49 : gf_filter_pid_set_info_str(stream->opid, "nets:rtcpp", &PROP_UINT( stream->rtp_ch->net_info.client_port_last ) );
507 : }
508 52 : if (stream->stat_stop_time) {
509 1 : time = stream->stat_stop_time - stream->stat_start_time;
510 : } else {
511 51 : time = gf_sys_clock() - stream->stat_start_time;
512 : }
513 52 : if (!time) return;
514 :
515 52 : bps = 8.0f * stream->rtp_bytes;
516 52 : bps *= 1000;
517 52 : bps /= time;
518 52 : gf_filter_pid_set_info_str(stream->opid, "nets:bw_down", &PROP_UINT( (u32) bps ) );
519 :
520 52 : bps = 8.0f * stream->rtcp_bytes;
521 52 : bps *= 1000;
522 52 : bps /= time;
523 52 : gf_filter_pid_set_info_str(stream->opid, "nets:ctrl_bw_down", &PROP_UINT( (u32) bps ) );
524 :
525 52 : bps = 8.0f * gf_rtp_get_tcp_bytes_sent(stream->rtp_ch);
526 52 : bps *= 1000;
527 52 : bps /= time;
528 52 : gf_filter_pid_set_info_str(stream->opid, "nets:ctrl_bw_up", &PROP_UINT( (u32) bps ) );
529 : }
530 :
531 :
532 755 : void rtpin_stream_on_rtp_pck(GF_RTPInStream *stream, char *pck, u32 size)
533 : {
534 : GF_Err e;
535 : GF_RTPHeader hdr;
536 : u32 PayloadStart;
537 755 : stream->rtp_bytes += size;
538 755 : stream->first_in_rtp_pck = GF_TRUE;
539 :
540 : /*first decode RTP*/
541 755 : e = gf_rtp_decode_rtp(stream->rtp_ch, pck, size, &hdr, &PayloadStart);
542 :
543 : /*corrupted or NULL data*/
544 755 : if (e || (PayloadStart >= size)) {
545 : //gf_service_send_packet(stream->rtpin->service, stream->opid, NULL, 0, NULL, GF_CORRUPTED_DATA);
546 0 : return;
547 : }
548 755 : if (!stream->opid && !stream->depacketizer) {
549 1 : stream->depacketizer = gf_rtp_depacketizer_new(NULL, hdr.PayloadType, rtp_sl_packet_cbk, stream);
550 1 : if (!stream->depacketizer) {
551 : return;
552 : }
553 1 : stream->rtp_ch->PayloadType = hdr.PayloadType;
554 1 : stream->rtp_ch->TimeScale = stream->depacketizer->clock_rate;
555 1 : rtpin_declare_pid(stream, GF_FALSE, 0, NULL);
556 : }
557 755 : if (!stream->depacketizer) {
558 : return;
559 : }
560 :
561 : /*first we only work with one payload type...*/
562 755 : if (hdr.PayloadType != stream->rtp_ch->PayloadType) {
563 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] Mismatched in packet payload type %d vs channel payload type %d, only one payload type per channel is currently supported\n", hdr.PayloadType, stream->rtp_ch->PayloadType));
564 : }
565 :
566 : //pure RTP, remap all streams to 0, adjust sync later
567 755 : if (!stream->rtsp) {
568 671 : if (!stream->first_rtp_ts || (hdr.TimeStamp < stream->first_rtp_ts-1) )
569 14 : stream->first_rtp_ts = 1 + hdr.TimeStamp;
570 : }
571 :
572 : /*if we must notify some timing, do it now. */
573 755 : if (stream->check_rtp_time) {
574 : Double ch_time;
575 :
576 : /*it may happen that we still receive packets from a previous "play" request. If this is the case,
577 : filter until we reach the indicated rtptime*/
578 6 : if (stream->rtp_ch->rtp_time
579 6 : && (stream->rtp_ch->rtp_first_SN > hdr.SequenceNumber)
580 0 : && (stream->rtp_ch->rtp_time > hdr.TimeStamp)
581 : ) {
582 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] Rejecting too early packet (TS %d vs signaled rtp time %d - diff %d ms)\n",
583 : hdr.TimeStamp, stream->rtp_ch->rtp_time, ((hdr.TimeStamp - stream->rtp_ch->rtp_time)*1000) / stream->rtp_ch->TimeScale));
584 : return;
585 : }
586 :
587 6 : ch_time = gf_rtp_get_current_time(stream->rtp_ch);
588 :
589 : /*this is the first packet on the channel (no PAUSE)*/
590 6 : if (stream->check_rtp_time == RTP_SET_TIME_RTP) {
591 : Double media_time = 0;
592 6 : if (stream->rtsp) {
593 6 : media_time = stream->current_start + ch_time;
594 : }
595 6 : gf_filter_pid_set_property_str(stream->opid, "time:timestamp", &PROP_LONGUINT(hdr.TimeStamp) );
596 6 : gf_filter_pid_set_property_str(stream->opid, "time:media", &PROP_DOUBLE(media_time) );
597 :
598 6 : GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Mapping RTP Time seq %d TS %d Media Time %g - rtp info seq %d TS %d\n",
599 : hdr.SequenceNumber, hdr.TimeStamp, stream->current_start + ch_time, stream->rtp_ch->rtp_first_SN, stream->rtp_ch->rtp_time
600 : ));
601 :
602 : /*skip RTCP clock init when RTSP is used*/
603 6 : if (stream->rtsp) stream->rtcp_init = GF_TRUE;
604 :
605 6 : if (stream->depacketizer->payt==GF_RTP_PAYT_H264_AVC) stream->depacketizer->flags |= GF_RTP_AVC_WAIT_RAP;
606 : }
607 : /*this is RESUME on channel, filter packet based on time (darwin seems to send
608 : couple of packet before)
609 : do not fetch if we're below 10 ms or <0, because this means we already have
610 : this packet - as the PAUSE is issued with the RTP currentTime*/
611 0 : else if (ch_time <= 0.021) {
612 : return;
613 : }
614 6 : stream->check_rtp_time = RTP_SET_TIME_NONE;
615 : }
616 :
617 755 : gf_rtp_depacketizer_process(stream->depacketizer, &hdr, pck + PayloadStart, size - PayloadStart);
618 :
619 : /*last check: signal EOS if we're close to end range in case the server do not send RTCP BYE*/
620 755 : if ((stream->flags & RTP_HAS_RANGE) && !(stream->flags & RTP_EOS) ) {
621 : /*also check last CTS*/
622 81 : Double ts = (Double) ((u32) stream->depacketizer->sl_hdr.compositionTimeStamp - hdr.TimeStamp);
623 81 : ts /= gf_rtp_get_clockrate(stream->rtp_ch);
624 81 : if (ABSDIFF(stream->range_end, (ts + stream->current_start + gf_rtp_get_current_time(stream->rtp_ch)) ) < 0.2) {
625 0 : stream->flags |= RTP_EOS;
626 0 : stream->stat_stop_time = gf_sys_clock();
627 0 : gf_filter_pid_set_eos(stream->opid);
628 : }
629 : }
630 :
631 755 : if (stream->rtpin->stats) {
632 755 : u32 now = gf_sys_clock();
633 755 : if (stream->last_stats_time + stream->rtpin->stats < now) {
634 52 : stream->last_stats_time = now;
635 52 : rtpin_stream_update_stats(stream);
636 : }
637 : }
638 : }
639 :
640 18 : static void rtpin_adjust_sync(GF_RTPIn *ctx)
641 : {
642 18 : u32 i, count = gf_list_count(ctx->streams);
643 : u64 max_ntp_us = 0;
644 :
645 18 : for (i=0; i<count; i++) {
646 19 : GF_RTPInStream *stream = gf_list_get(ctx->streams, i);
647 19 : if (!stream->rtcp_init) return;
648 :
649 18 : if (max_ntp_us < stream->init_ntp_us) {
650 : max_ntp_us = stream->init_ntp_us;
651 : }
652 : }
653 :
654 17 : for (i=0; i<count; i++) {
655 : s64 ntp_diff_us;
656 17 : GF_RTPInStream *stream = gf_list_get(ctx->streams, i);
657 :
658 : ntp_diff_us = max_ntp_us;
659 17 : ntp_diff_us -= stream->init_ntp_us;
660 17 : ntp_diff_us *= stream->rtp_ch->TimeScale;
661 17 : ntp_diff_us /= 1000000;
662 17 : stream->ts_adjust = ntp_diff_us;
663 : }
664 : }
665 :
666 32 : static void rtpin_stream_on_rtcp_pck(GF_RTPInStream *stream, char *pck, u32 size)
667 : {
668 : Bool has_sr;
669 : GF_Err e;
670 :
671 33 : if (stream->status == RTP_Connected) return;
672 : //not configured yes
673 32 : if (!stream->rtp_ch->TimeScale) return;
674 31 : stream->rtcp_bytes += size;
675 :
676 31 : e = gf_rtp_decode_rtcp(stream->rtp_ch, pck, size, &has_sr);
677 31 : if (e<0) return;
678 :
679 : /*update sync if on pure RTP*/
680 31 : if (!stream->rtcp_init && has_sr) {
681 : u64 ntp_clock_us, rtp_diff_us;
682 :
683 18 : ntp_clock_us = stream->rtp_ch->last_SR_NTP_frac;
684 18 : ntp_clock_us *= 1000000;
685 18 : ntp_clock_us /= 0xFFFFFFFF;
686 18 : ntp_clock_us += 1000000 * (u64) stream->rtp_ch->last_SR_NTP_sec;
687 :
688 : //ntp time at origin: ntp(now) - ntp(first_pck) = rtpts(now) - rtpts(orig) -> ntp_first = ntp - rtp_diff
689 18 : rtp_diff_us = stream->rtp_ch->last_SR_rtp_time - (stream->first_rtp_ts - 1);
690 18 : rtp_diff_us *= 1000000;
691 18 : rtp_diff_us /= stream->rtp_ch->TimeScale;
692 :
693 18 : stream->init_ntp_us = ntp_clock_us - rtp_diff_us;
694 :
695 :
696 18 : GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTCP] At %d Using Sender Report to map RTP TS %d to NTP clock "LLU" us - NTP origin "LLU"\n", gf_sys_clock(), stream->rtp_ch->last_SR_rtp_time, ntp_clock_us, stream->init_ntp_us));
697 :
698 18 : stream->rtcp_init = GF_TRUE;
699 :
700 18 : if (stream->rtpin->rtcpsync)
701 18 : rtpin_adjust_sync(stream->rtpin);
702 : }
703 :
704 31 : if (e == GF_EOS) {
705 13 : stream->flags |= RTP_EOS;
706 : }
707 : }
708 :
709 14 : GF_Err rtpin_rtsp_data_cbk(GF_RTSPSession *sess, void *cbk, u8 *buffer, u32 bufferSize, Bool IsRTCP)
710 : {
711 : GF_RTPInStream *stream = (GF_RTPInStream *) cbk;
712 14 : if (!stream || stream->rtpin->done) return GF_OK;
713 14 : if (IsRTCP) {
714 1 : rtpin_stream_on_rtcp_pck(stream, buffer, bufferSize);
715 : } else {
716 13 : rtpin_stream_on_rtp_pck(stream, buffer, bufferSize);
717 : }
718 : return GF_OK;
719 : }
720 :
721 :
722 :
723 5794080 : u32 rtpin_stream_read(GF_RTPInStream *stream)
724 : {
725 : u32 size, tot_size = 0;
726 :
727 5794080 : if (!stream->rtp_ch) return 0;
728 5794080 : if (gf_sk_group_sock_is_set(stream->rtpin->sockgroup, stream->rtp_ch->rtcp, GF_SK_SELECT_READ)) {
729 31 : size = gf_rtp_read_rtcp(stream->rtp_ch, stream->buffer, stream->rtpin->block_size);
730 31 : if (size) {
731 : tot_size += size;
732 31 : rtpin_stream_on_rtcp_pck(stream, stream->buffer, size);
733 : }
734 : }
735 :
736 5794080 : if (gf_sk_group_sock_is_set(stream->rtpin->sockgroup, stream->rtp_ch->rtp, GF_SK_SELECT_READ)) {
737 742 : size = gf_rtp_read_rtp(stream->rtp_ch, stream->buffer, stream->rtpin->block_size);
738 742 : if (size) {
739 723 : tot_size += size;
740 723 : stream->rtpin->udp_timeout = 0;
741 723 : rtpin_stream_on_rtp_pck(stream, stream->buffer, size);
742 : }
743 : }
744 5794080 : if (!tot_size) return 0;
745 :
746 : /*and send the report*/
747 742 : if (stream->flags & RTP_ENABLE_RTCP) gf_rtp_send_rtcp_report(stream->rtp_ch);
748 :
749 : /*detect timeout*/
750 742 : if (stream->rtpin->udp_timeout) {
751 18 : if (!stream->last_udp_time) {
752 18 : stream->last_udp_time = gf_sys_clock();
753 0 : } else if (stream->rtp_ch->net_info.IsUnicast) {
754 0 : u32 diff = gf_sys_clock() - stream->last_udp_time;
755 0 : if (diff >= stream->rtpin->udp_timeout) {
756 : char szMessage[1024];
757 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] UDP Timeout after %d ms\n", diff));
758 0 : sprintf(szMessage, "No data received in %d ms%s", diff, stream->rtpin->autortsp ? ", retrying using TCP" : "");
759 0 : rtpin_send_message(stream->rtpin, GF_IP_UDP_TIMEOUT, szMessage);
760 0 : if (stream->rtpin->autortsp)
761 0 : stream->rtpin->retry_tcp = GF_TRUE;
762 : }
763 : }
764 : }
765 : return tot_size;
766 : }
767 :
768 : #endif /*GPAC_DISABLE_STREAMING*/
|