* [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams
@ 2025-02-14 17:08 Rashad Tatum
2025-02-14 17:09 ` [FFmpeg-devel] [PATCH 2/2] libavformat/rtsp: Free memory allocated for temporary variables while processing sdp info Rashad Tatum
2025-02-17 8:46 ` [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams Michael Niedermayer
0 siblings, 2 replies; 4+ messages in thread
From: Rashad Tatum @ 2025-02-14 17:08 UTC (permalink / raw)
To: ffmpeg-devel
by first changing the RTSPSource to track the destination address
obtained from the source filter. For each RTSPStream, only add the source
filter from the sdp if sdp_ip string matches source-filter's destination
address.
Before issuing the setup request, change the lower_transport to
multicast if the sdp_ip is a multicast address.
Change the multicast case to append sources (from the source-filter) to
the rtp url to make the source specific multicast join work.
Signed-off-by: Rashad Tatum <tatum.rashad@gmail.com>
---
libavformat/rtsp.c | 88 +++++++++++++++++++++++++++++++---------------
libavformat/rtsp.h | 3 +-
2 files changed, 62 insertions(+), 29 deletions(-)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 5ea471b40c..0c65f8d1a4 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -389,16 +389,18 @@ typedef struct SDPParseState {
} SDPParseState;
static void copy_default_source_addrs(struct RTSPSource **addrs, int
count,
- struct RTSPSource ***dest, int
*dest_count)
+ struct RTSPSource ***dest, int
*dest_count, const char* sdp_ip_str)
{
RTSPSource *rtsp_src, *rtsp_src2;
int i;
for (i = 0; i < count; i++) {
rtsp_src = addrs[i];
- rtsp_src2 = av_memdup(rtsp_src, sizeof(*rtsp_src));
- if (!rtsp_src2)
- continue;
- dynarray_add(dest, dest_count, rtsp_src2);
+ if (strcmp(rtsp_src->dest_addr, sdp_ip_str) == 0) {
+ rtsp_src2 = av_memdup(rtsp_src, sizeof(*rtsp_src));
+ if (!rtsp_src2)
+ continue;
+ dynarray_add(dest, dest_count, rtsp_src2);
+ }
}
}
@@ -423,7 +425,7 @@ static void sdp_parse_line(AVFormatContext *s,
SDPParseState *s1,
{
RTSPState *rt = s->priv_data;
char buf1[64], st_type[64];
- const char *p;
+ const char *p, *sdp_ip_str, *dest_addr;
enum AVMediaType codec_type;
int payload_type;
AVStream *st;
@@ -448,6 +450,8 @@ static void sdp_parse_line(AVFormatContext *s,
SDPParseState *s1,
get_word_sep(buf1, sizeof(buf1), "/", &p);
if (get_sockaddr(s, buf1, &sdp_ip))
return;
+
+ sdp_ip_str = av_strdup(buf1);
ttl = 16;
if (*p == '/') {
p++;
@@ -461,6 +465,18 @@ static void sdp_parse_line(AVFormatContext *s,
SDPParseState *s1,
rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
rtsp_st->sdp_ip = sdp_ip;
rtsp_st->sdp_ttl = ttl;
+
+ copy_default_source_addrs(s1->default_include_source_addrs,
+
s1->nb_default_include_source_addrs,
+
&rtsp_st->include_source_addrs,
+
&rtsp_st->nb_include_source_addrs,
+ sdp_ip_str);
+ copy_default_source_addrs(s1->default_exclude_source_addrs,
+
s1->nb_default_exclude_source_addrs,
+
&rtsp_st->exclude_source_addrs,
+
&rtsp_st->nb_exclude_source_addrs,
+ sdp_ip_str);
+
}
break;
case 's':
@@ -504,15 +520,6 @@ static void sdp_parse_line(AVFormatContext *s,
SDPParseState *s1,
rtsp_st->sdp_ip = s1->default_ip;
rtsp_st->sdp_ttl = s1->default_ttl;
- copy_default_source_addrs(s1->default_include_source_addrs,
- s1->nb_default_include_source_addrs,
- &rtsp_st->include_source_addrs,
- &rtsp_st->nb_include_source_addrs);
- copy_default_source_addrs(s1->default_exclude_source_addrs,
- s1->nb_default_exclude_source_addrs,
- &rtsp_st->exclude_source_addrs,
- &rtsp_st->nb_exclude_source_addrs);
-
get_word(buf1, sizeof(buf1), &p); /* port */
rtsp_st->sdp_port = atoi(buf1);
@@ -672,11 +679,13 @@ static void sdp_parse_line(AVFormatContext *s,
SDPParseState *s1,
// not checking that the destination address actually
matches or is wildcard
get_word(buf1, sizeof(buf1), &p);
+ dest_addr = av_strdup(buf1);
while (*p != '\0') {
rtsp_src = av_mallocz(sizeof(*rtsp_src));
if (!rtsp_src)
return;
- get_word(rtsp_src->addr, sizeof(rtsp_src->addr), &p);
+ av_strlcpy(rtsp_src->dest_addr, dest_addr,
sizeof(rtsp_src->dest_addr));
+ get_word(rtsp_src->src_addr,
sizeof(rtsp_src->src_addr), &p);
if (exclude) {
if (s->nb_streams == 0) {
dynarray_add(&s1->default_exclude_source_addrs,
&s1->nb_default_exclude_source_addrs, rtsp_src);
@@ -859,10 +868,11 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s,
RTSPStream *rtsp_st)
rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
rtsp_st->dynamic_protocol_context,
rtsp_st->dynamic_handler);
- else if (CONFIG_RTPDEC)
+ else if (CONFIG_RTPDEC) {
rtsp_st->transport_priv = ff_rtp_parse_open(s, st,
rtsp_st->sdp_payload_type,
reordering_queue_size);
+ }
if (!rtsp_st->transport_priv) {
return AVERROR(ENOMEM);
@@ -1452,6 +1462,18 @@ retry:
return 0;
}
+static void append_source_addrs(char *buf, int size, const char *name,
+ int count, struct RTSPSource **addrs)
+{
+ int i;
+ if (!count)
+ return;
+ av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->src_addr);
+ for (i = 1; i < count; i++) {
+ av_strlcatf(buf, size, ",%s", addrs[i]->src_addr);
+ }
+}
+
int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host,
int port,
int lower_transport, const char
*real_challenge)
{
@@ -1510,6 +1532,11 @@ int ff_rtsp_make_setup_request(AVFormatContext
*s, const char *host, int port,
} else
rtsp_st = rt->rtsp_streams[i];
+ /* RTP/UDP Source Specific Multicast (SSM) */
+ if (ff_is_multicast_address((struct sockaddr*) &rtsp_st->sdp_ip)) {
+ lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST;
+ }
+
/* RTP/UDP */
if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
char buf[256];
@@ -1666,7 +1693,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s,
const char *host, int port,
break;
}
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
- char url[MAX_URL_SIZE], namebuf[50], optbuf[20] = "";
+ char url[MAX_URL_SIZE], namebuf[50], optbuf[1024] = "";
struct sockaddr_storage addr;
int port, ttl;
AVDictionary *opts = map_to_opts(rt);
@@ -1682,6 +1709,20 @@ int ff_rtsp_make_setup_request(AVFormatContext
*s, const char *host, int port,
}
if (ttl > 0)
snprintf(optbuf, sizeof(optbuf), "?ttl=%d", ttl);
+
+ if (rtsp_st->nb_include_source_addrs > 0) {
+ if(strlen(optbuf) == 0 ) {
+ snprintf(optbuf, sizeof(optbuf), "?");
+ }
+
+ append_source_addrs(optbuf, sizeof(optbuf), "sources",
+
rtsp_st->nb_include_source_addrs,
+
rtsp_st->include_source_addrs);
+ append_source_addrs(optbuf, sizeof(optbuf), "block",
+ rtsp_st->nb_exclude_source_addrs,
+ rtsp_st->exclude_source_addrs);
+ }
+
getnameinfo((struct sockaddr*) &addr, sizeof(addr),
namebuf, sizeof(namebuf), NULL, 0,
NI_NUMERICHOST);
ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
@@ -2383,16 +2424,7 @@ static int sdp_probe(const AVProbeData *p1)
return 0;
}
-static void append_source_addrs(char *buf, int size, const char *name,
- int count, struct RTSPSource **addrs)
-{
- int i;
- if (!count)
- return;
- av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
- for (i = 1; i < count; i++)
- av_strlcatf(buf, size, ",%s", addrs[i]->addr);
-}
+
static int sdp_read_header(AVFormatContext *s)
{
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 83b2e3f4fb..61de5cfb17 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -432,7 +432,8 @@ typedef struct RTSPState {
#define RTSP_FLAG_SATIP_RAW 0x20 /**< Export SAT>IP stream as raw
MPEG-TS */
typedef struct RTSPSource {
- char addr[128]; /**< Source-specific multicast include source IP
address (from SDP content) */
+ char dest_addr[128]; /**< Source-specific multicast destination IP
address (from SDP content) */
+ char src_addr[128]; /**< Source-specific multicast include source
IP address (from SDP content) */
} RTSPSource;
/**
--
2.48.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* [FFmpeg-devel] [PATCH 2/2] libavformat/rtsp: Free memory allocated for temporary variables while processing sdp info
2025-02-14 17:08 [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams Rashad Tatum
@ 2025-02-14 17:09 ` Rashad Tatum
2025-02-17 8:46 ` [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams Michael Niedermayer
1 sibling, 0 replies; 4+ messages in thread
From: Rashad Tatum @ 2025-02-14 17:09 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: Rashad Tatum <tatum.rashad@gmail.com>
---
libavformat/rtsp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 0c65f8d1a4..da733938bc 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -478,6 +478,7 @@ static void sdp_parse_line(AVFormatContext *s,
SDPParseState *s1,
sdp_ip_str);
}
+ av_freep(sdp_ip_str);
break;
case 's':
av_dict_set(&s->metadata, "title", p, 0);
@@ -702,6 +703,7 @@ static void sdp_parse_line(AVFormatContext *s,
SDPParseState *s1,
}
}
}
+ av_freep(dest_addr);
} else {
if (rt->server_type == RTSP_SERVER_WMS)
ff_wms_parse_sdp_a_line(s, p);
--
2.48.1
On 2/14/25 12:08 PM, Rashad Tatum wrote:
> by first changing the RTSPSource to track the destination address
> obtained from the source filter. For each RTSPStream, only add the source
> filter from the sdp if sdp_ip string matches source-filter's destination
> address.
>
> Before issuing the setup request, change the lower_transport to
> multicast if the sdp_ip is a multicast address.
>
> Change the multicast case to append sources (from the source-filter) to
> the rtp url to make the source specific multicast join work.
>
> Signed-off-by: Rashad Tatum <tatum.rashad@gmail.com>
> ---
> libavformat/rtsp.c | 88 +++++++++++++++++++++++++++++++---------------
> libavformat/rtsp.h | 3 +-
> 2 files changed, 62 insertions(+), 29 deletions(-)
>
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index 5ea471b40c..0c65f8d1a4 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -389,16 +389,18 @@ typedef struct SDPParseState {
> } SDPParseState;
> static void copy_default_source_addrs(struct RTSPSource **addrs, int
> count,
> - struct RTSPSource ***dest, int
> *dest_count)
> + struct RTSPSource ***dest, int
> *dest_count, const char* sdp_ip_str)
> {
> RTSPSource *rtsp_src, *rtsp_src2;
> int i;
> for (i = 0; i < count; i++) {
> rtsp_src = addrs[i];
> - rtsp_src2 = av_memdup(rtsp_src, sizeof(*rtsp_src));
> - if (!rtsp_src2)
> - continue;
> - dynarray_add(dest, dest_count, rtsp_src2);
> + if (strcmp(rtsp_src->dest_addr, sdp_ip_str) == 0) {
> + rtsp_src2 = av_memdup(rtsp_src, sizeof(*rtsp_src));
> + if (!rtsp_src2)
> + continue;
> + dynarray_add(dest, dest_count, rtsp_src2);
> + }
> }
> }
> @@ -423,7 +425,7 @@ static void sdp_parse_line(AVFormatContext *s,
> SDPParseState *s1,
> {
> RTSPState *rt = s->priv_data;
> char buf1[64], st_type[64];
> - const char *p;
> + const char *p, *sdp_ip_str, *dest_addr;
> enum AVMediaType codec_type;
> int payload_type;
> AVStream *st;
> @@ -448,6 +450,8 @@ static void sdp_parse_line(AVFormatContext *s,
> SDPParseState *s1,
> get_word_sep(buf1, sizeof(buf1), "/", &p);
> if (get_sockaddr(s, buf1, &sdp_ip))
> return;
> +
> + sdp_ip_str = av_strdup(buf1);
> ttl = 16;
> if (*p == '/') {
> p++;
> @@ -461,6 +465,18 @@ static void sdp_parse_line(AVFormatContext *s,
> SDPParseState *s1,
> rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
> rtsp_st->sdp_ip = sdp_ip;
> rtsp_st->sdp_ttl = ttl;
> +
> + copy_default_source_addrs(s1->default_include_source_addrs,
> + s1->nb_default_include_source_addrs,
> + &rtsp_st->include_source_addrs,
> + &rtsp_st->nb_include_source_addrs,
> + sdp_ip_str);
> + copy_default_source_addrs(s1->default_exclude_source_addrs,
> + s1->nb_default_exclude_source_addrs,
> + &rtsp_st->exclude_source_addrs,
> + &rtsp_st->nb_exclude_source_addrs,
> + sdp_ip_str);
> +
> }
> break;
> case 's':
> @@ -504,15 +520,6 @@ static void sdp_parse_line(AVFormatContext *s,
> SDPParseState *s1,
> rtsp_st->sdp_ip = s1->default_ip;
> rtsp_st->sdp_ttl = s1->default_ttl;
> - copy_default_source_addrs(s1->default_include_source_addrs,
> - s1->nb_default_include_source_addrs,
> - &rtsp_st->include_source_addrs,
> - &rtsp_st->nb_include_source_addrs);
> - copy_default_source_addrs(s1->default_exclude_source_addrs,
> - s1->nb_default_exclude_source_addrs,
> - &rtsp_st->exclude_source_addrs,
> - &rtsp_st->nb_exclude_source_addrs);
> -
> get_word(buf1, sizeof(buf1), &p); /* port */
> rtsp_st->sdp_port = atoi(buf1);
> @@ -672,11 +679,13 @@ static void sdp_parse_line(AVFormatContext *s,
> SDPParseState *s1,
> // not checking that the destination address actually
> matches or is wildcard
> get_word(buf1, sizeof(buf1), &p);
> + dest_addr = av_strdup(buf1);
> while (*p != '\0') {
> rtsp_src = av_mallocz(sizeof(*rtsp_src));
> if (!rtsp_src)
> return;
> - get_word(rtsp_src->addr, sizeof(rtsp_src->addr), &p);
> + av_strlcpy(rtsp_src->dest_addr, dest_addr,
> sizeof(rtsp_src->dest_addr));
> + get_word(rtsp_src->src_addr,
> sizeof(rtsp_src->src_addr), &p);
> if (exclude) {
> if (s->nb_streams == 0) {
>
> dynarray_add(&s1->default_exclude_source_addrs,
> &s1->nb_default_exclude_source_addrs, rtsp_src);
> @@ -859,10 +868,11 @@ int ff_rtsp_open_transport_ctx(AVFormatContext
> *s, RTSPStream *rtsp_st)
> rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
>
> rtsp_st->dynamic_protocol_context,
> rtsp_st->dynamic_handler);
> - else if (CONFIG_RTPDEC)
> + else if (CONFIG_RTPDEC) {
> rtsp_st->transport_priv = ff_rtp_parse_open(s, st,
> rtsp_st->sdp_payload_type,
> reordering_queue_size);
> + }
> if (!rtsp_st->transport_priv) {
> return AVERROR(ENOMEM);
> @@ -1452,6 +1462,18 @@ retry:
> return 0;
> }
> +static void append_source_addrs(char *buf, int size, const char *name,
> + int count, struct RTSPSource **addrs)
> +{
> + int i;
> + if (!count)
> + return;
> + av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->src_addr);
> + for (i = 1; i < count; i++) {
> + av_strlcatf(buf, size, ",%s", addrs[i]->src_addr);
> + }
> +}
> +
> int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host,
> int port,
> int lower_transport, const char
> *real_challenge)
> {
> @@ -1510,6 +1532,11 @@ int ff_rtsp_make_setup_request(AVFormatContext
> *s, const char *host, int port,
> } else
> rtsp_st = rt->rtsp_streams[i];
> + /* RTP/UDP Source Specific Multicast (SSM) */
> + if (ff_is_multicast_address((struct sockaddr*)
> &rtsp_st->sdp_ip)) {
> + lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST;
> + }
> +
> /* RTP/UDP */
> if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
> char buf[256];
> @@ -1666,7 +1693,7 @@ int ff_rtsp_make_setup_request(AVFormatContext
> *s, const char *host, int port,
> break;
> }
> case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
> - char url[MAX_URL_SIZE], namebuf[50], optbuf[20] = "";
> + char url[MAX_URL_SIZE], namebuf[50], optbuf[1024] = "";
> struct sockaddr_storage addr;
> int port, ttl;
> AVDictionary *opts = map_to_opts(rt);
> @@ -1682,6 +1709,20 @@ int ff_rtsp_make_setup_request(AVFormatContext
> *s, const char *host, int port,
> }
> if (ttl > 0)
> snprintf(optbuf, sizeof(optbuf), "?ttl=%d", ttl);
> +
> + if (rtsp_st->nb_include_source_addrs > 0) {
> + if(strlen(optbuf) == 0 ) {
> + snprintf(optbuf, sizeof(optbuf), "?");
> + }
> +
> + append_source_addrs(optbuf, sizeof(optbuf), "sources",
> + rtsp_st->nb_include_source_addrs,
> + rtsp_st->include_source_addrs);
> + append_source_addrs(optbuf, sizeof(optbuf), "block",
> + rtsp_st->nb_exclude_source_addrs,
> + rtsp_st->exclude_source_addrs);
> + }
> +
> getnameinfo((struct sockaddr*) &addr, sizeof(addr),
> namebuf, sizeof(namebuf), NULL, 0,
> NI_NUMERICHOST);
> ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
> @@ -2383,16 +2424,7 @@ static int sdp_probe(const AVProbeData *p1)
> return 0;
> }
> -static void append_source_addrs(char *buf, int size, const char *name,
> - int count, struct RTSPSource **addrs)
> -{
> - int i;
> - if (!count)
> - return;
> - av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
> - for (i = 1; i < count; i++)
> - av_strlcatf(buf, size, ",%s", addrs[i]->addr);
> -}
> +
> static int sdp_read_header(AVFormatContext *s)
> {
> diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
> index 83b2e3f4fb..61de5cfb17 100644
> --- a/libavformat/rtsp.h
> +++ b/libavformat/rtsp.h
> @@ -432,7 +432,8 @@ typedef struct RTSPState {
> #define RTSP_FLAG_SATIP_RAW 0x20 /**< Export SAT>IP stream as raw
> MPEG-TS */
> typedef struct RTSPSource {
> - char addr[128]; /**< Source-specific multicast include source IP
> address (from SDP content) */
> + char dest_addr[128]; /**< Source-specific multicast destination
> IP address (from SDP content) */
> + char src_addr[128]; /**< Source-specific multicast include source
> IP address (from SDP content) */
> } RTSPSource;
> /**
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams
2025-02-14 17:08 [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams Rashad Tatum
2025-02-14 17:09 ` [FFmpeg-devel] [PATCH 2/2] libavformat/rtsp: Free memory allocated for temporary variables while processing sdp info Rashad Tatum
@ 2025-02-17 8:46 ` Michael Niedermayer
2025-02-17 15:43 ` Rashad Tatum
1 sibling, 1 reply; 4+ messages in thread
From: Michael Niedermayer @ 2025-02-17 8:46 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1.1: Type: text/plain, Size: 2071 bytes --]
On Fri, Feb 14, 2025 at 12:08:24PM -0500, Rashad Tatum wrote:
> by first changing the RTSPSource to track the destination address
> obtained from the source filter. For each RTSPStream, only add the source
> filter from the sdp if sdp_ip string matches source-filter's destination
> address.
>
> Before issuing the setup request, change the lower_transport to
> multicast if the sdp_ip is a multicast address.
>
> Change the multicast case to append sources (from the source-filter) to
> the rtp url to make the source specific multicast join work.
>
> Signed-off-by: Rashad Tatum <tatum.rashad@gmail.com>
> ---
> libavformat/rtsp.c | 88 +++++++++++++++++++++++++++++++---------------
> libavformat/rtsp.h | 3 +-
> 2 files changed, 62 insertions(+), 29 deletions(-)
>
> diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> index 5ea471b40c..0c65f8d1a4 100644
> --- a/libavformat/rtsp.c
> +++ b/libavformat/rtsp.c
> @@ -389,16 +389,18 @@ typedef struct SDPParseState {
> } SDPParseState;
> static void copy_default_source_addrs(struct RTSPSource **addrs, int
> count,
> - struct RTSPSource ***dest, int
> *dest_count)
> + struct RTSPSource ***dest, int
> *dest_count, const char* sdp_ip_str)
Applying: libavformat/rtsp: Make source specific multicast work for rtsp streams
error: patch fragment without header at line 41: @@ -448,6 +450,8 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
error: could not build fake ancestor
Patch failed at 0001 libavformat/rtsp: Make source specific multicast work for rtsp streams
This patch is corrupted by line breaks
Check your editors line/word wraping settings
OR
attach the patch
OR
use git send-email
thx
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Many things microsoft did are stupid, but not doing something just because
microsoft did it is even more stupid. If everything ms did were stupid they
would be bankrupt already.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams
2025-02-17 8:46 ` [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams Michael Niedermayer
@ 2025-02-17 15:43 ` Rashad Tatum
0 siblings, 0 replies; 4+ messages in thread
From: Rashad Tatum @ 2025-02-17 15:43 UTC (permalink / raw)
To: FFmpeg development discussions and patches
[-- Attachment #1: Type: text/plain, Size: 2648 bytes --]
I'm not sure how this happened. I'll check my Thunderbird settings. For
now, I have attached the patches.
On Mon, Feb 17, 2025 at 3:46 AM Michael Niedermayer <michael@niedermayer.cc>
wrote:
> On Fri, Feb 14, 2025 at 12:08:24PM -0500, Rashad Tatum wrote:
> > by first changing the RTSPSource to track the destination address
> > obtained from the source filter. For each RTSPStream, only add the source
> > filter from the sdp if sdp_ip string matches source-filter's destination
> > address.
> >
> > Before issuing the setup request, change the lower_transport to
> > multicast if the sdp_ip is a multicast address.
> >
> > Change the multicast case to append sources (from the source-filter) to
> > the rtp url to make the source specific multicast join work.
> >
> > Signed-off-by: Rashad Tatum <tatum.rashad@gmail.com>
> > ---
> > libavformat/rtsp.c | 88 +++++++++++++++++++++++++++++++---------------
> > libavformat/rtsp.h | 3 +-
> > 2 files changed, 62 insertions(+), 29 deletions(-)
> >
> > diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
> > index 5ea471b40c..0c65f8d1a4 100644
> > --- a/libavformat/rtsp.c
> > +++ b/libavformat/rtsp.c
> > @@ -389,16 +389,18 @@ typedef struct SDPParseState {
> > } SDPParseState;
> > static void copy_default_source_addrs(struct RTSPSource **addrs, int
> > count,
> > - struct RTSPSource ***dest, int
> > *dest_count)
> > + struct RTSPSource ***dest, int
> > *dest_count, const char* sdp_ip_str)
>
> Applying: libavformat/rtsp: Make source specific multicast work for rtsp
> streams
> error: patch fragment without header at line 41: @@ -448,6 +450,8 @@
> static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
> error: could not build fake ancestor
> Patch failed at 0001 libavformat/rtsp: Make source specific multicast work
> for rtsp streams
>
> This patch is corrupted by line breaks
> Check your editors line/word wraping settings
> OR
> attach the patch
> OR
> use git send-email
>
> thx
>
> [...]
> --
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> Many things microsoft did are stupid, but not doing something just because
> microsoft did it is even more stupid. If everything ms did were stupid they
> would be bankrupt already.
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
[-- Attachment #2: 0001-libavformat-rtsp-Make-source-specific-multicast-work.patch --]
[-- Type: text/x-patch, Size: 9568 bytes --]
From f8617a40ecd2fe6bc0a755816270b72e81be8291 Mon Sep 17 00:00:00 2001
From: Rashad Tatum <tatum.rashad@gmail.com>
Date: Thu, 13 Feb 2025 20:31:34 -0500
Subject: [PATCH] libavformat/rtsp: Make source specific multicast work for
rtsp streams
by first changing the RTSPSource to track the destination address
obtained from the source filter. For each RTSPStream, only add the source
filter from the sdp if sdp_ip string matches source-filter's destination
address.
Before issuing the setup request, change the lower_transport to
multicast if the sdp_ip is a multicast address.
Change the multicast case to append sources (from the source-filter) to
the rtp url to make the source specific multicast join work.
---
libavformat/rtsp.c | 88 +++++++++++++++++++++++++++++++---------------
libavformat/rtsp.h | 3 +-
2 files changed, 62 insertions(+), 29 deletions(-)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 5ea471b40c..0c65f8d1a4 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -389,16 +389,18 @@ typedef struct SDPParseState {
} SDPParseState;
static void copy_default_source_addrs(struct RTSPSource **addrs, int count,
- struct RTSPSource ***dest, int *dest_count)
+ struct RTSPSource ***dest, int *dest_count, const char* sdp_ip_str)
{
RTSPSource *rtsp_src, *rtsp_src2;
int i;
for (i = 0; i < count; i++) {
rtsp_src = addrs[i];
- rtsp_src2 = av_memdup(rtsp_src, sizeof(*rtsp_src));
- if (!rtsp_src2)
- continue;
- dynarray_add(dest, dest_count, rtsp_src2);
+ if (strcmp(rtsp_src->dest_addr, sdp_ip_str) == 0) {
+ rtsp_src2 = av_memdup(rtsp_src, sizeof(*rtsp_src));
+ if (!rtsp_src2)
+ continue;
+ dynarray_add(dest, dest_count, rtsp_src2);
+ }
}
}
@@ -423,7 +425,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
{
RTSPState *rt = s->priv_data;
char buf1[64], st_type[64];
- const char *p;
+ const char *p, *sdp_ip_str, *dest_addr;
enum AVMediaType codec_type;
int payload_type;
AVStream *st;
@@ -448,6 +450,8 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
get_word_sep(buf1, sizeof(buf1), "/", &p);
if (get_sockaddr(s, buf1, &sdp_ip))
return;
+
+ sdp_ip_str = av_strdup(buf1);
ttl = 16;
if (*p == '/') {
p++;
@@ -461,6 +465,18 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
rtsp_st->sdp_ip = sdp_ip;
rtsp_st->sdp_ttl = ttl;
+
+ copy_default_source_addrs(s1->default_include_source_addrs,
+ s1->nb_default_include_source_addrs,
+ &rtsp_st->include_source_addrs,
+ &rtsp_st->nb_include_source_addrs,
+ sdp_ip_str);
+ copy_default_source_addrs(s1->default_exclude_source_addrs,
+ s1->nb_default_exclude_source_addrs,
+ &rtsp_st->exclude_source_addrs,
+ &rtsp_st->nb_exclude_source_addrs,
+ sdp_ip_str);
+
}
break;
case 's':
@@ -504,15 +520,6 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
rtsp_st->sdp_ip = s1->default_ip;
rtsp_st->sdp_ttl = s1->default_ttl;
- copy_default_source_addrs(s1->default_include_source_addrs,
- s1->nb_default_include_source_addrs,
- &rtsp_st->include_source_addrs,
- &rtsp_st->nb_include_source_addrs);
- copy_default_source_addrs(s1->default_exclude_source_addrs,
- s1->nb_default_exclude_source_addrs,
- &rtsp_st->exclude_source_addrs,
- &rtsp_st->nb_exclude_source_addrs);
-
get_word(buf1, sizeof(buf1), &p); /* port */
rtsp_st->sdp_port = atoi(buf1);
@@ -672,11 +679,13 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
// not checking that the destination address actually matches or is wildcard
get_word(buf1, sizeof(buf1), &p);
+ dest_addr = av_strdup(buf1);
while (*p != '\0') {
rtsp_src = av_mallocz(sizeof(*rtsp_src));
if (!rtsp_src)
return;
- get_word(rtsp_src->addr, sizeof(rtsp_src->addr), &p);
+ av_strlcpy(rtsp_src->dest_addr, dest_addr, sizeof(rtsp_src->dest_addr));
+ get_word(rtsp_src->src_addr, sizeof(rtsp_src->src_addr), &p);
if (exclude) {
if (s->nb_streams == 0) {
dynarray_add(&s1->default_exclude_source_addrs, &s1->nb_default_exclude_source_addrs, rtsp_src);
@@ -859,10 +868,11 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
rtsp_st->dynamic_protocol_context,
rtsp_st->dynamic_handler);
- else if (CONFIG_RTPDEC)
+ else if (CONFIG_RTPDEC) {
rtsp_st->transport_priv = ff_rtp_parse_open(s, st,
rtsp_st->sdp_payload_type,
reordering_queue_size);
+ }
if (!rtsp_st->transport_priv) {
return AVERROR(ENOMEM);
@@ -1452,6 +1462,18 @@ retry:
return 0;
}
+static void append_source_addrs(char *buf, int size, const char *name,
+ int count, struct RTSPSource **addrs)
+{
+ int i;
+ if (!count)
+ return;
+ av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->src_addr);
+ for (i = 1; i < count; i++) {
+ av_strlcatf(buf, size, ",%s", addrs[i]->src_addr);
+ }
+}
+
int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
int lower_transport, const char *real_challenge)
{
@@ -1510,6 +1532,11 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
} else
rtsp_st = rt->rtsp_streams[i];
+ /* RTP/UDP Source Specific Multicast (SSM) */
+ if (ff_is_multicast_address((struct sockaddr*) &rtsp_st->sdp_ip)) {
+ lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST;
+ }
+
/* RTP/UDP */
if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
char buf[256];
@@ -1666,7 +1693,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
break;
}
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
- char url[MAX_URL_SIZE], namebuf[50], optbuf[20] = "";
+ char url[MAX_URL_SIZE], namebuf[50], optbuf[1024] = "";
struct sockaddr_storage addr;
int port, ttl;
AVDictionary *opts = map_to_opts(rt);
@@ -1682,6 +1709,20 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
}
if (ttl > 0)
snprintf(optbuf, sizeof(optbuf), "?ttl=%d", ttl);
+
+ if (rtsp_st->nb_include_source_addrs > 0) {
+ if(strlen(optbuf) == 0 ) {
+ snprintf(optbuf, sizeof(optbuf), "?");
+ }
+
+ append_source_addrs(optbuf, sizeof(optbuf), "sources",
+ rtsp_st->nb_include_source_addrs,
+ rtsp_st->include_source_addrs);
+ append_source_addrs(optbuf, sizeof(optbuf), "block",
+ rtsp_st->nb_exclude_source_addrs,
+ rtsp_st->exclude_source_addrs);
+ }
+
getnameinfo((struct sockaddr*) &addr, sizeof(addr),
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
@@ -2383,16 +2424,7 @@ static int sdp_probe(const AVProbeData *p1)
return 0;
}
-static void append_source_addrs(char *buf, int size, const char *name,
- int count, struct RTSPSource **addrs)
-{
- int i;
- if (!count)
- return;
- av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
- for (i = 1; i < count; i++)
- av_strlcatf(buf, size, ",%s", addrs[i]->addr);
-}
+
static int sdp_read_header(AVFormatContext *s)
{
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 83b2e3f4fb..61de5cfb17 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -432,7 +432,8 @@ typedef struct RTSPState {
#define RTSP_FLAG_SATIP_RAW 0x20 /**< Export SAT>IP stream as raw MPEG-TS */
typedef struct RTSPSource {
- char addr[128]; /**< Source-specific multicast include source IP address (from SDP content) */
+ char dest_addr[128]; /**< Source-specific multicast destination IP address (from SDP content) */
+ char src_addr[128]; /**< Source-specific multicast include source IP address (from SDP content) */
} RTSPSource;
/**
--
2.48.1
[-- Attachment #3: 0001-libavformat-rtsp-Free-memory-allocated-for-temporary.patch --]
[-- Type: text/x-patch, Size: 1046 bytes --]
From ac0749deed8dc09409035d0c01b3873ace451fa4 Mon Sep 17 00:00:00 2001
From: Rashad Tatum <tatum.rashad@gmail.com>
Date: Fri, 14 Feb 2025 11:30:45 -0500
Subject: [PATCH] libavformat/rtsp: Free memory allocated for temporary
variables while processing sdp info
---
libavformat/rtsp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 0c65f8d1a4..da733938bc 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -478,6 +478,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
sdp_ip_str);
}
+ av_freep(sdp_ip_str);
break;
case 's':
av_dict_set(&s->metadata, "title", p, 0);
@@ -702,6 +703,7 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
}
}
}
+ av_freep(dest_addr);
} else {
if (rt->server_type == RTSP_SERVER_WMS)
ff_wms_parse_sdp_a_line(s, p);
--
2.48.1
[-- Attachment #4: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-02-17 15:43 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-02-14 17:08 [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams Rashad Tatum
2025-02-14 17:09 ` [FFmpeg-devel] [PATCH 2/2] libavformat/rtsp: Free memory allocated for temporary variables while processing sdp info Rashad Tatum
2025-02-17 8:46 ` [FFmpeg-devel] [PATCH 1/2] libavformat/rtsp: Make source specific multicast work for rtsp streams Michael Niedermayer
2025-02-17 15:43 ` Rashad Tatum
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git