From 7203dbde3910b9be3345bc04667a01ecd9291445 Mon Sep 17 00:00:00 2001 From: Ed Torbett Date: Thu, 27 Jun 2013 08:53:00 +0100 Subject: avformat/rt*p: Joining a SSM multicast group using an SDP (Issue #2171) Passes Source-Specific Multicast parameters read from an sdp file through to the UDP socket code, allowing source-specific multicast streams to be correctly received. As an integral part of this change, additional checking (currently only enabled in the case of SSM streams, but probably useful in similar scenarios) has been added to the RTP protocol handler to distinguish UDP packets arriving from multiple sources to the same port and process only the expected packets (those transmitted from the expected UDP source address). This resolves an issue identified when multiple instances of FFmpeg subscribe to different Source-Specific Multicast streams but with each sharing the same destination port. Signed-off-by: Edward Torbett Signed-off-by: Michael Niedermayer --- libavformat/rtsp.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'libavformat/rtsp.c') diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 3a07e9c91c..ff3b74079b 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -498,6 +498,23 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, p += strspn(p, SPACE_CHARS); if (av_strstart(p, "inline:", &p)) get_word(rtsp_st->crypto_params, sizeof(rtsp_st->crypto_params), &p); + } else if (av_strstart(p, "source-filter", &p) && s->nb_streams > 0) { + get_word(buf1, sizeof(buf1), &p); // ignore tag + + get_word(buf1, sizeof(buf1), &p); + if (strcmp(buf1, "IN") != 0) + return; + get_word(buf1, sizeof(buf1), &p); + if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6")) + return; + get_word(buf1, sizeof(buf1), &p); //ignore repeated multicast address + get_word(buf1, sizeof(buf1), &p); + if (get_sockaddr(buf1, &sdp_ip)) + return; + + rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1]; + rtsp_st->ssm = 1; + rtsp_st->source_ip = sdp_ip; } else { if (rt->server_type == RTSP_SERVER_WMS) ff_wms_parse_sdp_a_line(s, p); @@ -2084,6 +2101,11 @@ static int sdp_read_header(AVFormatContext *s) "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port, rtsp_st->sdp_ttl, rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0); + if (rtsp_st->ssm) { + getnameinfo((struct sockaddr*) &rtsp_st->source_ip, sizeof(rtsp_st->source_ip), + namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST); + av_strlcatf(url, sizeof(url), "&ssm=%s", namebuf); + } if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, NULL) < 0) { err = AVERROR_INVALIDDATA; -- cgit v1.2.3