00001 /* 00002 * RTSP demuxer 00003 * Copyright (c) 2002 Fabrice Bellard 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "libavutil/avstring.h" 00023 #include "libavutil/intreadwrite.h" 00024 #include "libavutil/mathematics.h" 00025 #include "avformat.h" 00026 00027 #include "internal.h" 00028 #include "network.h" 00029 #include "os_support.h" 00030 #include "rtsp.h" 00031 #include "rdt.h" 00032 #include "url.h" 00033 00034 static int rtsp_read_play(AVFormatContext *s) 00035 { 00036 RTSPState *rt = s->priv_data; 00037 RTSPMessageHeader reply1, *reply = &reply1; 00038 int i; 00039 char cmd[1024]; 00040 00041 av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state); 00042 rt->nb_byes = 0; 00043 00044 if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { 00045 if (rt->transport == RTSP_TRANSPORT_RTP) { 00046 for (i = 0; i < rt->nb_rtsp_streams; i++) { 00047 RTSPStream *rtsp_st = rt->rtsp_streams[i]; 00048 RTPDemuxContext *rtpctx = rtsp_st->transport_priv; 00049 if (!rtpctx) 00050 continue; 00051 ff_rtp_reset_packet_queue(rtpctx); 00052 rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE; 00053 rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE; 00054 rtpctx->base_timestamp = 0; 00055 rtpctx->timestamp = 0; 00056 rtpctx->unwrapped_timestamp = 0; 00057 rtpctx->rtcp_ts_offset = 0; 00058 } 00059 } 00060 if (rt->state == RTSP_STATE_PAUSED) { 00061 cmd[0] = 0; 00062 } else { 00063 snprintf(cmd, sizeof(cmd), 00064 "Range: npt=%"PRId64".%03"PRId64"-\r\n", 00065 rt->seek_timestamp / AV_TIME_BASE, 00066 rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000); 00067 } 00068 ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL); 00069 if (reply->status_code != RTSP_STATUS_OK) { 00070 return -1; 00071 } 00072 if (rt->transport == RTSP_TRANSPORT_RTP && 00073 reply->range_start != AV_NOPTS_VALUE) { 00074 for (i = 0; i < rt->nb_rtsp_streams; i++) { 00075 RTSPStream *rtsp_st = rt->rtsp_streams[i]; 00076 RTPDemuxContext *rtpctx = rtsp_st->transport_priv; 00077 AVStream *st = NULL; 00078 if (!rtpctx || rtsp_st->stream_index < 0) 00079 continue; 00080 st = s->streams[rtsp_st->stream_index]; 00081 rtpctx->range_start_offset = 00082 av_rescale_q(reply->range_start, AV_TIME_BASE_Q, 00083 st->time_base); 00084 } 00085 } 00086 } 00087 rt->state = RTSP_STATE_STREAMING; 00088 return 0; 00089 } 00090 00091 /* pause the stream */ 00092 static int rtsp_read_pause(AVFormatContext *s) 00093 { 00094 RTSPState *rt = s->priv_data; 00095 RTSPMessageHeader reply1, *reply = &reply1; 00096 00097 if (rt->state != RTSP_STATE_STREAMING) 00098 return 0; 00099 else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { 00100 ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL); 00101 if (reply->status_code != RTSP_STATUS_OK) { 00102 return -1; 00103 } 00104 } 00105 rt->state = RTSP_STATE_PAUSED; 00106 return 0; 00107 } 00108 00109 int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply) 00110 { 00111 RTSPState *rt = s->priv_data; 00112 char cmd[1024]; 00113 unsigned char *content = NULL; 00114 int ret; 00115 00116 /* describe the stream */ 00117 snprintf(cmd, sizeof(cmd), 00118 "Accept: application/sdp\r\n"); 00119 if (rt->server_type == RTSP_SERVER_REAL) { 00124 av_strlcat(cmd, 00125 "Require: com.real.retain-entity-for-setup\r\n", 00126 sizeof(cmd)); 00127 } 00128 ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content); 00129 if (!content) 00130 return AVERROR_INVALIDDATA; 00131 if (reply->status_code != RTSP_STATUS_OK) { 00132 av_freep(&content); 00133 return AVERROR_INVALIDDATA; 00134 } 00135 00136 av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content); 00137 /* now we got the SDP description, we parse it */ 00138 ret = ff_sdp_parse(s, (const char *)content); 00139 av_freep(&content); 00140 if (ret < 0) 00141 return ret; 00142 00143 return 0; 00144 } 00145 00146 static int rtsp_probe(AVProbeData *p) 00147 { 00148 if (av_strstart(p->filename, "rtsp:", NULL)) 00149 return AVPROBE_SCORE_MAX; 00150 return 0; 00151 } 00152 00153 static int rtsp_read_header(AVFormatContext *s, 00154 AVFormatParameters *ap) 00155 { 00156 RTSPState *rt = s->priv_data; 00157 int ret; 00158 00159 ret = ff_rtsp_connect(s); 00160 if (ret) 00161 return ret; 00162 00163 rt->real_setup_cache = av_mallocz(2 * s->nb_streams * sizeof(*rt->real_setup_cache)); 00164 if (!rt->real_setup_cache) 00165 return AVERROR(ENOMEM); 00166 rt->real_setup = rt->real_setup_cache + s->nb_streams; 00167 00168 if (rt->initial_pause) { 00169 /* do not start immediately */ 00170 } else { 00171 if (rtsp_read_play(s) < 0) { 00172 ff_rtsp_close_streams(s); 00173 ff_rtsp_close_connections(s); 00174 return AVERROR_INVALIDDATA; 00175 } 00176 } 00177 00178 return 0; 00179 } 00180 00181 int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, 00182 uint8_t *buf, int buf_size) 00183 { 00184 RTSPState *rt = s->priv_data; 00185 int id, len, i, ret; 00186 RTSPStream *rtsp_st; 00187 00188 av_dlog(s, "tcp_read_packet:\n"); 00189 redo: 00190 for (;;) { 00191 RTSPMessageHeader reply; 00192 00193 ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL); 00194 if (ret < 0) 00195 return ret; 00196 if (ret == 1) /* received '$' */ 00197 break; 00198 /* XXX: parse message */ 00199 if (rt->state != RTSP_STATE_STREAMING) 00200 return 0; 00201 } 00202 ret = ffurl_read_complete(rt->rtsp_hd, buf, 3); 00203 if (ret != 3) 00204 return -1; 00205 id = buf[0]; 00206 len = AV_RB16(buf + 1); 00207 av_dlog(s, "id=%d len=%d\n", id, len); 00208 if (len > buf_size || len < 8) 00209 goto redo; 00210 /* get the data */ 00211 ret = ffurl_read_complete(rt->rtsp_hd, buf, len); 00212 if (ret != len) 00213 return -1; 00214 if (rt->transport == RTSP_TRANSPORT_RDT && 00215 ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0) 00216 return -1; 00217 00218 /* find the matching stream */ 00219 for (i = 0; i < rt->nb_rtsp_streams; i++) { 00220 rtsp_st = rt->rtsp_streams[i]; 00221 if (id >= rtsp_st->interleaved_min && 00222 id <= rtsp_st->interleaved_max) 00223 goto found; 00224 } 00225 goto redo; 00226 found: 00227 *prtsp_st = rtsp_st; 00228 return len; 00229 } 00230 00231 static int resetup_tcp(AVFormatContext *s) 00232 { 00233 RTSPState *rt = s->priv_data; 00234 char host[1024]; 00235 int port; 00236 00237 av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, 00238 s->filename); 00239 ff_rtsp_undo_setup(s); 00240 return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP, 00241 rt->real_challenge); 00242 } 00243 00244 static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) 00245 { 00246 RTSPState *rt = s->priv_data; 00247 int ret; 00248 RTSPMessageHeader reply1, *reply = &reply1; 00249 char cmd[1024]; 00250 00251 retry: 00252 if (rt->server_type == RTSP_SERVER_REAL) { 00253 int i; 00254 00255 for (i = 0; i < s->nb_streams; i++) 00256 rt->real_setup[i] = s->streams[i]->discard; 00257 00258 if (!rt->need_subscription) { 00259 if (memcmp (rt->real_setup, rt->real_setup_cache, 00260 sizeof(enum AVDiscard) * s->nb_streams)) { 00261 snprintf(cmd, sizeof(cmd), 00262 "Unsubscribe: %s\r\n", 00263 rt->last_subscription); 00264 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, 00265 cmd, reply, NULL); 00266 if (reply->status_code != RTSP_STATUS_OK) 00267 return AVERROR_INVALIDDATA; 00268 rt->need_subscription = 1; 00269 } 00270 } 00271 00272 if (rt->need_subscription) { 00273 int r, rule_nr, first = 1; 00274 00275 memcpy(rt->real_setup_cache, rt->real_setup, 00276 sizeof(enum AVDiscard) * s->nb_streams); 00277 rt->last_subscription[0] = 0; 00278 00279 snprintf(cmd, sizeof(cmd), 00280 "Subscribe: "); 00281 for (i = 0; i < rt->nb_rtsp_streams; i++) { 00282 rule_nr = 0; 00283 for (r = 0; r < s->nb_streams; r++) { 00284 if (s->streams[r]->id == i) { 00285 if (s->streams[r]->discard != AVDISCARD_ALL) { 00286 if (!first) 00287 av_strlcat(rt->last_subscription, ",", 00288 sizeof(rt->last_subscription)); 00289 ff_rdt_subscribe_rule( 00290 rt->last_subscription, 00291 sizeof(rt->last_subscription), i, rule_nr); 00292 first = 0; 00293 } 00294 rule_nr++; 00295 } 00296 } 00297 } 00298 av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription); 00299 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, 00300 cmd, reply, NULL); 00301 if (reply->status_code != RTSP_STATUS_OK) 00302 return AVERROR_INVALIDDATA; 00303 rt->need_subscription = 0; 00304 00305 if (rt->state == RTSP_STATE_STREAMING) 00306 rtsp_read_play (s); 00307 } 00308 } 00309 00310 ret = ff_rtsp_fetch_packet(s, pkt); 00311 if (ret < 0) { 00312 if (ret == AVERROR(ETIMEDOUT) && !rt->packets) { 00313 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP && 00314 rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP)) { 00315 RTSPMessageHeader reply1, *reply = &reply1; 00316 av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n"); 00317 if (rtsp_read_pause(s) != 0) 00318 return -1; 00319 // TEARDOWN is required on Real-RTSP, but might make 00320 // other servers close the connection. 00321 if (rt->server_type == RTSP_SERVER_REAL) 00322 ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL, 00323 reply, NULL); 00324 rt->session_id[0] = '0円'; 00325 if (resetup_tcp(s) == 0) { 00326 rt->state = RTSP_STATE_IDLE; 00327 rt->need_subscription = 1; 00328 if (rtsp_read_play(s) != 0) 00329 return -1; 00330 goto retry; 00331 } 00332 } 00333 } 00334 return ret; 00335 } 00336 rt->packets++; 00337 00338 /* send dummy request to keep TCP connection alive */ 00339 if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { 00340 if (rt->server_type == RTSP_SERVER_WMS || 00341 (rt->server_type != RTSP_SERVER_REAL && 00342 rt->get_parameter_supported)) { 00343 ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL); 00344 } else { 00345 ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL); 00346 } 00347 } 00348 00349 return 0; 00350 } 00351 00352 static int rtsp_read_seek(AVFormatContext *s, int stream_index, 00353 int64_t timestamp, int flags) 00354 { 00355 RTSPState *rt = s->priv_data; 00356 00357 rt->seek_timestamp = av_rescale_q(timestamp, 00358 s->streams[stream_index]->time_base, 00359 AV_TIME_BASE_Q); 00360 switch(rt->state) { 00361 default: 00362 case RTSP_STATE_IDLE: 00363 break; 00364 case RTSP_STATE_STREAMING: 00365 if (rtsp_read_pause(s) != 0) 00366 return -1; 00367 rt->state = RTSP_STATE_SEEKING; 00368 if (rtsp_read_play(s) != 0) 00369 return -1; 00370 break; 00371 case RTSP_STATE_PAUSED: 00372 rt->state = RTSP_STATE_IDLE; 00373 break; 00374 } 00375 return 0; 00376 } 00377 00378 static int rtsp_read_close(AVFormatContext *s) 00379 { 00380 RTSPState *rt = s->priv_data; 00381 00382 ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); 00383 00384 ff_rtsp_close_streams(s); 00385 ff_rtsp_close_connections(s); 00386 ff_network_close(); 00387 rt->real_setup = NULL; 00388 av_freep(&rt->real_setup_cache); 00389 return 0; 00390 } 00391 00392 const AVClass rtsp_demuxer_class = { 00393 .class_name = "RTSP demuxer", 00394 .item_name = av_default_item_name, 00395 .option = ff_rtsp_options, 00396 .version = LIBAVUTIL_VERSION_INT, 00397 }; 00398 00399 AVInputFormat ff_rtsp_demuxer = { 00400 .name = "rtsp", 00401 .long_name = NULL_IF_CONFIG_SMALL("RTSP input format"), 00402 .priv_data_size = sizeof(RTSPState), 00403 .read_probe = rtsp_probe, 00404 .read_header = rtsp_read_header, 00405 .read_packet = rtsp_read_packet, 00406 .read_close = rtsp_read_close, 00407 .read_seek = rtsp_read_seek, 00408 .flags = AVFMT_NOFILE, 00409 .read_play = rtsp_read_play, 00410 .read_pause = rtsp_read_pause, 00411 .priv_class = &rtsp_demuxer_class, 00412 };