diff mbox series

[FFmpeg-devel] avformat/rtp: Pass sources and block filter addresses via sdp file for rtp

Message ID 20200406215439.51231-1-phunkyfish@gmail.com
State Superseded
Headers show
Series [FFmpeg-devel] avformat/rtp: Pass sources and block filter addresses via sdp file for rtp | expand

Checks

Context Check Description
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Ross Nicholson April 6, 2020, 9:54 p.m. UTC
---
 libavformat/rtsp.c | 50 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 41 insertions(+), 9 deletions(-)

Comments

Nicolas George April 6, 2020, 10:36 p.m. UTC | #1
phunkyfish (12020-04-06):
> ---
>  libavformat/rtsp.c | 50 +++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 41 insertions(+), 9 deletions(-)
> 
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index cd6fc32a29..2b59a9330d 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -21,6 +21,7 @@
>  
>  #include "libavutil/avassert.h"
>  #include "libavutil/base64.h"
> +#include "libavutil/bprint.h"
>  #include "libavutil/avstring.h"
>  #include "libavutil/intreadwrite.h"
>  #include "libavutil/mathematics.h"
> @@ -2447,7 +2448,7 @@ static int rtp_probe(const AVProbeData *p)
>  static int rtp_read_header(AVFormatContext *s)
>  {
>      uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
> -    char host[500], sdp[500];
> +    char host[500], filters_buf[1000];
>      int ret, port;
>      URLContext* in = NULL;
>      int payload_type;
> @@ -2456,6 +2457,8 @@ static int rtp_read_header(AVFormatContext *s)
>      AVIOContext pb;
>      socklen_t addrlen = sizeof(addr);
>      RTSPState *rt = s->priv_data;
> +    const char *p;
> +    AVBPrint sdp;
>  
>      if (!ff_network_init())
>          return AVERROR(EIO);
> @@ -2513,16 +2516,40 @@ static int rtp_read_header(AVFormatContext *s)
>      av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
>                   NULL, 0, s->url);
>  
> -    snprintf(sdp, sizeof(sdp),
> -             "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
> -             addr.ss_family == AF_INET ? 4 : 6, host,
> -             par->codec_type == AVMEDIA_TYPE_DATA  ? "application" :
> -             par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
> -             port, payload_type);
> -    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
> +    av_bprint_init(&sdp, 0, AV_BPRINT_SIZE_UNLIMITED);
> +    av_bprintf(&sdp, "v=0\r\nc=IN IP%d %s\r\n",
> +               addr.ss_family == AF_INET ? 4 : 6, host);
> +
> +    p = strchr(s->url, '?');
> +    if (p) {
> +        static const char *filters[][2] = {{"sources", "incl"}, {"block", "excl"}, {NULL, NULL}};
> +        int i;
> +        char *q;
> +        for (i = 0; filters[i][0]; i++) {
> +            if (av_find_info_tag(filters_buf, sizeof(filters_buf), filters[i][0], p)) {
> +                q = filters_buf;
> +                while ((q = strchr(q, ',')) != NULL)
> +                    *q = ' ';
> +                av_bprintf(&sdp, "a=source-filter:%s IN IP%d %s %s\r\n",
> +                           filters[i][1],
> +                           addr.ss_family == AF_INET ? 4 : 6, host,
> +                           filters_buf);

> +                if (sdp.len != sdp.size)
> +                    goto fail_nobuf;

Only check at the end.

> +            }
> +        }
> +    }
> +
> +    av_bprintf(&sdp, "m=%s %d RTP/AVP %d\r\n",
> +               par->codec_type == AVMEDIA_TYPE_DATA  ? "application" :
> +               par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
> +               port, payload_type);
> +    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp.str);

> +    if (sdp.len != sdp.size)
> +        goto fail_nobuf;

av_bprint_is_complete(). Is this test even correct? Did you test the
code?

>      avcodec_parameters_free(&par);
>  
> -    ffio_init_context(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
> +    ffio_init_context(&pb, sdp.str, strlen(sdp.str), 0, NULL, NULL, NULL, NULL);
>      s->pb = &pb;
>  
>      /* sdp_read_header initializes this again */
> @@ -2532,9 +2559,14 @@ static int rtp_read_header(AVFormatContext *s)
>  
>      ret = sdp_read_header(s);
>      s->pb = NULL;
> +    av_bprint_finalize(&sdp, NULL);
>      return ret;
>  
> +fail_nobuf:

> +    ret = AVERROR(ENOBUFS);

This is not the error code you are looking for.

> +    av_log(s, AV_LOG_ERROR, "rtp_read_header(): not enough buffer space for sdp-headers\n");
>  fail:
> +    av_bprint_finalize(&sdp, NULL);
>      avcodec_parameters_free(&par);
>      if (in)
>          ffurl_close(in);

Regards,
Ross Nicholson April 7, 2020, 10:12 a.m. UTC | #2
Hey Nicolas,

Thanks for the review. I have incorporated your comments in the latest
version.

I have to get some users local to the problematic streams to do the
testing, they are not available in my region. It has made it somewhat
problematic to get this far ;)

