Message ID | 1333741401-27244-1-git-send-email-martin@martin.st |
---|---|
State | Superseded |
Headers | show |
On Fri, 6 Apr 2012, Martin Storsjö wrote: > 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 Hmm, this still isn't totally right - for MS-RTSP/UDP, we need the data stream, since all the packets actually are sent over this connection, according to this code snippet: /* * WMS serves all UDP data over a single connection, the RTX, which * isn't necessarily the first in the SDP but has to be the first * to be set up, else the second/third SETUP will fail with a 461. */ if (lower_transport == RTSP_LOWER_TRANSPORT_UDP && rt->server_type == RTSP_SERVER_WMS) { if (i == 0) { /* rtx first */ for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) { int len = strlen(rt->rtsp_streams[rtx]->control_url); if (len >= 4 && !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4, "/rtx")) break; } if (rtx == rt->nb_rtsp_streams) return -1; /* no RTX found */ rtsp_st = rt->rtsp_streams[rtx]; } else rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1]; } else rtsp_st = rt->rtsp_streams[i]; This stream of course doesn't have to be exposed to the caller. I'll see if there's a neater way of handling it... // Martin
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;