When using RTP-over-UDP, send dummy packets during stream setup, similar to
what e.g. RealPlayer does. This allows proper port forwarding setup in NAT- based environments. Patch by Martin Storsjö <$firstname at $firstname dot st>. Originally committed as revision 21856 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
fe74099aee
commit
9c8fa20d7e
@ -273,6 +273,45 @@ int rtp_check_and_send_back_rr(RTPDemuxContext *s, int count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rtp_send_punch_packets(URLContext* rtp_handle)
|
||||||
|
{
|
||||||
|
ByteIOContext *pb;
|
||||||
|
uint8_t *buf;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
/* Send a small RTP packet */
|
||||||
|
if (url_open_dyn_buf(&pb) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
put_byte(pb, (RTP_VERSION << 6));
|
||||||
|
put_byte(pb, 0); /* Payload type */
|
||||||
|
put_be16(pb, 0); /* Seq */
|
||||||
|
put_be32(pb, 0); /* Timestamp */
|
||||||
|
put_be32(pb, 0); /* SSRC */
|
||||||
|
|
||||||
|
put_flush_packet(pb);
|
||||||
|
len = url_close_dyn_buf(pb, &buf);
|
||||||
|
if ((len > 0) && buf)
|
||||||
|
url_write(rtp_handle, buf, len);
|
||||||
|
av_free(buf);
|
||||||
|
|
||||||
|
/* Send a minimal RTCP RR */
|
||||||
|
if (url_open_dyn_buf(&pb) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
put_byte(pb, (RTP_VERSION << 6));
|
||||||
|
put_byte(pb, 201); /* receiver report */
|
||||||
|
put_be16(pb, 1); /* length in words - 1 */
|
||||||
|
put_be32(pb, 0); /* our own SSRC */
|
||||||
|
|
||||||
|
put_flush_packet(pb);
|
||||||
|
len = url_close_dyn_buf(pb, &buf);
|
||||||
|
if ((len > 0) && buf)
|
||||||
|
url_write(rtp_handle, buf, len);
|
||||||
|
av_free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open a new RTP parse context for stream 'st'. 'st' can be NULL for
|
* open a new RTP parse context for stream 'st'. 'st' can be NULL for
|
||||||
* MPEG2TS streams to indicate that they should be demuxed inside the
|
* MPEG2TS streams to indicate that they should be demuxed inside the
|
||||||
|
@ -73,6 +73,19 @@ int rtp_set_remote_url(URLContext *h, const char *uri);
|
|||||||
void rtp_get_file_handles(URLContext *h, int *prtp_fd, int *prtcp_fd);
|
void rtp_get_file_handles(URLContext *h, int *prtp_fd, int *prtcp_fd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a dummy packet on both port pairs to set up the connection
|
||||||
|
* state in potential NAT routers, so that we're able to receive
|
||||||
|
* packets.
|
||||||
|
*
|
||||||
|
* Note, this only works if the NAT router doesn't remap ports. This
|
||||||
|
* isn't a standardized procedure, but it works in many cases in practice.
|
||||||
|
*
|
||||||
|
* The same routine is used with RDT too, even if RDT doesn't use normal
|
||||||
|
* RTP packets otherwise.
|
||||||
|
*/
|
||||||
|
void rtp_send_punch_packets(URLContext* rtp_handle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* some rtp servers assume client is dead if they don't hear from them...
|
* some rtp servers assume client is dead if they don't hear from them...
|
||||||
* so we send a Receiver Report to the provided ByteIO context
|
* so we send a Receiver Report to the provided ByteIO context
|
||||||
|
@ -1146,6 +1146,12 @@ static int make_setup_request(AVFormatContext *s, const char *host, int port,
|
|||||||
err = AVERROR_INVALIDDATA;
|
err = AVERROR_INVALIDDATA;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
/* Try to initialize the connection state in a
|
||||||
|
* potential NAT router by sending dummy packets.
|
||||||
|
* RTP/RTCP dummy packets are used for RDT, too.
|
||||||
|
*/
|
||||||
|
if (!(rt->server_type == RTSP_SERVER_WMS && i > 1))
|
||||||
|
rtp_send_punch_packets(rtsp_st->rtp_handle);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
|
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user