rtsp: punch holes again after pause

Message ID 1424639989-59337-1-git-send-email-martin@martin.st
State Committed
Commit cdcc370293a159c321e41af7f0eef141c62d698d
Headers show

Commit Message

Martin Storsjö Feb. 22, 2015, 9:19 p.m.
From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>

When a client behind a NAT issues a pause command, and stay paused for a
long time, the router may stop the RTP/RTCP port redirection. Resend the
hole punching packets before each PLAY command to cause the router to
restart the port redirection in that case.

Move the existing code for sending the packets from the SETUP phase
to the PLAY phase.
---
Moved the code to a separate loop, instead of adding it in an existing
loop which is only executed for RTP (not for RDT).
---
 libavformat/rtsp.c    |  7 -------
 libavformat/rtspdec.c | 12 ++++++++++++
 2 files changed, 12 insertions(+), 7 deletions(-)

Comments

Thomas Volkert Feb. 22, 2015, 9:36 p.m. | #1
On 22.02.2015 22:19, Martin Storsjö wrote:
> From: Gilles Chanteperdrix <gilles.chanteperdrix@xenomai.org>
>
> When a client behind a NAT issues a pause command, and stay paused for a
> long time, the router may stop the RTP/RTCP port redirection. Resend the
> hole punching packets before each PLAY command to cause the router to
> restart the port redirection in that case.
>
> Move the existing code for sending the packets from the SETUP phase
> to the PLAY phase.
> ---
> Moved the code to a separate loop, instead of adding it in an existing
> loop which is only executed for RTP (not for RDT).
> ---
>   libavformat/rtsp.c    |  7 -------
>   libavformat/rtspdec.c | 12 ++++++++++++
>   2 files changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index bd6494a..2aa19dc 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -1540,13 +1540,6 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
>                   err = AVERROR_INVALIDDATA;
>                   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 (CONFIG_RTPDEC &&
> -                !(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat)
> -                ff_rtp_send_punch_packets(rtsp_st->rtp_handle);
>               break;
>           }
>           case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
> diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
> index 418f383..659c768 100644
> --- a/libavformat/rtspdec.c
> +++ b/libavformat/rtspdec.c
> @@ -504,6 +504,18 @@ static int rtsp_read_play(AVFormatContext *s)
>       av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
>       rt->nb_byes = 0;
>   
> +    if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
> +        for (i = 0; i < rt->nb_rtsp_streams; i++) {
> +            RTSPStream *rtsp_st = rt->rtsp_streams[i];
> +            /* 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 (rtsp_st->rtp_handle &&
> +                !(rt->server_type == RTSP_SERVER_WMS && i > 1))
> +                ff_rtp_send_punch_packets(rtsp_st->rtp_handle);
> +        }
> +    }
>       if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
>           if (rt->transport == RTSP_TRANSPORT_RTP) {
>               for (i = 0; i < rt->nb_rtsp_streams; i++) {

Good idea, LGTM.

BR,
Thomas.

Patch

diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index bd6494a..2aa19dc 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1540,13 +1540,6 @@  int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
                 err = AVERROR_INVALIDDATA;
                 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 (CONFIG_RTPDEC &&
-                !(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat)
-                ff_rtp_send_punch_packets(rtsp_st->rtp_handle);
             break;
         }
         case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 418f383..659c768 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -504,6 +504,18 @@  static int rtsp_read_play(AVFormatContext *s)
     av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
     rt->nb_byes = 0;
 
+    if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
+        for (i = 0; i < rt->nb_rtsp_streams; i++) {
+            RTSPStream *rtsp_st = rt->rtsp_streams[i];
+            /* 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 (rtsp_st->rtp_handle &&
+                !(rt->server_type == RTSP_SERVER_WMS && i > 1))
+                ff_rtp_send_punch_packets(rtsp_st->rtp_handle);
+        }
+    }
     if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
         if (rt->transport == RTSP_TRANSPORT_RTP) {
             for (i = 0; i < rt->nb_rtsp_streams; i++) {