phunkyfish

On Mon, 6 Apr 2020 at 23:36, Nicolas George <george@nsup.org> wrote:

> phunkyfish (12020-04-06):
> > ---
> >  libavformat/rtsp.c | 50 +++++++++++++++++++++++++++++++++++++---------
> >  1 file changed, 41 insertions(+), 9 deletions(-)
> >
> > diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> > index cd6fc32a29..2b59a9330d 100644
> > --- a/libavformat/rtsp.c
> > +++ b/libavformat/rtsp.c
> > @@ -21,6 +21,7 @@
> >
> >  #include "libavutil/avassert.h"
> >  #include "libavutil/base64.h"
> > +#include "libavutil/bprint.h"
> >  #include "libavutil/avstring.h"
> >  #include "libavutil/intreadwrite.h"
> >  #include "libavutil/mathematics.h"
> > @@ -2447,7 +2448,7 @@ static int rtp_probe(const AVProbeData *p)
> >  static int rtp_read_header(AVFormatContext *s)
> >  {
> >      uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
> > -    char host[500], sdp[500];
> > +    char host[500], filters_buf[1000];
> >      int ret, port;
> >      URLContext* in = NULL;
> >      int payload_type;
> > @@ -2456,6 +2457,8 @@ static int rtp_read_header(AVFormatContext *s)
> >      AVIOContext pb;
> >      socklen_t addrlen = sizeof(addr);
> >      RTSPState *rt = s->priv_data;
> > +    const char *p;
> > +    AVBPrint sdp;
> >
> >      if (!ff_network_init())
> >          return AVERROR(EIO);
> > @@ -2513,16 +2516,40 @@ static int rtp_read_header(AVFormatContext *s)
> >      av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
> >                   NULL, 0, s->url);
> >
> > -    snprintf(sdp, sizeof(sdp),
> > -             "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
> > -             addr.ss_family == AF_INET ? 4 : 6, host,
> > -             par->codec_type == AVMEDIA_TYPE_DATA  ? "application" :
> > -             par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
> > -             port, payload_type);
> > -    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
> > +    av_bprint_init(&sdp, 0, AV_BPRINT_SIZE_UNLIMITED);
> > +    av_bprintf(&sdp, "v=0\r\nc=IN IP%d %s\r\n",
> > +               addr.ss_family == AF_INET ? 4 : 6, host);
> > +
> > +    p = strchr(s->url, '?');
> > +    if (p) {
> > +        static const char *filters[][2] = {{"sources", "incl"},
> {"block", "excl"}, {NULL, NULL}};
> > +        int i;
> > +        char *q;
> > +        for (i = 0; filters[i][0]; i++) {
> > +            if (av_find_info_tag(filters_buf, sizeof(filters_buf),
> filters[i][0], p)) {
> > +                q = filters_buf;
> > +                while ((q = strchr(q, ',')) != NULL)
> > +                    *q = ' ';
> > +                av_bprintf(&sdp, "a=source-filter:%s IN IP%d %s %s\r\n",
> > +                           filters[i][1],
> > +                           addr.ss_family == AF_INET ? 4 : 6, host,
> > +                           filters_buf);
>
> > +                if (sdp.len != sdp.size)
> > +                    goto fail_nobuf;
>
> Only check at the end.
>
> > +            }
> > +        }
> > +    }
> > +
> > +    av_bprintf(&sdp, "m=%s %d RTP/AVP %d\r\n",
> > +               par->codec_type == AVMEDIA_TYPE_DATA  ? "application" :
> > +               par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" :
> "audio",
> > +               port, payload_type);
> > +    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp.str);
>
> > +    if (sdp.len != sdp.size)
> > +        goto fail_nobuf;
>
> av_bprint_is_complete(). Is this test even correct? Did you test the
> code?
>
> >      avcodec_parameters_free(&par);
> >
> > -    ffio_init_context(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
> > +    ffio_init_context(&pb, sdp.str, strlen(sdp.str), 0, NULL, NULL,
> NULL, NULL);
> >      s->pb = &pb;
> >
> >      /* sdp_read_header initializes this again */
> > @@ -2532,9 +2559,14 @@ static int rtp_read_header(AVFormatContext *s)
> >
> >      ret = sdp_read_header(s);
> >      s->pb = NULL;
> > +    av_bprint_finalize(&sdp, NULL);
> >      return ret;
> >
> > +fail_nobuf:
>
> > +    ret = AVERROR(ENOBUFS);
>
> This is not the error code you are looking for.
>
> > +    av_log(s, AV_LOG_ERROR, "rtp_read_header(): not enough buffer space
> for sdp-headers\n");
> >  fail:
> > +    av_bprint_finalize(&sdp, NULL);
> >      avcodec_parameters_free(&par);
> >      if (in)
> >          ffurl_close(in);
>
> Regards,
>
> --
>   Nicolas George
>
diff mbox series

Patch

diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index cd6fc32a29..2b59a9330d 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -21,6 +21,7 @@ 
 
 #include "libavutil/avassert.h"
 #include "libavutil/base64.h"
+#include "libavutil/bprint.h"
 #include "libavutil/avstring.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
@@ -2447,7 +2448,7 @@  static int rtp_probe(const AVProbeData *p)
 static int rtp_read_header(AVFormatContext *s)
 {
     uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
-    char host[500], sdp[500];
+    char host[500], filters_buf[1000];
     int ret, port;
     URLContext* in = NULL;
     int payload_type;
@@ -2456,6 +2457,8 @@  static int rtp_read_header(AVFormatContext *s)
     AVIOContext pb;
     socklen_t addrlen = sizeof(addr);
     RTSPState *rt = s->priv_data;
+    const char *p;
+    AVBPrint sdp;
 
     if (!ff_network_init())
         return AVERROR(EIO);
@@ -2513,16 +2516,40 @@  static int rtp_read_header(AVFormatContext *s)
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
                  NULL, 0, s->url);
 
-    snprintf(sdp, sizeof(sdp),
-             "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
-             addr.ss_family == AF_INET ? 4 : 6, host,
-             par->codec_type == AVMEDIA_TYPE_DATA  ? "application" :
-             par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
-             port, payload_type);
-    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
+    av_bprint_init(&sdp, 0, AV_BPRINT_SIZE_UNLIMITED);
+    av_bprintf(&sdp, "v=0\r\nc=IN IP%d %s\r\n",
+               addr.ss_family == AF_INET ? 4 : 6, host);
+
+    p = strchr(s->url, '?');
+    if (p) {
+        static const char *filters[][2] = {{"sources", "incl"}, {"block", "excl"}, {NULL, NULL}};
+        int i;
+        char *q;
+        for (i = 0; filters[i][0]; i++) {
+            if (av_find_info_tag(filters_buf, sizeof(filters_buf), filters[i][0], p)) {
+                q = filters_buf;
+                while ((q = strchr(q, ',')) != NULL)
+                    *q = ' ';
+                av_bprintf(&sdp, "a=source-filter:%s IN IP%d %s %s\r\n",
+                           filters[i][1],
+                           addr.ss_family == AF_INET ? 4 : 6, host,
+                           filters_buf);
+                if (sdp.len != sdp.size)
+                    goto fail_nobuf;
+            }
+        }
+    }
+
+    av_bprintf(&sdp, "m=%s %d RTP/AVP %d\r\n",
+               par->codec_type == AVMEDIA_TYPE_DATA  ? "application" :
+               par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
+               port, payload_type);
+    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp.str);
+    if (sdp.len != sdp.size)
+        goto fail_nobuf;
     avcodec_parameters_free(&par);
 
-    ffio_init_context(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
+    ffio_init_context(&pb, sdp.str, strlen(sdp.str), 0, NULL, NULL, NULL, NULL);
     s->pb = &pb;
 
     /* sdp_read_header initializes this again */
@@ -2532,9 +2559,14 @@  static int rtp_read_header(AVFormatContext *s)
 
     ret = sdp_read_header(s);
     s->pb = NULL;
+    av_bprint_finalize(&sdp, NULL);
     return ret;
 
+fail_nobuf:
+    ret = AVERROR(ENOBUFS);
+    av_log(s, AV_LOG_ERROR, "rtp_read_header(): not enough buffer space for sdp-headers\n");
 fail:
+    av_bprint_finalize(&sdp, NULL);
     avcodec_parameters_free(&par);
     if (in)
         ffurl_close(in);