1. call stack
avformat_open_input() {
init_input(); // get s->iformat if s->iformat is NULL.
s->iformat->read_header(s) // rtsp_read_header { // ff_rtsp_demuxer
ff_rtsp_connect() {
if (rt->control_transport == RTSP_MODE_TUNNEL) { // rtsp over http
// GET request
ffurl_connect(rt->rtsp_hd, NULL);
// POST request
ff_http_init_auth_state(rt->rtsp_hd_out, rt->rtsp_hd);
ffurl_connect(rt->rtsp_hd_out, NULL);
}
else { // rtsp directly connect by tcp
ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
&s->interrupt_callback, NULL); // setup rtsp connection
}
for (rt->server_type = RTSP_SERVER_RTP;;) {
ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply,
NULL); // send OPTIONS command, and get response
ff_rtsp_setup_input_streams(s, reply);
// send DESCRIBE command, and get response,
// if not authed, resend describe with auth
}
do {
// send SETUP commands, and setup rtp, rtcp connection
err = ff_rtsp_make_setup_request(s, host, port, lower_transport,
rt->server_type == RTSP_SERVER_REAL ? real_challenge : NULL); {
while (j <= rt->rtp_port_max) {
ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE,
&s->interrupt_callback, NULL); { // mark 1
ffurl_connect() {
uc->prot->url_open() // rtp_open { // ff_rtp_protocol, mark 2
build_udp_url(buf, sizeof(buf), hostname, rtp_port,
local_rtp_port, ttl, max_packet_size, connect);
ffurl_open(&s->rtp_hd, buf, flags,
&h->interrupt_callback, NULL) {
ffurl_connect() {
uc->prot->url_open2(); // udp_open
// ff_udp_protocol
}
}
build_udp_url(buf, sizeof(buf), hostname, rtcp_port,
local_rtcp_port, ttl, max_packet_size, connect);
ffurl_open(&s->rtcp_hd, buf, flags,
&h->interrupt_callback, NULL) {
ffurl_connect() {
uc->prot->url_open2(); // udp_open
// ff_udp_protocol
}
}
} // mark 2
}
} // ffurl_open, mark 1
// send SETUP command, and get Response.
ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL);
}
}
} while while (err);
}
rtsp_read_play(s); // send PLAYcommands
}
} // avformat_open_input