rtp: Map the urloptions to AVOptions
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
This commit is contained in:
parent
4978850ca2
commit
3c47e7c435
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "libavutil/parseutils.h"
|
#include "libavutil/parseutils.h"
|
||||||
#include "libavutil/avstring.h"
|
#include "libavutil/avstring.h"
|
||||||
|
#include "libavutil/opt.h"
|
||||||
#include "avformat.h"
|
#include "avformat.h"
|
||||||
#include "avio_internal.h"
|
#include "avio_internal.h"
|
||||||
#include "rtp.h"
|
#include "rtp.h"
|
||||||
@ -42,14 +43,44 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct RTPContext {
|
typedef struct RTPContext {
|
||||||
|
const AVClass *class;
|
||||||
URLContext *rtp_hd, *rtcp_hd;
|
URLContext *rtp_hd, *rtcp_hd;
|
||||||
int rtp_fd, rtcp_fd, nb_ssm_include_addrs, nb_ssm_exclude_addrs;
|
int rtp_fd, rtcp_fd, nb_ssm_include_addrs, nb_ssm_exclude_addrs;
|
||||||
struct sockaddr_storage **ssm_include_addrs, **ssm_exclude_addrs;
|
struct sockaddr_storage **ssm_include_addrs, **ssm_exclude_addrs;
|
||||||
int write_to_source;
|
int write_to_source;
|
||||||
struct sockaddr_storage last_rtp_source, last_rtcp_source;
|
struct sockaddr_storage last_rtp_source, last_rtcp_source;
|
||||||
socklen_t last_rtp_source_len, last_rtcp_source_len;
|
socklen_t last_rtp_source_len, last_rtcp_source_len;
|
||||||
|
int ttl;
|
||||||
|
int rtcp_port, local_rtpport, local_rtcpport;
|
||||||
|
int connect;
|
||||||
|
int pkt_size;
|
||||||
|
char *sources;
|
||||||
|
char *block;
|
||||||
} RTPContext;
|
} RTPContext;
|
||||||
|
|
||||||
|
#define OFFSET(x) offsetof(RTPContext, x)
|
||||||
|
#define D AV_OPT_FLAG_DECODING_PARAM
|
||||||
|
#define E AV_OPT_FLAG_ENCODING_PARAM
|
||||||
|
static const AVOption options[] = {
|
||||||
|
{ "ttl", "Time to live (in milliseconds, multicast only)", OFFSET(ttl), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
|
||||||
|
{ "rtcp_port", "Custom rtcp port", OFFSET(rtcp_port), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
|
||||||
|
{ "local_rtpport", "Local rtp port", OFFSET(local_rtpport), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
|
||||||
|
{ "local_rtcpport", "Local rtcp port", OFFSET(local_rtcpport), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
|
||||||
|
{ "connect", "Connect socket", OFFSET(connect), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = D|E },
|
||||||
|
{ "write_to_source", "Send packets to the source address of the latest received packet", OFFSET(write_to_source), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = D|E },
|
||||||
|
{ "pkt_size", "Maximum packet size", OFFSET(pkt_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
|
||||||
|
{ "sources", "Source list", OFFSET(sources), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
|
||||||
|
{ "block", "Block list", OFFSET(block), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const AVClass rtp_class = {
|
||||||
|
.class_name = "rtp",
|
||||||
|
.item_name = av_default_item_name,
|
||||||
|
.option = options,
|
||||||
|
.version = LIBAVUTIL_VERSION_INT,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If no filename is given to av_open_input_file because you want to
|
* If no filename is given to av_open_input_file because you want to
|
||||||
* get the local port first, then you must call this function to set
|
* get the local port first, then you must call this function to set
|
||||||
@ -188,21 +219,21 @@ static av_printf_format(3, 4) void url_add_option(char *buf, int buf_size, const
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void build_udp_url(char *buf, int buf_size,
|
static void build_udp_url(RTPContext *s,
|
||||||
const char *hostname, int port,
|
char *buf, int buf_size,
|
||||||
int local_port, int ttl,
|
const char *hostname,
|
||||||
int max_packet_size, int connect,
|
int port, int local_port,
|
||||||
const char *include_sources,
|
const char *include_sources,
|
||||||
const char *exclude_sources)
|
const char *exclude_sources)
|
||||||
{
|
{
|
||||||
ff_url_join(buf, buf_size, "udp", NULL, hostname, port, NULL);
|
ff_url_join(buf, buf_size, "udp", NULL, hostname, port, NULL);
|
||||||
if (local_port >= 0)
|
if (local_port >= 0)
|
||||||
url_add_option(buf, buf_size, "localport=%d", local_port);
|
url_add_option(buf, buf_size, "localport=%d", local_port);
|
||||||
if (ttl >= 0)
|
if (s->ttl >= 0)
|
||||||
url_add_option(buf, buf_size, "ttl=%d", ttl);
|
url_add_option(buf, buf_size, "ttl=%d", s->ttl);
|
||||||
if (max_packet_size >=0)
|
if (s->pkt_size >= 0)
|
||||||
url_add_option(buf, buf_size, "pkt_size=%d", max_packet_size);
|
url_add_option(buf, buf_size, "pkt_size=%d", s->pkt_size);
|
||||||
if (connect)
|
if (s->connect)
|
||||||
url_add_option(buf, buf_size, "connect=1");
|
url_add_option(buf, buf_size, "connect=1");
|
||||||
if (include_sources && include_sources[0])
|
if (include_sources && include_sources[0])
|
||||||
url_add_option(buf, buf_size, "sources=%s", include_sources);
|
url_add_option(buf, buf_size, "sources=%s", include_sources);
|
||||||
@ -275,10 +306,9 @@ static void rtp_parse_addr_list(URLContext *h, char *buf,
|
|||||||
static int rtp_open(URLContext *h, const char *uri, int flags)
|
static int rtp_open(URLContext *h, const char *uri, int flags)
|
||||||
{
|
{
|
||||||
RTPContext *s = h->priv_data;
|
RTPContext *s = h->priv_data;
|
||||||
int rtp_port, rtcp_port,
|
int rtp_port;
|
||||||
ttl, connect,
|
|
||||||
local_rtp_port, local_rtcp_port, max_packet_size;
|
|
||||||
char hostname[256], include_sources[1024] = "", exclude_sources[1024] = "";
|
char hostname[256], include_sources[1024] = "", exclude_sources[1024] = "";
|
||||||
|
char *sources = include_sources, *block = exclude_sources;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
char path[1024];
|
char path[1024];
|
||||||
const char *p;
|
const char *p;
|
||||||
@ -286,60 +316,61 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
|
|||||||
av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
|
av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
|
||||||
path, sizeof(path), uri);
|
path, sizeof(path), uri);
|
||||||
/* extract parameters */
|
/* extract parameters */
|
||||||
ttl = -1;
|
if (s->rtcp_port < 0)
|
||||||
rtcp_port = rtp_port+1;
|
s->rtcp_port = rtp_port + 1;
|
||||||
local_rtp_port = -1;
|
|
||||||
local_rtcp_port = -1;
|
|
||||||
max_packet_size = -1;
|
|
||||||
connect = 0;
|
|
||||||
|
|
||||||
p = strchr(uri, '?');
|
p = strchr(uri, '?');
|
||||||
if (p) {
|
if (p) {
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
|
||||||
ttl = strtol(buf, NULL, 10);
|
s->ttl = strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
|
||||||
rtcp_port = strtol(buf, NULL, 10);
|
s->rtcp_port = strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
|
||||||
local_rtp_port = strtol(buf, NULL, 10);
|
s->local_rtpport = strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) {
|
||||||
local_rtp_port = strtol(buf, NULL, 10);
|
s->local_rtpport = strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "localrtcpport", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "localrtcpport", p)) {
|
||||||
local_rtcp_port = strtol(buf, NULL, 10);
|
s->local_rtcpport = strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
|
||||||
max_packet_size = strtol(buf, NULL, 10);
|
s->pkt_size = strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
|
||||||
connect = strtol(buf, NULL, 10);
|
s->connect = strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) {
|
||||||
s->write_to_source = strtol(buf, NULL, 10);
|
s->write_to_source = strtol(buf, NULL, 10);
|
||||||
}
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
|
||||||
av_strlcpy(include_sources, buf, sizeof(include_sources));
|
av_strlcpy(include_sources, buf, sizeof(include_sources));
|
||||||
|
|
||||||
rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
|
rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
|
||||||
|
} else {
|
||||||
|
rtp_parse_addr_list(h, s->sources, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
|
||||||
|
sources = s->sources;
|
||||||
}
|
}
|
||||||
if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
|
if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
|
||||||
av_strlcpy(exclude_sources, buf, sizeof(exclude_sources));
|
av_strlcpy(exclude_sources, buf, sizeof(exclude_sources));
|
||||||
rtp_parse_addr_list(h, buf, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs);
|
rtp_parse_addr_list(h, buf, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs);
|
||||||
|
} else {
|
||||||
|
rtp_parse_addr_list(h, s->block, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs);
|
||||||
|
block = s->block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
build_udp_url(buf, sizeof(buf),
|
build_udp_url(s, buf, sizeof(buf),
|
||||||
hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
|
hostname, rtp_port, s->local_rtpport, sources, block);
|
||||||
connect, include_sources, exclude_sources);
|
|
||||||
if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
|
if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (local_rtp_port>=0 && local_rtcp_port<0)
|
if (s->local_rtpport >= 0 && s->local_rtcpport < 0)
|
||||||
local_rtcp_port = ff_udp_get_local_port(s->rtp_hd) + 1;
|
s->local_rtcpport = ff_udp_get_local_port(s->rtp_hd) + 1;
|
||||||
|
|
||||||
build_udp_url(buf, sizeof(buf),
|
build_udp_url(s, buf, sizeof(buf),
|
||||||
hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
|
hostname, s->rtcp_port, s->local_rtcpport, sources, block);
|
||||||
connect, include_sources, exclude_sources);
|
|
||||||
if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
|
if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -548,4 +579,5 @@ URLProtocol ff_rtp_protocol = {
|
|||||||
.url_get_multi_file_handle = rtp_get_multi_file_handle,
|
.url_get_multi_file_handle = rtp_get_multi_file_handle,
|
||||||
.priv_data_size = sizeof(RTPContext),
|
.priv_data_size = sizeof(RTPContext),
|
||||||
.flags = URL_PROTOCOL_FLAG_NETWORK,
|
.flags = URL_PROTOCOL_FLAG_NETWORK,
|
||||||
|
.priv_data_class = &rtp_class,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user