* RTSP/SDP client
* Copyright (c) 2002 Fabrice Bellard
*
- * This file is part of FFmpeg.
+ * This file is part of Libav.
*
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/base64.h"
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "libavutil/random_seed.h"
+#include "libavutil/dict.h"
#include "avformat.h"
+#include "avio_internal.h"
#include <sys/time.h>
#if HAVE_POLL_H
#include "rdt.h"
#include "rtpdec_formats.h"
#include "rtpenc_chain.h"
+#include "url.h"
+#include "rtpenc.h"
//#define DEBUG
-//#define DEBUG_RTP_TCP
/* Timeout values for socket poll, in ms,
* and read_packet(), in seconds */
#define SDP_MAX_SIZE 16384
#define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
+#define OFFSET(x) offsetof(RTSPState, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+#define ENC AV_OPT_FLAG_ENCODING_PARAM
+
+#define RTSP_FLAG_OPTS(name, longname) \
+ { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
+ { "filter_src", "Only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }
+
+const AVOption ff_rtsp_options[] = {
+ { "initial_pause", "Don't start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_INT, {0}, 0, 1, DEC },
+ FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
+ { "rtsp_transport", "RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {0}, INT_MIN, INT_MAX, DEC|ENC, "rtsp_transport" }, \
+ { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
+ { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
+ { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
+ { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {(1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
+ RTSP_FLAG_OPTS("rtsp_flags", "RTSP flags"),
+ { NULL },
+};
+
+static const AVOption sdp_options[] = {
+ RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
+ { NULL },
+};
+
+static const AVOption rtp_options[] = {
+ RTSP_FLAG_OPTS("rtp_flags", "RTP flags"),
+ { NULL },
+};
+
static void get_word_until_chars(char *buf, int buf_size,
const char *sep, const char **pp)
{
return;
codec->codec_id = handler->codec_id;
rtsp_st->dynamic_handler = handler;
- if (handler->open)
- rtsp_st->dynamic_protocol_context = handler->open();
+ if (handler->alloc)
+ rtsp_st->dynamic_protocol_context = handler->alloc();
}
/* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
}
break;
case 's':
- av_metadata_set2(&s->metadata, "title", p, 0);
+ av_dict_set(&s->metadata, "title", p, 0);
break;
case 'i':
if (s->nb_streams == 0) {
- av_metadata_set2(&s->metadata, "comment", p, 0);
+ av_dict_set(&s->metadata, "comment", p, 0);
break;
}
break;
if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
/* no corresponding stream */
} else {
- st = av_new_stream(s, rt->nb_rtsp_streams - 1);
+ st = avformat_new_stream(s, NULL);
if (!st)
return;
+ st->id = rt->nb_rtsp_streams - 1;
rtsp_st->stream_index = st->index;
st->codec->codec_type = codec_type;
if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
}
}
-/**
- * Parse the sdp description and allocate the rtp streams and the
- * pollfd array used for udp ones.
- */
-
int ff_sdp_parse(AVFormatContext *s, const char *content)
{
RTSPState *rt = s->priv_data;
av_write_trailer(rtpctx);
if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
uint8_t *ptr;
- url_close_dyn_buf(rtpctx->pb, &ptr);
+ avio_close_dyn_buf(rtpctx->pb, &ptr);
av_free(ptr);
} else {
- url_fclose(rtpctx->pb);
+ avio_close(rtpctx->pb);
}
avformat_free_context(rtpctx);
} else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
ff_rdt_parse_close(rtsp_st->transport_priv);
else if (CONFIG_RTPDEC)
- rtp_parse_close(rtsp_st->transport_priv);
+ ff_rtp_parse_close(rtsp_st->transport_priv);
}
rtsp_st->transport_priv = NULL;
if (rtsp_st->rtp_handle)
- url_close(rtsp_st->rtp_handle);
+ ffurl_close(rtsp_st->rtp_handle);
rtsp_st->rtp_handle = NULL;
}
}
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st) {
if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
- rtsp_st->dynamic_handler->close(
+ rtsp_st->dynamic_handler->free(
rtsp_st->dynamic_protocol_context);
av_free(rtsp_st);
}
rtsp_st->dynamic_protocol_context,
rtsp_st->dynamic_handler);
else if (CONFIG_RTPDEC)
- rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle,
+ rtsp_st->transport_priv = ff_rtp_parse_open(s, st, rtsp_st->rtp_handle,
rtsp_st->sdp_payload_type,
(rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay)
? 0 : RTP_REORDER_QUEUE_DEFAULT_SIZE);
return AVERROR(ENOMEM);
} else if (rt->transport != RTSP_TRANSPORT_RDT && CONFIG_RTPDEC) {
if (rtsp_st->dynamic_handler) {
- rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
- rtsp_st->dynamic_protocol_context,
- rtsp_st->dynamic_handler);
+ ff_rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
+ rtsp_st->dynamic_protocol_context,
+ rtsp_st->dynamic_handler);
}
}
if (!strcmp(key, "url"))
av_strlcpy(url, value, sizeof(url));
else if (!strcmp(key, "seq"))
- seq = strtol(value, NULL, 10);
+ seq = strtoul(value, NULL, 10);
else if (!strcmp(key, "rtptime"))
- rtptime = strtol(value, NULL, 10);
+ rtptime = strtoul(value, NULL, 10);
if (*p == ',') {
handle_rtp_info(rt, url, seq, rtptime);
url[0] = '\0';
p += strspn(p, SPACE_CHARS);
if (method && !strcmp(method, "PLAY"))
rtsp_parse_rtp_info(rt, p);
+ } else if (av_stristart(p, "Public:", &p) && rt) {
+ if (strstr(p, "GET_PARAMETER") &&
+ method && !strcmp(method, "OPTIONS"))
+ rt->get_parameter_supported = 1;
+ } else if (av_stristart(p, "x-Accept-Dynamic-Rate:", &p) && rt) {
+ p += strspn(p, SPACE_CHARS);
+ rt->accept_dynamic_rate = atoi(p);
}
}
int ret, len, len1;
uint8_t buf[1024];
- ret = url_read_complete(rt->rtsp_hd, buf, 3);
+ ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
if (ret != 3)
return;
len = AV_RB16(buf + 1);
len1 = len;
if (len1 > sizeof(buf))
len1 = sizeof(buf);
- ret = url_read_complete(rt->rtsp_hd, buf, len1);
+ ret = ffurl_read_complete(rt->rtsp_hd, buf, len1);
if (ret != len1)
return;
len -= len1;
for (;;) {
q = buf;
for (;;) {
- ret = url_read_complete(rt->rtsp_hd, &ch, 1);
-#ifdef DEBUG_RTP_TCP
+ ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1);
av_dlog(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
-#endif
if (ret != 1)
return AVERROR_EOF;
if (ch == '\n')
if (content_length > 0) {
/* leave some room for a trailing '\0' (useful for simple parsing) */
content = av_malloc(content_length + 1);
- (void)url_read_complete(rt->rtsp_hd, content, content_length);
+ ffurl_read_complete(rt->rtsp_hd, content, content_length);
content[content_length] = '\0';
}
if (content_ptr)
av_dlog(s, "Sending:\n%s--\n", buf);
- url_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
+ ffurl_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
if (send_content_length > 0 && send_content) {
if (rt->control_transport == RTSP_MODE_TUNNEL) {
av_log(s, AV_LOG_ERROR, "tunneling of RTSP requests "
"with content data not supported\n");
return AVERROR_PATCHWELCOME;
}
- url_write(rt->rtsp_hd_out, send_content, send_content_length);
+ ffurl_write(rt->rtsp_hd_out, send_content, send_content_length);
}
rt->last_cmd_time = av_gettime();
return 0;
}
-/**
- * @return 0 on success, <0 on error, 1 if protocol is unavailable.
- */
int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
int lower_transport, const char *real_challenge)
{
for (j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) {
char transport[2048];
- /**
+ /*
* 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.
"?localport=%d", j);
/* we will use two ports per rtp stream (rtp and rtcp) */
j += 2;
- if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0)
+ if (ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE) == 0)
goto rtp_opened;
}
}
-#if 0
- /* then try on any port */
- if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) {
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
-#else
av_log(s, AV_LOG_ERROR, "Unable to open an input RTP port\n");
err = AVERROR(EIO);
goto fail;
-#endif
rtp_opened:
- port = rtp_get_local_rtp_port(rtsp_st->rtp_handle);
+ port = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
have_port:
snprintf(transport, sizeof(transport) - 1,
"%s/UDP;", trans_pref);
/* RTP/TCP */
else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
- /** For WMS streams, the application streams are only used for
+ /* For WMS streams, the application streams are only used for
* UDP. When trying to set it up for TCP streams, the server
* will return an error. Therefore, we skip those streams. */
if (rt->server_type == RTSP_SERVER_WMS &&
continue;
snprintf(transport, sizeof(transport) - 1,
"%s/TCP;", trans_pref);
- if (rt->server_type == RTSP_SERVER_WMS)
+ if (rt->transport != RTSP_TRANSPORT_RDT)
av_strlcat(transport, "unicast;", sizeof(transport));
av_strlcatf(transport, sizeof(transport),
"interleaved=%d-%d",
snprintf(cmd, sizeof(cmd),
"Transport: %s\r\n",
transport);
+ if (rt->accept_dynamic_rate)
+ av_strlcat(cmd, "x-Dynamic-Rate: 0\r\n", sizeof(cmd));
if (i == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {
char real_res[41], real_csum[9];
ff_rdt_calc_response_and_checksum(real_res, real_csum,
case RTSP_LOWER_TRANSPORT_UDP: {
char url[1024], options[30] = "";
- if (rt->filter_source)
+ if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
av_strlcpy(options, "?connect=1", sizeof(options));
/* Use source address if specified */
if (reply->transports[0].source[0]) {
ff_url_join(url, sizeof(url), "rtp", NULL,
reply->transports[0].source,
- reply->transports[0].server_port_min, options);
+ reply->transports[0].server_port_min, "%s", options);
} else {
ff_url_join(url, sizeof(url), "rtp", NULL, host,
- reply->transports[0].server_port_min, options);
+ reply->transports[0].server_port_min, "%s", options);
}
if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
- rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
+ ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
*/
if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat &&
CONFIG_RTPDEC)
- rtp_send_punch_packets(rtsp_st->rtp_handle);
+ ff_rtp_send_punch_packets(rtsp_st->rtp_handle);
break;
}
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
port, "?ttl=%d", ttl);
- if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
+ if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
void ff_rtsp_close_connections(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
- if (rt->rtsp_hd_out != rt->rtsp_hd) url_close(rt->rtsp_hd_out);
- url_close(rt->rtsp_hd);
+ if (rt->rtsp_hd_out != rt->rtsp_hd) ffurl_close(rt->rtsp_hd_out);
+ ffurl_close(rt->rtsp_hd);
rt->rtsp_hd = rt->rtsp_hd_out = NULL;
}
if (!ff_network_init())
return AVERROR(EIO);
-redirect:
+
rt->control_transport = RTSP_MODE_PLAIN;
+ if (rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_HTTP)) {
+ rt->lower_transport_mask = 1 << RTSP_LOWER_TRANSPORT_TCP;
+ rt->control_transport = RTSP_MODE_TUNNEL;
+ }
+ /* Only pass through valid flags from here */
+ rt->lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
+
+redirect:
+ lower_transport_mask = rt->lower_transport_mask;
/* extract hostname and port */
av_url_split(NULL, 0, auth, sizeof(auth),
host, sizeof(host), &port, path, sizeof(path), s->filename);
if (port < 0)
port = RTSP_DEFAULT_PORT;
+#if FF_API_RTSP_URL_OPTIONS
/* search for options */
option_list = strrchr(path, '?');
if (option_list) {
* the options back into the same string. */
filename = option_list;
while (option_list) {
+ int handled = 1;
/* move the option pointer */
option = ++option_list;
option_list = strchr(option_list, '&');
lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP);
rt->control_transport = RTSP_MODE_TUNNEL;
} else if (!strcmp(option, "filter_src")) {
- rt->filter_source = 1;
+ rt->rtsp_flags |= RTSP_FLAG_FILTER_SRC;
} else {
/* Write options back into the buffer, using memmove instead
* of strcpy since the strings may overlap. */
memmove(++filename, option, len);
filename += len;
if (option_list) *filename = '&';
+ handled = 0;
}
+ if (handled)
+ av_log(s, AV_LOG_WARNING, "Options passed via URL are "
+ "deprecated, use -rtsp_transport "
+ "and -rtsp_flags instead.\n");
}
*filename = 0;
}
+#endif
if (!lower_transport_mask)
lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
av_get_random_seed(), av_get_random_seed());
/* GET requests */
- if (url_alloc(&rt->rtsp_hd, httpname, URL_RDONLY) < 0) {
+ if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ) < 0) {
err = AVERROR(EIO);
goto fail;
}
ff_http_set_headers(rt->rtsp_hd, headers);
/* complete the connection */
- if (url_connect(rt->rtsp_hd)) {
+ if (ffurl_connect(rt->rtsp_hd)) {
err = AVERROR(EIO);
goto fail;
}
/* POST requests */
- if (url_alloc(&rt->rtsp_hd_out, httpname, URL_WRONLY) < 0 ) {
+ if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE) < 0 ) {
err = AVERROR(EIO);
goto fail;
}
ff_http_init_auth_state(rt->rtsp_hd_out, rt->rtsp_hd);
/* complete the connection */
- if (url_connect(rt->rtsp_hd_out)) {
+ if (ffurl_connect(rt->rtsp_hd_out)) {
err = AVERROR(EIO);
goto fail;
}
} else {
/* open the tcp connection */
ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL);
- if (url_open(&rt->rtsp_hd, tcpname, URL_RDWR) < 0) {
+ if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE) < 0) {
err = AVERROR(EIO);
goto fail;
}
}
rt->seq = 0;
- tcp_fd = url_get_file_handle(rt->rtsp_hd);
+ tcp_fd = ffurl_get_file_handle(rt->rtsp_hd);
if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
NULL, 0, NI_NUMERICHOST);
cmd[0] = 0;
if (rt->server_type == RTSP_SERVER_REAL)
av_strlcat(cmd,
- /**
+ /*
* The following entries are required for proper
* streaming from a Realmedia server. They are
* interdependent in some way although we currently
* don't quite understand how. Values were copied
* from mplayer SVN r23589.
- * @param CompanyID is a 16-byte ID in base64
- * @param ClientChallenge is a 16-byte ID in hex
+ * ClientChallenge is a 16-byte ID in hex
+ * CompanyID is a 16-byte ID in base64
*/
"ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
"PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
goto fail;
lower_transport_mask &= ~(1 << lower_transport);
if (lower_transport_mask == 0 && err == 1) {
- err = FF_NETERROR(EPROTONOSUPPORT);
+ err = AVERROR(EPROTONOSUPPORT);
goto fail;
}
} while (err);
for (;;) {
if (url_interrupt_cb())
- return AVERROR(EINTR);
+ return AVERROR_EXIT;
if (wait_end && wait_end - av_gettime() < 0)
return AVERROR(EAGAIN);
max_p = 0;
if (rt->rtsp_hd) {
- tcp_fd = url_get_file_handle(rt->rtsp_hd);
+ tcp_fd = ffurl_get_file_handle(rt->rtsp_hd);
p[max_p].fd = tcp_fd;
p[max_p++].events = POLLIN;
} else {
for (i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st->rtp_handle) {
- p[max_p].fd = url_get_file_handle(rtsp_st->rtp_handle);
+ p[max_p].fd = ffurl_get_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN;
- p[max_p].fd = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
+ p[max_p].fd = ff_rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
p[max_p++].events = POLLIN;
}
}
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st->rtp_handle) {
if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
- ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
+ ret = ffurl_read(rtsp_st->rtp_handle, buf, buf_size);
if (ret > 0) {
*prtsp_st = rtsp_st;
return ret;
}
#endif
} else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
- return FF_NETERROR(ETIMEDOUT);
+ return AVERROR(ETIMEDOUT);
} else if (n < 0 && errno != EINTR)
return AVERROR(errno);
}
if (rt->transport == RTSP_TRANSPORT_RDT) {
ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
} else
- ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
+ ret = ff_rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
if (ret == 0) {
rt->cur_transport_priv = NULL;
return 0;
case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
- rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
+ ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
break;
}
if (len == AVERROR(EAGAIN) && first_queue_st &&
rt->transport == RTSP_TRANSPORT_RTP) {
rtsp_st = first_queue_st;
- ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
+ ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
goto end;
}
if (len < 0)
if (rt->transport == RTSP_TRANSPORT_RDT) {
ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
} else {
- ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
+ ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
if (ret < 0) {
/* Either bad packet, or a RTCP packet. Check if the
* first_rtcp_ntp_time field was initialized. */
/* read the whole sdp file */
/* XXX: better loading */
content = av_malloc(SDP_MAX_SIZE);
- size = get_buffer(s->pb, content, SDP_MAX_SIZE - 1);
+ size = avio_read(s->pb, content, SDP_MAX_SIZE - 1);
if (size <= 0) {
av_free(content);
return AVERROR_INVALIDDATA;
namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
ff_url_join(url, sizeof(url), "rtp", NULL,
namebuf, rtsp_st->sdp_port,
- "?localport=%d&ttl=%d", rtsp_st->sdp_port,
- rtsp_st->sdp_ttl);
- if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
+ "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port,
+ rtsp_st->sdp_ttl,
+ rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0);
+ if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
return 0;
}
+static const AVClass sdp_demuxer_class = {
+ .class_name = "SDP demuxer",
+ .item_name = av_default_item_name,
+ .option = sdp_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_sdp_demuxer = {
- "sdp",
- NULL_IF_CONFIG_SMALL("SDP"),
- sizeof(RTSPState),
- sdp_probe,
- sdp_read_header,
- ff_rtsp_fetch_packet,
- sdp_read_close,
+ .name = "sdp",
+ .long_name = NULL_IF_CONFIG_SMALL("SDP"),
+ .priv_data_size = sizeof(RTSPState),
+ .read_probe = sdp_probe,
+ .read_header = sdp_read_header,
+ .read_packet = ff_rtsp_fetch_packet,
+ .read_close = sdp_read_close,
+ .priv_class = &sdp_demuxer_class
};
#endif /* CONFIG_SDP_DEMUXER */
if (!ff_network_init())
return AVERROR(EIO);
- ret = url_open(&in, s->filename, URL_RDONLY);
+ ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ);
if (ret)
goto fail;
while (1) {
- ret = url_read(in, recvbuf, sizeof(recvbuf));
+ ret = ffurl_read(in, recvbuf, sizeof(recvbuf));
if (ret == AVERROR(EAGAIN))
continue;
if (ret < 0)
payload_type = recvbuf[1] & 0x7f;
break;
}
- getsockname(url_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
- url_close(in);
+ getsockname(ffurl_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
+ ffurl_close(in);
in = NULL;
memset(&codec, 0, sizeof(codec));
port, payload_type);
av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
- init_put_byte(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
+ ffio_init_context(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
s->pb = &pb;
/* sdp_read_header initializes this again */
fail:
if (in)
- url_close(in);
+ ffurl_close(in);
ff_network_close();
return ret;
}
+static const AVClass rtp_demuxer_class = {
+ .class_name = "RTP demuxer",
+ .item_name = av_default_item_name,
+ .option = rtp_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
AVInputFormat ff_rtp_demuxer = {
- "rtp",
- NULL_IF_CONFIG_SMALL("RTP input format"),
- sizeof(RTSPState),
- rtp_probe,
- rtp_read_header,
- ff_rtsp_fetch_packet,
- sdp_read_close,
+ .name = "rtp",
+ .long_name = NULL_IF_CONFIG_SMALL("RTP input format"),
+ .priv_data_size = sizeof(RTSPState),
+ .read_probe = rtp_probe,
+ .read_header = rtp_read_header,
+ .read_packet = ff_rtsp_fetch_packet,
+ .read_close = sdp_read_close,
.flags = AVFMT_NOFILE,
+ .priv_class = &rtp_demuxer_class
};
#endif /* CONFIG_RTP_DEMUXER */