Libav 0.7.1
|
00001 /* 00002 * RTSP demuxer 00003 * Copyright (c) 2002 Fabrice Bellard 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav 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 * Libav 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 Libav; 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/opt.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->rtcp_ts_offset = 0; 00056 } 00057 } 00058 if (rt->state == RTSP_STATE_PAUSED) { 00059 cmd[0] = 0; 00060 } else { 00061 snprintf(cmd, sizeof(cmd), 00062 "Range: npt=%"PRId64".%03"PRId64"-\r\n", 00063 rt->seek_timestamp / AV_TIME_BASE, 00064 rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000); 00065 } 00066 ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL); 00067 if (reply->status_code != RTSP_STATUS_OK) { 00068 return -1; 00069 } 00070 if (rt->transport == RTSP_TRANSPORT_RTP && 00071 reply->range_start != AV_NOPTS_VALUE) { 00072 for (i = 0; i < rt->nb_rtsp_streams; i++) { 00073 RTSPStream *rtsp_st = rt->rtsp_streams[i]; 00074 RTPDemuxContext *rtpctx = rtsp_st->transport_priv; 00075 AVStream *st = NULL; 00076 if (!rtpctx || rtsp_st->stream_index < 0) 00077 continue; 00078 st = s->streams[rtsp_st->stream_index]; 00079 rtpctx->range_start_offset = 00080 av_rescale_q(reply->range_start, AV_TIME_BASE_Q, 00081 st->time_base); 00082 } 00083 } 00084 } 00085 rt->state = RTSP_STATE_STREAMING; 00086 return 0; 00087 } 00088 00089 /* pause the stream */ 00090 static int rtsp_read_pause(AVFormatContext *s) 00091 { 00092 RTSPState *rt = s->priv_data; 00093 RTSPMessageHeader reply1, *reply = &reply1; 00094 00095 if (rt->state != RTSP_STATE_STREAMING) 00096 return 0; 00097 else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { 00098 ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL); 00099 if (reply->status_code != RTSP_STATUS_OK) { 00100 return -1; 00101 } 00102 } 00103 rt->state = RTSP_STATE_PAUSED; 00104 return 0; 00105 } 00106 00107 int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply) 00108 { 00109 RTSPState *rt = s->priv_data; 00110 char cmd[1024]; 00111 unsigned char *content = NULL; 00112 int ret; 00113 00114 /* describe the stream */ 00115 snprintf(cmd, sizeof(cmd), 00116 "Accept: application/sdp\r\n"); 00117 if (rt->server_type == RTSP_SERVER_REAL) { 00122 av_strlcat(cmd, 00123 "Require: com.real.retain-entity-for-setup\r\n", 00124 sizeof(cmd)); 00125 } 00126 ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content); 00127 if (!content) 00128 return AVERROR_INVALIDDATA; 00129 if (reply->status_code != RTSP_STATUS_OK) { 00130 av_freep(&content); 00131 return AVERROR_INVALIDDATA; 00132 } 00133 00134 av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content); 00135 /* now we got the SDP description, we parse it */ 00136 ret = ff_sdp_parse(s, (const char *)content); 00137 av_freep(&content); 00138 if (ret < 0) 00139 return ret; 00140 00141 return 0; 00142 } 00143 00144 static int rtsp_probe(AVProbeData *p) 00145 { 00146 if (av_strstart(p->filename, "rtsp:", NULL)) 00147 return AVPROBE_SCORE_MAX; 00148 return 0; 00149 } 00150 00151 static int rtsp_read_header(AVFormatContext *s, 00152 AVFormatParameters *ap) 00153 { 00154 RTSPState *rt = s->priv_data; 00155 int ret; 00156 00157 ret = ff_rtsp_connect(s); 00158 if (ret) 00159 return ret; 00160 00161 rt->real_setup_cache = av_mallocz(2 * s->nb_streams * sizeof(*rt->real_setup_cache)); 00162 if (!rt->real_setup_cache) 00163 return AVERROR(ENOMEM); 00164 rt->real_setup = rt->real_setup_cache + s->nb_streams; 00165 00166 #if FF_API_FORMAT_PARAMETERS 00167 if (ap->initial_pause) 00168 rt->initial_pause = ap->initial_pause; 00169 #endif 00170 00171 if (rt->initial_pause) { 00172 /* do not start immediately */ 00173 } else { 00174 if (rtsp_read_play(s) < 0) { 00175 ff_rtsp_close_streams(s); 00176 ff_rtsp_close_connections(s); 00177 return AVERROR_INVALIDDATA; 00178 } 00179 } 00180 00181 return 0; 00182 } 00183 00184 int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, 00185 uint8_t *buf, int buf_size) 00186 { 00187 RTSPState *rt = s->priv_data; 00188 int id, len, i, ret; 00189 RTSPStream *rtsp_st; 00190 00191 av_dlog(s, "tcp_read_packet:\n"); 00192 redo: 00193 for (;;) { 00194 RTSPMessageHeader reply; 00195 00196 ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL); 00197 if (ret < 0) 00198 return ret; 00199 if (ret == 1) /* received '$' */ 00200 break; 00201 /* XXX: parse message */ 00202 if (rt->state != RTSP_STATE_STREAMING) 00203 return 0; 00204 } 00205 ret = ffurl_read_complete(rt->rtsp_hd, buf, 3); 00206 if (ret != 3) 00207 return -1; 00208 id = buf[0]; 00209 len = AV_RB16(buf + 1); 00210 av_dlog(s, "id=%d len=%d\n", id, len); 00211 if (len > buf_size || len < 12) 00212 goto redo; 00213 /* get the data */ 00214 ret = ffurl_read_complete(rt->rtsp_hd, buf, len); 00215 if (ret != len) 00216 return -1; 00217 if (rt->transport == RTSP_TRANSPORT_RDT && 00218 ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0) 00219 return -1; 00220 00221 /* find the matching stream */ 00222 for (i = 0; i < rt->nb_rtsp_streams; i++) { 00223 rtsp_st = rt->rtsp_streams[i]; 00224 if (id >= rtsp_st->interleaved_min && 00225 id <= rtsp_st->interleaved_max) 00226 goto found; 00227 } 00228 goto redo; 00229 found: 00230 *prtsp_st = rtsp_st; 00231 return len; 00232 } 00233 00234 static int resetup_tcp(AVFormatContext *s) 00235 { 00236 RTSPState *rt = s->priv_data; 00237 char host[1024]; 00238 int port; 00239 00240 av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, 00241 s->filename); 00242 ff_rtsp_undo_setup(s); 00243 return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP, 00244 rt->real_challenge); 00245 } 00246 00247 static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) 00248 { 00249 RTSPState *rt = s->priv_data; 00250 int ret; 00251 RTSPMessageHeader reply1, *reply = &reply1; 00252 char cmd[1024]; 00253 00254 retry: 00255 if (rt->server_type == RTSP_SERVER_REAL) { 00256 int i; 00257 00258 for (i = 0; i < s->nb_streams; i++) 00259 rt->real_setup[i] = s->streams[i]->discard; 00260 00261 if (!rt->need_subscription) { 00262 if (memcmp (rt->real_setup, rt->real_setup_cache, 00263 sizeof(enum AVDiscard) * s->nb_streams)) { 00264 snprintf(cmd, sizeof(cmd), 00265 "Unsubscribe: %s\r\n", 00266 rt->last_subscription); 00267 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, 00268 cmd, reply, NULL); 00269 if (reply->status_code != RTSP_STATUS_OK) 00270 return AVERROR_INVALIDDATA; 00271 rt->need_subscription = 1; 00272 } 00273 } 00274 00275 if (rt->need_subscription) { 00276 int r, rule_nr, first = 1; 00277 00278 memcpy(rt->real_setup_cache, rt->real_setup, 00279 sizeof(enum AVDiscard) * s->nb_streams); 00280 rt->last_subscription[0] = 0; 00281 00282 snprintf(cmd, sizeof(cmd), 00283 "Subscribe: "); 00284 for (i = 0; i < rt->nb_rtsp_streams; i++) { 00285 rule_nr = 0; 00286 for (r = 0; r < s->nb_streams; r++) { 00287 if (s->streams[r]->id == i) { 00288 if (s->streams[r]->discard != AVDISCARD_ALL) { 00289 if (!first) 00290 av_strlcat(rt->last_subscription, ",", 00291 sizeof(rt->last_subscription)); 00292 ff_rdt_subscribe_rule( 00293 rt->last_subscription, 00294 sizeof(rt->last_subscription), i, rule_nr); 00295 first = 0; 00296 } 00297 rule_nr++; 00298 } 00299 } 00300 } 00301 av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription); 00302 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, 00303 cmd, reply, NULL); 00304 if (reply->status_code != RTSP_STATUS_OK) 00305 return AVERROR_INVALIDDATA; 00306 rt->need_subscription = 0; 00307 00308 if (rt->state == RTSP_STATE_STREAMING) 00309 rtsp_read_play (s); 00310 } 00311 } 00312 00313 ret = ff_rtsp_fetch_packet(s, pkt); 00314 if (ret < 0) { 00315 if (ret == AVERROR(ETIMEDOUT) && !rt->packets) { 00316 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP && 00317 rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP)) { 00318 RTSPMessageHeader reply1, *reply = &reply1; 00319 av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n"); 00320 if (rtsp_read_pause(s) != 0) 00321 return -1; 00322 // TEARDOWN is required on Real-RTSP, but might make 00323 // other servers close the connection. 00324 if (rt->server_type == RTSP_SERVER_REAL) 00325 ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL, 00326 reply, NULL); 00327 rt->session_id[0] = '\0'; 00328 if (resetup_tcp(s) == 0) { 00329 rt->state = RTSP_STATE_IDLE; 00330 rt->need_subscription = 1; 00331 if (rtsp_read_play(s) != 0) 00332 return -1; 00333 goto retry; 00334 } 00335 } 00336 } 00337 return ret; 00338 } 00339 rt->packets++; 00340 00341 /* send dummy request to keep TCP connection alive */ 00342 if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { 00343 if (rt->server_type == RTSP_SERVER_WMS || 00344 (rt->server_type != RTSP_SERVER_REAL && 00345 rt->get_parameter_supported)) { 00346 ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL); 00347 } else { 00348 ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL); 00349 } 00350 } 00351 00352 return 0; 00353 } 00354 00355 static int rtsp_read_seek(AVFormatContext *s, int stream_index, 00356 int64_t timestamp, int flags) 00357 { 00358 RTSPState *rt = s->priv_data; 00359 00360 rt->seek_timestamp = av_rescale_q(timestamp, 00361 s->streams[stream_index]->time_base, 00362 AV_TIME_BASE_Q); 00363 switch(rt->state) { 00364 default: 00365 case RTSP_STATE_IDLE: 00366 break; 00367 case RTSP_STATE_STREAMING: 00368 if (rtsp_read_pause(s) != 0) 00369 return -1; 00370 rt->state = RTSP_STATE_SEEKING; 00371 if (rtsp_read_play(s) != 0) 00372 return -1; 00373 break; 00374 case RTSP_STATE_PAUSED: 00375 rt->state = RTSP_STATE_IDLE; 00376 break; 00377 } 00378 return 0; 00379 } 00380 00381 static int rtsp_read_close(AVFormatContext *s) 00382 { 00383 RTSPState *rt = s->priv_data; 00384 00385 #if 0 00386 /* NOTE: it is valid to flush the buffer here */ 00387 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { 00388 avio_close(&rt->rtsp_gb); 00389 } 00390 #endif 00391 ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); 00392 00393 ff_rtsp_close_streams(s); 00394 ff_rtsp_close_connections(s); 00395 ff_network_close(); 00396 rt->real_setup = NULL; 00397 av_freep(&rt->real_setup_cache); 00398 return 0; 00399 } 00400 00401 static const AVOption options[] = { 00402 { "initial_pause", "Don't start playing the stream immediately", offsetof(RTSPState, initial_pause), FF_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, 00403 { NULL }, 00404 }; 00405 00406 const AVClass rtsp_demuxer_class = { 00407 .class_name = "RTSP demuxer", 00408 .item_name = av_default_item_name, 00409 .option = options, 00410 .version = LIBAVUTIL_VERSION_INT, 00411 }; 00412 00413 AVInputFormat ff_rtsp_demuxer = { 00414 "rtsp", 00415 NULL_IF_CONFIG_SMALL("RTSP input format"), 00416 sizeof(RTSPState), 00417 rtsp_probe, 00418 rtsp_read_header, 00419 rtsp_read_packet, 00420 rtsp_read_close, 00421 rtsp_read_seek, 00422 .flags = AVFMT_NOFILE, 00423 .read_play = rtsp_read_play, 00424 .read_pause = rtsp_read_pause, 00425 .priv_class = &rtsp_demuxer_class, 00426 };