#include "rtpproto.h"
#include "rtsp.h"
#include "rdt.h"
+#include "tls.h"
#include "url.h"
static const struct RTSPStatusMessage {
if (extracontent)
av_strlcat(message, extracontent, sizeof(message));
av_strlcat(message, "\r\n", sizeof(message));
- av_dlog(s, "Sending response:\n%s", message);
- ffurl_write(rt->rtsp_hd, message, strlen(message));
+ av_log(s, AV_LOG_TRACE, "Sending response:\n%s", message);
+ ffurl_write(rt->rtsp_hd_out, message, strlen(message));
return 0;
}
if (ret)
return ret;
if (rbuflen > 1) {
- av_dlog(s, "Parsing[%d]: %s\n", rbuflen, rbuf);
+ av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
ff_rtsp_parse_line(request, rbuf, rt, method);
}
} while (rbuflen > 0);
request.transports[0].interleaved_max);
} else {
do {
+ AVDictionary *opts = NULL;
+ char buf[256];
+ snprintf(buf, sizeof(buf), "%d", rt->buffer_size);
+ av_dict_set(&opts, "buffer_size", buf, 0);
ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
- av_dlog(s, "Opening: %s", url);
+ av_log(s, AV_LOG_TRACE, "Opening: %s", url);
ret = ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
- &s->interrupt_callback, NULL);
+ &s->interrupt_callback, &opts);
+ av_dict_free(&opts);
if (ret)
localport += 2;
} while (ret || localport > rt->rtp_port_max);
return ret;
}
- av_dlog(s, "Listening on: %d",
+ av_log(s, AV_LOG_TRACE, "Listening on: %d",
ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle));
if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
RTSPState *rt = s->priv_data;
const char *linept, *searchlinept;
linept = strchr(line, ' ');
+
+ if (!linept)
+ return AVERROR_INVALIDDATA;
+
if (linept - line > methodsize - 1) {
av_log(s, AV_LOG_ERROR, "Method string too long\n");
return AVERROR(EIO);
}
searchlinept = strchr(linept, ' ');
- if (searchlinept == NULL) {
+ if (!searchlinept) {
av_log(s, AV_LOG_ERROR, "Error parsing message URI\n");
return AVERROR_INVALIDDATA;
}
av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
rt->nb_byes = 0;
+ if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
+ for (i = 0; i < rt->nb_rtsp_streams; i++) {
+ RTSPStream *rtsp_st = rt->rtsp_streams[i];
+ /* Try to initialize the connection state in a
+ * potential NAT router by sending dummy packets.
+ * RTP/RTCP dummy packets are used for RDT, too.
+ */
+ if (rtsp_st->rtp_handle &&
+ !(rt->server_type == RTSP_SERVER_WMS && i > 1))
+ ff_rtp_send_punch_packets(rtsp_st->rtp_handle);
+ }
+ }
if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
if (rt->transport == RTSP_TRANSPORT_RTP) {
for (i = 0; i < rt->nb_rtsp_streams; i++) {
static int rtsp_listen(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
- char host[128], path[512], auth[128];
+ char proto[128], host[128], path[512], auth[128];
char uri[500];
int port;
+ int default_port = RTSP_DEFAULT_PORT;
char tcpname[500];
+ const char *lower_proto = "tcp";
unsigned char rbuf[4096];
unsigned char method[10];
int rbuflen = 0;
enum RTSPMethod methodcode;
/* extract hostname and port */
- av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
- path, sizeof(path), s->filename);
+ av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
+ &port, path, sizeof(path), s->filename);
/* ff_url_join. No authorization by now (NULL) */
- ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL, host,
+ ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
port, "%s", path);
+ if (!strcmp(proto, "rtsps")) {
+ lower_proto = "tls";
+ default_port = RTSPS_DEFAULT_PORT;
+ }
+
if (port < 0)
- port = RTSP_DEFAULT_PORT;
+ port = default_port;
/* Create TCP connection */
- ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port,
+ ff_url_join(tcpname, sizeof(tcpname), lower_proto, NULL, host, port,
"?listen&listen_timeout=%d", rt->initial_timeout * 1000);
if (ret = ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
static int rtsp_probe(AVProbeData *p)
{
- if (av_strstart(p->filename, "rtsp:", NULL))
+ if (
+#if CONFIG_TLS_PROTOCOL
+ av_strstart(p->filename, "rtsps:", NULL) ||
+#endif
+ av_strstart(p->filename, "rtsp:", NULL))
return AVPROBE_SCORE_MAX;
return 0;
}
int id, len, i, ret;
RTSPStream *rtsp_st;
- av_dlog(s, "tcp_read_packet:\n");
+ av_log(s, AV_LOG_TRACE, "tcp_read_packet:\n");
redo:
for (;;) {
RTSPMessageHeader reply;
return -1;
id = buf[0];
len = AV_RB16(buf + 1);
- av_dlog(s, "id=%d len=%d\n", id, len);
+ av_log(s, AV_LOG_TRACE, "id=%d len=%d\n", id, len);
if (len > buf_size || len < 12)
goto redo;
/* get the data */
if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
/* send dummy request to keep TCP connection alive */
- if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
+ if ((av_gettime_relative() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
rt->auth_state.stale) {
if (rt->server_type == RTSP_SERVER_WMS ||
(rt->server_type != RTSP_SERVER_REAL &&