*end = AV_NOPTS_VALUE;
get_word_sep(buf, sizeof(buf), "-", &p);
- av_parse_time(start, buf, 1);
+ if (av_parse_time(start, buf, 1) < 0)
+ return;
if (*p == '-') {
p++;
get_word_sep(buf, sizeof(buf), "-", &p);
}
}
-static int get_sockaddr(const char *buf, struct sockaddr_storage *sock)
+static int get_sockaddr(AVFormatContext *s,
+ const char *buf, struct sockaddr_storage *sock)
{
struct addrinfo hints = { 0 }, *ai = NULL;
+ int ret;
+
hints.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(buf, NULL, &hints, &ai))
+ if ((ret = getaddrinfo(buf, NULL, &hints, &ai))) {
+ av_log(s, AV_LOG_ERROR, "getaddrinfo(%s): %s\n",
+ buf,
+ gai_strerror(ret));
return -1;
+ }
memcpy(sock, ai->ai_addr, FFMIN(sizeof(*sock), ai->ai_addrlen));
freeaddrinfo(ai);
return 0;
static void init_rtp_handler(RTPDynamicProtocolHandler *handler,
RTSPStream *rtsp_st, AVStream *st)
{
- AVCodecContext *codec = st ? st->codec : NULL;
+ AVCodecParameters *par = st ? st->codecpar : NULL;
if (!handler)
return;
- if (codec)
- codec->codec_id = handler->codec_id;
+ if (par)
+ par->codec_id = handler->codec_id;
rtsp_st->dynamic_handler = handler;
if (st)
st->need_parsing = handler->need_parsing;
AVStream *st, RTSPStream *rtsp_st,
int payload_type, const char *p)
{
- AVCodecContext *codec = st->codec;
+ AVCodecParameters *par = st->codecpar;
char buf[256];
int i;
AVCodec *c;
if (payload_type < RTP_PT_PRIVATE) {
/* We are in a standard case
* (from http://www.iana.org/assignments/rtp-parameters). */
- codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
+ par->codec_id = ff_rtp_codec_id(buf, par->codec_type);
}
- if (codec->codec_id == AV_CODEC_ID_NONE) {
+ if (par->codec_id == AV_CODEC_ID_NONE) {
RTPDynamicProtocolHandler *handler =
- ff_rtp_handler_find_by_name(buf, codec->codec_type);
+ ff_rtp_handler_find_by_name(buf, par->codec_type);
init_rtp_handler(handler, rtsp_st, st);
/* If no dynamic handler was found, check with the list of standard
* allocated types, if such a stream for some reason happens to
* use a private payload type. This isn't handled in rtpdec.c, since
* the format name from the rtpmap line never is passed into rtpdec. */
if (!rtsp_st->dynamic_handler)
- codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
+ par->codec_id = ff_rtp_codec_id(buf, par->codec_type);
}
- c = avcodec_find_decoder(codec->codec_id);
+ c = avcodec_find_decoder(par->codec_id);
if (c && c->name)
c_name = c->name;
else
get_word_sep(buf, sizeof(buf), "/", &p);
i = atoi(buf);
- switch (codec->codec_type) {
+ switch (par->codec_type) {
case AVMEDIA_TYPE_AUDIO:
av_log(s, AV_LOG_DEBUG, "audio codec set to: %s\n", c_name);
- codec->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE;
- codec->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS;
+ par->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE;
+ par->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS;
if (i > 0) {
- codec->sample_rate = i;
- avpriv_set_pts_info(st, 32, 1, codec->sample_rate);
+ par->sample_rate = i;
+ avpriv_set_pts_info(st, 32, 1, par->sample_rate);
get_word_sep(buf, sizeof(buf), "/", &p);
i = atoi(buf);
if (i > 0)
- codec->channels = i;
+ par->channels = i;
}
av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n",
- codec->sample_rate);
+ par->sample_rate);
av_log(s, AV_LOG_DEBUG, "audio channels set to: %i\n",
- codec->channels);
+ par->channels);
break;
case AVMEDIA_TYPE_VIDEO:
av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name);
struct sockaddr_storage sdp_ip;
int ttl;
- av_dlog(s, "sdp: %c='%s'\n", letter, buf);
+ av_log(s, AV_LOG_TRACE, "sdp: %c='%s'\n", letter, buf);
p = buf;
if (s1->skip_media && letter != 'm')
if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6"))
return;
get_word_sep(buf1, sizeof(buf1), "/", &p);
- if (get_sockaddr(buf1, &sdp_ip))
+ if (get_sockaddr(s, buf1, &sdp_ip))
return;
ttl = 16;
if (*p == '/') {
return;
st->id = rt->nb_rtsp_streams - 1;
rtsp_st->stream_index = st->index;
- st->codec->codec_type = codec_type;
+ st->codecpar->codec_type = codec_type;
if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
RTPDynamicProtocolHandler *handler;
/* if standard payload type, we can find the codec right now */
- ff_rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type);
- if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
- st->codec->sample_rate > 0)
- avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);
+ ff_rtp_get_codec_info(st->codecpar, rtsp_st->sdp_payload_type);
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
+ st->codecpar->sample_rate > 0)
+ avpriv_set_pts_info(st, 32, 1, st->codecpar->sample_rate);
/* Even static payload types may need a custom depacketizer */
handler = ff_rtp_handler_find_by_id(
- rtsp_st->sdp_payload_type, st->codec->codec_type);
+ rtsp_st->sdp_payload_type, st->codecpar->codec_type);
init_rtp_handler(handler, rtsp_st, st);
finalize_rtp_handler_init(s, rtsp_st, st);
}
} else if (av_strstart(p, "SampleRate:integer;", &p) &&
s->nb_streams > 0) {
st = s->streams[s->nb_streams - 1];
- st->codec->sample_rate = atoi(p);
+ st->codecpar->sample_rate = atoi(p);
} else if (av_strstart(p, "crypto:", &p) && s->nb_streams > 0) {
// RFC 4568
rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
}
if (CONFIG_RTPDEC && rt->ts)
ff_mpegts_parse_close(rt->ts);
+ av_freep(&rt->protocols);
av_free(rt->p);
av_free(rt->recvbuf);
}
}
/* XXX: only one transport specification is parsed */
-static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
+static void rtsp_parse_transport(AVFormatContext *s,
+ RTSPMessageHeader *reply, const char *p)
{
char transport_protocol[16];
char profile[16];
if (*p == '=') {
p++;
get_word_sep(buf, sizeof(buf), ";,", &p);
- get_sockaddr(buf, &th->destination);
+ get_sockaddr(s, buf, &th->destination);
}
} else if (!strcmp(parameter, "source")) {
if (*p == '=') {
p++;
reply->nb_transports++;
+ if (reply->nb_transports >= RTSP_MAX_TRANSPORTS)
+ break;
}
}
handle_rtp_info(rt, url, seq, rtptime);
}
-void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
+void ff_rtsp_parse_line(AVFormatContext *s,
+ RTSPMessageHeader *reply, const char *buf,
RTSPState *rt, const char *method)
{
const char *p;
} else if (av_stristart(p, "Content-Length:", &p)) {
reply->content_length = strtol(p, NULL, 10);
} else if (av_stristart(p, "Transport:", &p)) {
- rtsp_parse_transport(reply, p);
+ rtsp_parse_transport(s, reply, p);
} else if (av_stristart(p, "CSeq:", &p)) {
reply->seq = strtol(p, NULL, 10);
} else if (av_stristart(p, "Range:", &p)) {
return;
len = AV_RB16(buf + 1);
- av_dlog(s, "skipping RTP packet len=%d\n", len);
+ av_log(s, AV_LOG_TRACE, "skipping RTP packet len=%d\n", len);
/* skip payload */
while (len > 0) {
q = buf;
for (;;) {
ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1);
- av_dlog(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
+ av_log(s, AV_LOG_TRACE, "ret=%d c=%02x [%c]\n", ret, ch, ch);
if (ret != 1)
return AVERROR_EOF;
if (ch == '\n')
break;
- if (ch == '$') {
- /* XXX: only parse it if first char on line ? */
+ if (ch == '$' && q == buf) {
if (return_on_interleaved_data) {
return 1;
} else
}
*q = '\0';
- av_dlog(s, "line='%s'\n", buf);
+ av_log(s, AV_LOG_TRACE, "line='%s'\n", buf);
/* test if last line */
if (buf[0] == '\0')
request = 1;
}
} else {
- ff_rtsp_parse_line(reply, p, rt, method);
+ ff_rtsp_parse_line(s, reply, p, rt, method);
av_strlcat(rt->last_reply, p, sizeof(rt->last_reply));
av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));
}
out_buf = base64buf;
}
- av_dlog(s, "Sending:\n%s--\n", buf);
+ av_log(s, AV_LOG_TRACE, "Sending:\n%s--\n", buf);
ffurl_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
if (send_content_length > 0 && send_content) {
/* we will use two ports per rtp stream (rtp and rtcp) */
j += 2;
err = ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE,
- &s->interrupt_callback, &opts);
+ &s->interrupt_callback, &opts, rt->protocols, NULL);
av_dict_free(&opts);
* will return an error. Therefore, we skip those streams. */
if (rt->server_type == RTSP_SERVER_WMS &&
(rtsp_st->stream_index < 0 ||
- s->streams[rtsp_st->stream_index]->codec->codec_type ==
+ s->streams[rtsp_st->stream_index]->codecpar->codec_type ==
AVMEDIA_TYPE_DATA))
continue;
snprintf(transport, sizeof(transport) - 1,
ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
port, "%s", optbuf);
if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
- &s->interrupt_callback, NULL) < 0) {
+ &s->interrupt_callback, NULL, rt->protocols, NULL) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
if (!ff_network_init())
return AVERROR(EIO);
+ if (!rt->protocols) {
+ rt->protocols = ffurl_get_protocols(s->protocol_whitelist,
+ s->protocol_blacklist);
+ if (!rt->protocols)
+ return AVERROR(ENOMEM);
+ }
+
if (s->max_delay < 0) /* Not set by the caller */
s->max_delay = s->iformat ? DEFAULT_REORDERING_DELAY : 0;
/* GET requests */
if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ,
- &s->interrupt_callback) < 0) {
+ &s->interrupt_callback, rt->protocols) < 0) {
err = AVERROR(EIO);
goto fail;
}
/* POST requests */
if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE,
- &s->interrupt_callback) < 0 ) {
+ &s->interrupt_callback, rt->protocols) < 0 ) {
err = AVERROR(EIO);
goto fail;
}
ff_url_join(tcpname, sizeof(tcpname), lower_rtsp_proto, NULL,
host, port, NULL);
if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
- &s->interrupt_callback, NULL) < 0) {
+ &s->interrupt_callback, NULL, rt->protocols, NULL) < 0) {
err = AVERROR(EIO);
goto fail;
}
}
if (len == AVERROR(EAGAIN) && first_queue_st &&
rt->transport == RTSP_TRANSPORT_RTP) {
+ av_log(s, AV_LOG_WARNING,
+ "max delay reached. need to consume packet\n");
rtsp_st = first_queue_st;
ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
goto end;
if (!ff_network_init())
return AVERROR(EIO);
+ if (!rt->protocols) {
+ rt->protocols = ffurl_get_protocols(s->protocol_whitelist,
+ s->protocol_blacklist);
+ if (!rt->protocols)
+ return AVERROR(ENOMEM);
+ }
+
if (s->max_delay < 0) /* Not set by the caller */
s->max_delay = DEFAULT_REORDERING_DELAY;
if (rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)
/* read the whole sdp file */
/* XXX: better loading */
content = av_malloc(SDP_MAX_SIZE);
+ if (!content)
+ return AVERROR(ENOMEM);
size = avio_read(s->pb, content, SDP_MAX_SIZE - 1);
if (size <= 0) {
av_free(content);
if (!(rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)) {
AVDictionary *opts = map_to_opts(rt);
- getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip, sizeof(rtsp_st->sdp_ip),
- namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
+ err = getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip,
+ sizeof(rtsp_st->sdp_ip),
+ namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
+ if (err) {
+ av_log(s, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(err));
+ err = AVERROR(EIO);
+ av_dict_free(&opts);
+ goto fail;
+ }
ff_url_join(url, sizeof(url), "rtp", NULL,
namebuf, rtsp_st->sdp_port,
"?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
rtsp_st->nb_exclude_source_addrs,
rtsp_st->exclude_source_addrs);
err = ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
- &s->interrupt_callback, &opts);
+ &s->interrupt_callback, &opts, rt->protocols, NULL);
av_dict_free(&opts);
int ret, port;
URLContext* in = NULL;
int payload_type;
- AVCodecContext codec = { 0 };
+ AVCodecParameters *par = NULL;
struct sockaddr_storage addr;
AVIOContext pb;
socklen_t addrlen = sizeof(addr);
if (!ff_network_init())
return AVERROR(EIO);
+ if (!rt->protocols) {
+ rt->protocols = ffurl_get_protocols(s->protocol_whitelist,
+ s->protocol_blacklist);
+ if (!rt->protocols)
+ return AVERROR(ENOMEM);
+ }
+
ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ,
- &s->interrupt_callback, NULL);
+ &s->interrupt_callback, NULL, rt->protocols, NULL);
if (ret)
goto fail;
ffurl_close(in);
in = NULL;
- if (ff_rtp_get_codec_info(&codec, payload_type)) {
+ par = avcodec_parameters_alloc();
+ if (!par) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if (ff_rtp_get_codec_info(par, payload_type)) {
av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d "
"without an SDP file describing it\n",
payload_type);
goto fail;
}
- if (codec.codec_type != AVMEDIA_TYPE_DATA) {
+ if (par->codec_type != AVMEDIA_TYPE_DATA) {
av_log(s, AV_LOG_WARNING, "Guessing on RTP content - if not received "
"properly you need an SDP file "
"describing it\n");
snprintf(sdp, sizeof(sdp),
"v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
addr.ss_family == AF_INET ? 4 : 6, host,
- codec.codec_type == AVMEDIA_TYPE_DATA ? "application" :
- codec.codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
+ par->codec_type == AVMEDIA_TYPE_DATA ? "application" :
+ par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
port, payload_type);
av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
+ avcodec_parameters_free(&par);
ffio_init_context(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
s->pb = &pb;
return ret;
fail:
+ avcodec_parameters_free(&par);
if (in)
ffurl_close(in);
ff_network_close();