This avoids having to try to wait for data in
avformat_find_stream_info that we won't be able to decode anyway.
---
 libavformat/rtsp.c |   28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index c94ef02..c9c366f 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -278,6 +278,32 @@ int ff_rtsp_next_attr_and_value(const char **p, char 
*attr, int attr_size,
     return 0;
 }
 
+static void free_uninitialized_stream(AVFormatContext *s)
+{
+    RTSPState *rt = s->priv_data;
+    RTSPStream *rtsp_st;
+    AVStream *st;
+
+    if (rt->nb_rtsp_streams <= 0)
+        return;
+    rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
+    if (rtsp_st->stream_index < 0)
+        return;
+    st = s->streams[rtsp_st->stream_index];
+    if (st->codec->codec_id != CODEC_ID_NONE)
+        return;
+    if (rtsp_st->dynamic_handler)
+        return;
+    /* Previous stream never got a codec id assigned, and isn't handled
+     * by any dynamic handler, thus don't expose it */
+    av_free(st->codec);
+    av_free(st->info);
+    av_free(st);
+    av_free(rtsp_st);
+    rt->nb_rtsp_streams--;
+    s->nb_streams--;
+}
+
 typedef struct SDPParseState {
     /* SDP only */
     struct sockaddr_storage default_ip;
@@ -354,6 +380,7 @@ static void sdp_parse_line(AVFormatContext *s, 
SDPParseState *s1,
             s1->skip_media = 1;
             return;
         }
+        free_uninitialized_stream(s);
         rtsp_st = av_mallocz(sizeof(RTSPStream));
         if (!rtsp_st)
             return;
@@ -523,6 +550,7 @@ int ff_sdp_parse(AVFormatContext *s, const char *content)
         if (*p == '\n')
             p++;
     }
+    free_uninitialized_stream(s);
     rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1));
     if (!rt->p) return AVERROR(ENOMEM);
     return 0;
-- 
1.7.9.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to