00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/avstring.h"
00023 #include "libavutil/intreadwrite.h"
00024 #include "libavutil/mathematics.h"
00025 #include "libavutil/random_seed.h"
00026 #include "libavutil/time.h"
00027 #include "avformat.h"
00028
00029 #include "internal.h"
00030 #include "network.h"
00031 #include "os_support.h"
00032 #include "rtsp.h"
00033 #include "rdt.h"
00034 #include "url.h"
00035
00036 static const struct RTSPStatusMessage {
00037 enum RTSPStatusCode code;
00038 const char *message;
00039 } status_messages[] = {
00040 { RTSP_STATUS_OK, "OK" },
00041 { RTSP_STATUS_METHOD, "Method Not Allowed" },
00042 { RTSP_STATUS_BANDWIDTH, "Not Enough Bandwidth" },
00043 { RTSP_STATUS_SESSION, "Session Not Found" },
00044 { RTSP_STATUS_STATE, "Method Not Valid in This State" },
00045 { RTSP_STATUS_AGGREGATE, "Aggregate operation not allowed" },
00046 { RTSP_STATUS_ONLY_AGGREGATE, "Only aggregate operation allowed" },
00047 { RTSP_STATUS_TRANSPORT, "Unsupported transport" },
00048 { RTSP_STATUS_INTERNAL, "Internal Server Error" },
00049 { RTSP_STATUS_SERVICE, "Service Unavailable" },
00050 { RTSP_STATUS_VERSION, "RTSP Version not supported" },
00051 { 0, "NULL" }
00052 };
00053
00054 static int rtsp_read_close(AVFormatContext *s)
00055 {
00056 RTSPState *rt = s->priv_data;
00057
00058 if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN))
00059 ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
00060
00061 ff_rtsp_close_streams(s);
00062 ff_rtsp_close_connections(s);
00063 ff_network_close();
00064 rt->real_setup = NULL;
00065 av_freep(&rt->real_setup_cache);
00066 return 0;
00067 }
00068
00069 static inline int read_line(AVFormatContext *s, char *rbuf, const int rbufsize,
00070 int *rbuflen)
00071 {
00072 RTSPState *rt = s->priv_data;
00073 int idx = 0;
00074 int ret = 0;
00075 *rbuflen = 0;
00076
00077 do {
00078 ret = ffurl_read_complete(rt->rtsp_hd, rbuf + idx, 1);
00079 if (ret < 0)
00080 return ret;
00081 if (rbuf[idx] == '\r') {
00082
00083 } else if (rbuf[idx] == '\n') {
00084 rbuf[idx] = '\0';
00085 *rbuflen = idx;
00086 return 0;
00087 } else
00088 idx++;
00089 } while (idx < rbufsize);
00090 av_log(s, AV_LOG_ERROR, "Message too long\n");
00091 return AVERROR(EIO);
00092 }
00093
00094 static int rtsp_send_reply(AVFormatContext *s, enum RTSPStatusCode code,
00095 const char *extracontent, uint16_t seq)
00096 {
00097 RTSPState *rt = s->priv_data;
00098 char message[4096];
00099 int index = 0;
00100 while (status_messages[index].code) {
00101 if (status_messages[index].code == code) {
00102 snprintf(message, sizeof(message), "RTSP/1.0 %d %s\r\n",
00103 code, status_messages[index].message);
00104 break;
00105 }
00106 index++;
00107 }
00108 if (!status_messages[index].code)
00109 return AVERROR(EINVAL);
00110 av_strlcatf(message, sizeof(message), "CSeq: %d\r\n", seq);
00111 av_strlcatf(message, sizeof(message), "Server: %s\r\n", LIBAVFORMAT_IDENT);
00112 if (extracontent)
00113 av_strlcat(message, extracontent, sizeof(message));
00114 av_strlcat(message, "\r\n", sizeof(message));
00115 av_dlog(s, "Sending response:\n%s", message);
00116 ffurl_write(rt->rtsp_hd, message, strlen(message));
00117
00118 return 0;
00119 }
00120
00121 static inline int check_sessionid(AVFormatContext *s,
00122 RTSPMessageHeader *request)
00123 {
00124 RTSPState *rt = s->priv_data;
00125 unsigned char *session_id = rt->session_id;
00126 if (!session_id[0]) {
00127 av_log(s, AV_LOG_WARNING, "There is no session-id at the moment\n");
00128 return 0;
00129 }
00130 if (strcmp(session_id, request->session_id)) {
00131 av_log(s, AV_LOG_ERROR, "Unexpected session-id %s\n",
00132 request->session_id);
00133 rtsp_send_reply(s, RTSP_STATUS_SESSION, NULL, request->seq);
00134 return AVERROR_STREAM_NOT_FOUND;
00135 }
00136 return 0;
00137 }
00138
00139 static inline int rtsp_read_request(AVFormatContext *s,
00140 RTSPMessageHeader *request,
00141 const char *method)
00142 {
00143 RTSPState *rt = s->priv_data;
00144 char rbuf[1024];
00145 int rbuflen, ret;
00146 do {
00147 ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
00148 if (ret)
00149 return ret;
00150 if (rbuflen > 1) {
00151 av_dlog(s, "Parsing[%d]: %s\n", rbuflen, rbuf);
00152 ff_rtsp_parse_line(request, rbuf, rt, method);
00153 }
00154 } while (rbuflen > 0);
00155 if (request->seq != rt->seq + 1) {
00156 av_log(s, AV_LOG_ERROR, "Unexpected Sequence number %d\n",
00157 request->seq);
00158 return AVERROR(EINVAL);
00159 }
00160 if (rt->session_id[0] && strcmp(method, "OPTIONS")) {
00161 ret = check_sessionid(s, request);
00162 if (ret)
00163 return ret;
00164 }
00165
00166 return 0;
00167 }
00168
00169 static int rtsp_read_announce(AVFormatContext *s)
00170 {
00171 RTSPState *rt = s->priv_data;
00172 RTSPMessageHeader request = { 0 };
00173 char sdp[4096];
00174 int ret;
00175
00176 ret = rtsp_read_request(s, &request, "ANNOUNCE");
00177 if (ret)
00178 return ret;
00179 rt->seq++;
00180 if (strcmp(request.content_type, "application/sdp")) {
00181 av_log(s, AV_LOG_ERROR, "Unexpected content type %s\n",
00182 request.content_type);
00183 rtsp_send_reply(s, RTSP_STATUS_SERVICE, NULL, request.seq);
00184 return AVERROR_OPTION_NOT_FOUND;
00185 }
00186 if (request.content_length && request.content_length < sizeof(sdp) - 1) {
00187
00188 if (ffurl_read_complete(rt->rtsp_hd, sdp, request.content_length)
00189 < request.content_length) {
00190 av_log(s, AV_LOG_ERROR,
00191 "Unable to get complete SDP Description in ANNOUNCE\n");
00192 rtsp_send_reply(s, RTSP_STATUS_INTERNAL, NULL, request.seq);
00193 return AVERROR(EIO);
00194 }
00195 sdp[request.content_length] = '\0';
00196 av_log(s, AV_LOG_VERBOSE, "SDP: %s\n", sdp);
00197 ret = ff_sdp_parse(s, sdp);
00198 if (ret)
00199 return ret;
00200 rtsp_send_reply(s, RTSP_STATUS_OK, NULL, request.seq);
00201 return 0;
00202 }
00203 av_log(s, AV_LOG_ERROR,
00204 "Content-Length header value exceeds sdp allocated buffer (4KB)\n");
00205 rtsp_send_reply(s, RTSP_STATUS_INTERNAL,
00206 "Content-Length exceeds buffer size", request.seq);
00207 return AVERROR(EIO);
00208 }
00209
00210 static int rtsp_read_options(AVFormatContext *s)
00211 {
00212 RTSPState *rt = s->priv_data;
00213 RTSPMessageHeader request = { 0 };
00214 int ret = 0;
00215
00216
00217 ret = rtsp_read_request(s, &request, "OPTIONS");
00218 if (ret)
00219 return ret;
00220 rt->seq++;
00221
00222 rtsp_send_reply(s, RTSP_STATUS_OK,
00223 "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, RECORD\r\n",
00224 request.seq);
00225 return 0;
00226 }
00227
00228 static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl)
00229 {
00230 RTSPState *rt = s->priv_data;
00231 RTSPMessageHeader request = { 0 };
00232 int ret = 0;
00233 char url[1024];
00234 RTSPStream *rtsp_st;
00235 char responseheaders[1024];
00236 int localport = -1;
00237 int transportidx = 0;
00238 int streamid = 0;
00239
00240 ret = rtsp_read_request(s, &request, "SETUP");
00241 if (ret)
00242 return ret;
00243 rt->seq++;
00244 if (!request.nb_transports) {
00245 av_log(s, AV_LOG_ERROR, "No transport defined in SETUP\n");
00246 return AVERROR_INVALIDDATA;
00247 }
00248 for (transportidx = 0; transportidx < request.nb_transports;
00249 transportidx++) {
00250 if (!request.transports[transportidx].mode_record ||
00251 (request.transports[transportidx].lower_transport !=
00252 RTSP_LOWER_TRANSPORT_UDP &&
00253 request.transports[transportidx].lower_transport !=
00254 RTSP_LOWER_TRANSPORT_TCP)) {
00255 av_log(s, AV_LOG_ERROR, "mode=record/receive not set or transport"
00256 " protocol not supported (yet)\n");
00257 return AVERROR_INVALIDDATA;
00258 }
00259 }
00260 if (request.nb_transports > 1)
00261 av_log(s, AV_LOG_WARNING, "More than one transport not supported, "
00262 "using first of all\n");
00263 for (streamid = 0; streamid < rt->nb_rtsp_streams; streamid++) {
00264 if (!strcmp(rt->rtsp_streams[streamid]->control_url,
00265 controlurl))
00266 break;
00267 }
00268 if (streamid == rt->nb_rtsp_streams) {
00269 av_log(s, AV_LOG_ERROR, "Unable to find requested track\n");
00270 return AVERROR_STREAM_NOT_FOUND;
00271 }
00272 rtsp_st = rt->rtsp_streams[streamid];
00273 localport = rt->rtp_port_min;
00274
00275 if (request.transports[0].lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
00276 rt->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
00277 if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
00278 rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
00279 return ret;
00280 }
00281 rtsp_st->interleaved_min = request.transports[0].interleaved_min;
00282 rtsp_st->interleaved_max = request.transports[0].interleaved_max;
00283 snprintf(responseheaders, sizeof(responseheaders), "Transport: "
00284 "RTP/AVP/TCP;unicast;mode=receive;interleaved=%d-%d"
00285 "\r\n", request.transports[0].interleaved_min,
00286 request.transports[0].interleaved_max);
00287 } else {
00288 do {
00289 ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
00290 av_dlog(s, "Opening: %s", url);
00291 ret = ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
00292 &s->interrupt_callback, NULL);
00293 if (ret)
00294 localport += 2;
00295 } while (ret || localport > rt->rtp_port_max);
00296 if (localport > rt->rtp_port_max) {
00297 rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
00298 return ret;
00299 }
00300
00301 av_dlog(s, "Listening on: %d",
00302 ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle));
00303 if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
00304 rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
00305 return ret;
00306 }
00307
00308 localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
00309 snprintf(responseheaders, sizeof(responseheaders), "Transport: "
00310 "RTP/AVP/UDP;unicast;mode=receive;source=%s;"
00311 "client_port=%d-%d;server_port=%d-%d\r\n",
00312 host, request.transports[0].client_port_min,
00313 request.transports[0].client_port_max, localport,
00314 localport + 1);
00315 }
00316
00317
00318
00319
00320 while (strlen(rt->session_id) < 8)
00321 av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());
00322
00323 av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
00324 rt->session_id);
00325
00326 rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
00327
00328 rt->state = RTSP_STATE_PAUSED;
00329 return 0;
00330 }
00331
00332 static int rtsp_read_record(AVFormatContext *s)
00333 {
00334 RTSPState *rt = s->priv_data;
00335 RTSPMessageHeader request = { 0 };
00336 int ret = 0;
00337 char responseheaders[1024];
00338
00339 ret = rtsp_read_request(s, &request, "RECORD");
00340 if (ret)
00341 return ret;
00342 ret = check_sessionid(s, &request);
00343 if (ret)
00344 return ret;
00345 rt->seq++;
00346 snprintf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
00347 rt->session_id);
00348 rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
00349
00350 rt->state = RTSP_STATE_STREAMING;
00351 return 0;
00352 }
00353
00354 static inline int parse_command_line(AVFormatContext *s, const char *line,
00355 int linelen, char *uri, int urisize,
00356 char *method, int methodsize,
00357 enum RTSPMethod *methodcode)
00358 {
00359 RTSPState *rt = s->priv_data;
00360 const char *linept, *searchlinept;
00361 linept = strchr(line, ' ');
00362 if (linept - line > methodsize - 1) {
00363 av_log(s, AV_LOG_ERROR, "Method string too long\n");
00364 return AVERROR(EIO);
00365 }
00366 memcpy(method, line, linept - line);
00367 method[linept - line] = '\0';
00368 linept++;
00369 if (!strcmp(method, "ANNOUNCE"))
00370 *methodcode = ANNOUNCE;
00371 else if (!strcmp(method, "OPTIONS"))
00372 *methodcode = OPTIONS;
00373 else if (!strcmp(method, "RECORD"))
00374 *methodcode = RECORD;
00375 else if (!strcmp(method, "SETUP"))
00376 *methodcode = SETUP;
00377 else if (!strcmp(method, "PAUSE"))
00378 *methodcode = PAUSE;
00379 else if (!strcmp(method, "TEARDOWN"))
00380 *methodcode = TEARDOWN;
00381 else
00382 *methodcode = UNKNOWN;
00383
00384 if (rt->state == RTSP_STATE_IDLE) {
00385 if ((*methodcode != ANNOUNCE) && (*methodcode != OPTIONS)) {
00386 av_log(s, AV_LOG_ERROR, "Unexpected command in Idle State %s\n",
00387 line);
00388 return AVERROR_PROTOCOL_NOT_FOUND;
00389 }
00390 } else if (rt->state == RTSP_STATE_PAUSED) {
00391 if ((*methodcode != OPTIONS) && (*methodcode != RECORD)
00392 && (*methodcode != SETUP)) {
00393 av_log(s, AV_LOG_ERROR, "Unexpected command in Paused State %s\n",
00394 line);
00395 return AVERROR_PROTOCOL_NOT_FOUND;
00396 }
00397 } else if (rt->state == RTSP_STATE_STREAMING) {
00398 if ((*methodcode != PAUSE) && (*methodcode != OPTIONS)
00399 && (*methodcode != TEARDOWN)) {
00400 av_log(s, AV_LOG_ERROR, "Unexpected command in Streaming State"
00401 " %s\n", line);
00402 return AVERROR_PROTOCOL_NOT_FOUND;
00403 }
00404 } else {
00405 av_log(s, AV_LOG_ERROR, "Unexpected State [%d]\n", rt->state);
00406 return AVERROR_BUG;
00407 }
00408
00409 searchlinept = strchr(linept, ' ');
00410 if (searchlinept == NULL) {
00411 av_log(s, AV_LOG_ERROR, "Error parsing message URI\n");
00412 return AVERROR_INVALIDDATA;
00413 }
00414 if (searchlinept - linept > urisize - 1) {
00415 av_log(s, AV_LOG_ERROR, "uri string length exceeded buffer size\n");
00416 return AVERROR(EIO);
00417 }
00418 memcpy(uri, linept, searchlinept - linept);
00419 uri[searchlinept - linept] = '\0';
00420 if (strcmp(rt->control_uri, uri)) {
00421 char host[128], path[512], auth[128];
00422 int port;
00423 char ctl_host[128], ctl_path[512], ctl_auth[128];
00424 int ctl_port;
00425 av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
00426 path, sizeof(path), uri);
00427 av_url_split(NULL, 0, ctl_auth, sizeof(ctl_auth), ctl_host,
00428 sizeof(ctl_host), &ctl_port, ctl_path, sizeof(ctl_path),
00429 rt->control_uri);
00430 if (strcmp(host, ctl_host))
00431 av_log(s, AV_LOG_INFO, "Host %s differs from expected %s\n",
00432 host, ctl_host);
00433 if (strcmp(path, ctl_path) && *methodcode != SETUP)
00434 av_log(s, AV_LOG_WARNING, "WARNING: Path %s differs from expected"
00435 " %s\n", path, ctl_path);
00436 if (*methodcode == ANNOUNCE) {
00437 av_log(s, AV_LOG_INFO,
00438 "Updating control URI to %s\n", uri);
00439 strcpy(rt->control_uri, uri);
00440 }
00441 }
00442
00443 linept = searchlinept + 1;
00444 if (!av_strstart(linept, "RTSP/1.0", NULL)) {
00445 av_log(s, AV_LOG_ERROR, "Error parsing protocol or version\n");
00446 return AVERROR_PROTOCOL_NOT_FOUND;
00447 }
00448 return 0;
00449 }
00450
00451 int ff_rtsp_parse_streaming_commands(AVFormatContext *s)
00452 {
00453 RTSPState *rt = s->priv_data;
00454 unsigned char rbuf[4096];
00455 unsigned char method[10];
00456 char uri[500];
00457 int ret;
00458 int rbuflen = 0;
00459 RTSPMessageHeader request = { 0 };
00460 enum RTSPMethod methodcode;
00461
00462 ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
00463 if (ret < 0)
00464 return ret;
00465 ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
00466 sizeof(method), &methodcode);
00467 if (ret) {
00468 av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
00469 return ret;
00470 }
00471
00472 ret = rtsp_read_request(s, &request, method);
00473 if (ret)
00474 return ret;
00475 rt->seq++;
00476 if (methodcode == PAUSE) {
00477 rt->state = RTSP_STATE_PAUSED;
00478 ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
00479
00480 } else if (methodcode == OPTIONS) {
00481 ret = rtsp_send_reply(s, RTSP_STATUS_OK,
00482 "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, "
00483 "RECORD\r\n", request.seq);
00484 } else if (methodcode == TEARDOWN) {
00485 rt->state = RTSP_STATE_IDLE;
00486 ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
00487 return 0;
00488 }
00489 return ret;
00490 }
00491
00492 static int rtsp_read_play(AVFormatContext *s)
00493 {
00494 RTSPState *rt = s->priv_data;
00495 RTSPMessageHeader reply1, *reply = &reply1;
00496 int i;
00497 char cmd[1024];
00498
00499 av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
00500 rt->nb_byes = 0;
00501
00502 if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
00503 if (rt->transport == RTSP_TRANSPORT_RTP) {
00504 for (i = 0; i < rt->nb_rtsp_streams; i++) {
00505 RTSPStream *rtsp_st = rt->rtsp_streams[i];
00506 RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
00507 if (!rtpctx)
00508 continue;
00509 ff_rtp_reset_packet_queue(rtpctx);
00510 rtpctx->last_rtcp_ntp_time = AV_NOPTS_VALUE;
00511 rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
00512 rtpctx->base_timestamp = 0;
00513 rtpctx->timestamp = 0;
00514 rtpctx->unwrapped_timestamp = 0;
00515 rtpctx->rtcp_ts_offset = 0;
00516 }
00517 }
00518 if (rt->state == RTSP_STATE_PAUSED) {
00519 cmd[0] = 0;
00520 } else {
00521 snprintf(cmd, sizeof(cmd),
00522 "Range: npt=%"PRId64".%03"PRId64"-\r\n",
00523 rt->seek_timestamp / AV_TIME_BASE,
00524 rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000);
00525 }
00526 ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
00527 if (reply->status_code != RTSP_STATUS_OK) {
00528 return -1;
00529 }
00530 if (rt->transport == RTSP_TRANSPORT_RTP &&
00531 reply->range_start != AV_NOPTS_VALUE) {
00532 for (i = 0; i < rt->nb_rtsp_streams; i++) {
00533 RTSPStream *rtsp_st = rt->rtsp_streams[i];
00534 RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
00535 AVStream *st = NULL;
00536 if (!rtpctx || rtsp_st->stream_index < 0)
00537 continue;
00538 st = s->streams[rtsp_st->stream_index];
00539 rtpctx->range_start_offset =
00540 av_rescale_q(reply->range_start, AV_TIME_BASE_Q,
00541 st->time_base);
00542 }
00543 }
00544 }
00545 rt->state = RTSP_STATE_STREAMING;
00546 return 0;
00547 }
00548
00549
00550 static int rtsp_read_pause(AVFormatContext *s)
00551 {
00552 RTSPState *rt = s->priv_data;
00553 RTSPMessageHeader reply1, *reply = &reply1;
00554
00555 if (rt->state != RTSP_STATE_STREAMING)
00556 return 0;
00557 else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
00558 ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
00559 if (reply->status_code != RTSP_STATUS_OK) {
00560 return -1;
00561 }
00562 }
00563 rt->state = RTSP_STATE_PAUSED;
00564 return 0;
00565 }
00566
00567 int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply)
00568 {
00569 RTSPState *rt = s->priv_data;
00570 char cmd[1024];
00571 unsigned char *content = NULL;
00572 int ret;
00573
00574
00575 snprintf(cmd, sizeof(cmd),
00576 "Accept: application/sdp\r\n");
00577 if (rt->server_type == RTSP_SERVER_REAL) {
00582 av_strlcat(cmd,
00583 "Require: com.real.retain-entity-for-setup\r\n",
00584 sizeof(cmd));
00585 }
00586 ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
00587 if (!content)
00588 return AVERROR_INVALIDDATA;
00589 if (reply->status_code != RTSP_STATUS_OK) {
00590 av_freep(&content);
00591 return AVERROR_INVALIDDATA;
00592 }
00593
00594 av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
00595
00596 ret = ff_sdp_parse(s, (const char *)content);
00597 av_freep(&content);
00598 if (ret < 0)
00599 return ret;
00600
00601 return 0;
00602 }
00603
00604 static int rtsp_listen(AVFormatContext *s)
00605 {
00606 RTSPState *rt = s->priv_data;
00607 char host[128], path[512], auth[128];
00608 char uri[500];
00609 int port;
00610 char tcpname[500];
00611 unsigned char rbuf[4096];
00612 unsigned char method[10];
00613 int rbuflen = 0;
00614 int ret;
00615 enum RTSPMethod methodcode;
00616
00617
00618 av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
00619 path, sizeof(path), s->filename);
00620
00621
00622 ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL, host,
00623 port, "%s", path);
00624
00625 ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port,
00626 "?listen&listen_timeout=%d", rt->initial_timeout * 1000);
00627
00628 if (ret = ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
00629 &s->interrupt_callback, NULL)) {
00630 av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n");
00631 return ret;
00632 }
00633 rt->state = RTSP_STATE_IDLE;
00634 rt->rtsp_hd_out = rt->rtsp_hd;
00635 for (;;) {
00636 ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
00637 if (ret < 0)
00638 return ret;
00639 ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
00640 sizeof(method), &methodcode);
00641 if (ret) {
00642 av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
00643 return ret;
00644 }
00645
00646 if (methodcode == ANNOUNCE) {
00647 ret = rtsp_read_announce(s);
00648 rt->state = RTSP_STATE_PAUSED;
00649 } else if (methodcode == OPTIONS) {
00650 ret = rtsp_read_options(s);
00651 } else if (methodcode == RECORD) {
00652 ret = rtsp_read_record(s);
00653 if (!ret)
00654 return 0;
00655 } else if (methodcode == SETUP)
00656 ret = rtsp_read_setup(s, host, uri);
00657 if (ret) {
00658 ffurl_close(rt->rtsp_hd);
00659 return AVERROR_INVALIDDATA;
00660 }
00661 }
00662 return 0;
00663 }
00664
00665 static int rtsp_probe(AVProbeData *p)
00666 {
00667 if (av_strstart(p->filename, "rtsp:", NULL))
00668 return AVPROBE_SCORE_MAX;
00669 return 0;
00670 }
00671
00672 static int rtsp_read_header(AVFormatContext *s)
00673 {
00674 RTSPState *rt = s->priv_data;
00675 int ret;
00676
00677 if (rt->initial_timeout > 0)
00678 rt->rtsp_flags |= RTSP_FLAG_LISTEN;
00679
00680 if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
00681 ret = rtsp_listen(s);
00682 if (ret)
00683 return ret;
00684 } else {
00685 ret = ff_rtsp_connect(s);
00686 if (ret)
00687 return ret;
00688
00689 rt->real_setup_cache = !s->nb_streams ? NULL :
00690 av_mallocz(2 * s->nb_streams * sizeof(*rt->real_setup_cache));
00691 if (!rt->real_setup_cache && s->nb_streams)
00692 return AVERROR(ENOMEM);
00693 rt->real_setup = rt->real_setup_cache + s->nb_streams;
00694
00695 if (rt->initial_pause) {
00696
00697 } else {
00698 if (rtsp_read_play(s) < 0) {
00699 ff_rtsp_close_streams(s);
00700 ff_rtsp_close_connections(s);
00701 return AVERROR_INVALIDDATA;
00702 }
00703 }
00704 }
00705
00706 return 0;
00707 }
00708
00709 int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
00710 uint8_t *buf, int buf_size)
00711 {
00712 RTSPState *rt = s->priv_data;
00713 int id, len, i, ret;
00714 RTSPStream *rtsp_st;
00715
00716 av_dlog(s, "tcp_read_packet:\n");
00717 redo:
00718 for (;;) {
00719 RTSPMessageHeader reply;
00720
00721 ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
00722 if (ret < 0)
00723 return ret;
00724 if (ret == 1)
00725 break;
00726
00727 if (rt->state != RTSP_STATE_STREAMING)
00728 return 0;
00729 }
00730 ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
00731 if (ret != 3)
00732 return -1;
00733 id = buf[0];
00734 len = AV_RB16(buf + 1);
00735 av_dlog(s, "id=%d len=%d\n", id, len);
00736 if (len > buf_size || len < 8)
00737 goto redo;
00738
00739 ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
00740 if (ret != len)
00741 return -1;
00742 if (rt->transport == RTSP_TRANSPORT_RDT &&
00743 ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
00744 return -1;
00745
00746
00747 for (i = 0; i < rt->nb_rtsp_streams; i++) {
00748 rtsp_st = rt->rtsp_streams[i];
00749 if (id >= rtsp_st->interleaved_min &&
00750 id <= rtsp_st->interleaved_max)
00751 goto found;
00752 }
00753 goto redo;
00754 found:
00755 *prtsp_st = rtsp_st;
00756 return len;
00757 }
00758
00759 static int resetup_tcp(AVFormatContext *s)
00760 {
00761 RTSPState *rt = s->priv_data;
00762 char host[1024];
00763 int port;
00764
00765 av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
00766 s->filename);
00767 ff_rtsp_undo_setup(s);
00768 return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
00769 rt->real_challenge);
00770 }
00771
00772 static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
00773 {
00774 RTSPState *rt = s->priv_data;
00775 int ret;
00776 RTSPMessageHeader reply1, *reply = &reply1;
00777 char cmd[1024];
00778
00779 retry:
00780 if (rt->server_type == RTSP_SERVER_REAL) {
00781 int i;
00782
00783 for (i = 0; i < s->nb_streams; i++)
00784 rt->real_setup[i] = s->streams[i]->discard;
00785
00786 if (!rt->need_subscription) {
00787 if (memcmp (rt->real_setup, rt->real_setup_cache,
00788 sizeof(enum AVDiscard) * s->nb_streams)) {
00789 snprintf(cmd, sizeof(cmd),
00790 "Unsubscribe: %s\r\n",
00791 rt->last_subscription);
00792 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
00793 cmd, reply, NULL);
00794 if (reply->status_code != RTSP_STATUS_OK)
00795 return AVERROR_INVALIDDATA;
00796 rt->need_subscription = 1;
00797 }
00798 }
00799
00800 if (rt->need_subscription) {
00801 int r, rule_nr, first = 1;
00802
00803 memcpy(rt->real_setup_cache, rt->real_setup,
00804 sizeof(enum AVDiscard) * s->nb_streams);
00805 rt->last_subscription[0] = 0;
00806
00807 snprintf(cmd, sizeof(cmd),
00808 "Subscribe: ");
00809 for (i = 0; i < rt->nb_rtsp_streams; i++) {
00810 rule_nr = 0;
00811 for (r = 0; r < s->nb_streams; r++) {
00812 if (s->streams[r]->id == i) {
00813 if (s->streams[r]->discard != AVDISCARD_ALL) {
00814 if (!first)
00815 av_strlcat(rt->last_subscription, ",",
00816 sizeof(rt->last_subscription));
00817 ff_rdt_subscribe_rule(
00818 rt->last_subscription,
00819 sizeof(rt->last_subscription), i, rule_nr);
00820 first = 0;
00821 }
00822 rule_nr++;
00823 }
00824 }
00825 }
00826 av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
00827 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
00828 cmd, reply, NULL);
00829 if (reply->status_code != RTSP_STATUS_OK)
00830 return AVERROR_INVALIDDATA;
00831 rt->need_subscription = 0;
00832
00833 if (rt->state == RTSP_STATE_STREAMING)
00834 rtsp_read_play (s);
00835 }
00836 }
00837
00838 ret = ff_rtsp_fetch_packet(s, pkt);
00839 if (ret < 0) {
00840 if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
00841 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
00842 rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP)) {
00843 RTSPMessageHeader reply1, *reply = &reply1;
00844 av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
00845 if (rtsp_read_pause(s) != 0)
00846 return -1;
00847
00848
00849 if (rt->server_type == RTSP_SERVER_REAL)
00850 ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
00851 reply, NULL);
00852 rt->session_id[0] = '\0';
00853 if (resetup_tcp(s) == 0) {
00854 rt->state = RTSP_STATE_IDLE;
00855 rt->need_subscription = 1;
00856 if (rtsp_read_play(s) != 0)
00857 return -1;
00858 goto retry;
00859 }
00860 }
00861 }
00862 return ret;
00863 }
00864 rt->packets++;
00865
00866 if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
00867
00868 if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
00869 rt->auth_state.stale) {
00870 if (rt->server_type == RTSP_SERVER_WMS ||
00871 (rt->server_type != RTSP_SERVER_REAL &&
00872 rt->get_parameter_supported)) {
00873 ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
00874 } else {
00875 ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);
00876 }
00877
00878
00879
00880 rt->auth_state.stale = 0;
00881 }
00882 }
00883
00884 return 0;
00885 }
00886
00887 static int rtsp_read_seek(AVFormatContext *s, int stream_index,
00888 int64_t timestamp, int flags)
00889 {
00890 RTSPState *rt = s->priv_data;
00891
00892 rt->seek_timestamp = av_rescale_q(timestamp,
00893 s->streams[stream_index]->time_base,
00894 AV_TIME_BASE_Q);
00895 switch(rt->state) {
00896 default:
00897 case RTSP_STATE_IDLE:
00898 break;
00899 case RTSP_STATE_STREAMING:
00900 if (rtsp_read_pause(s) != 0)
00901 return -1;
00902 rt->state = RTSP_STATE_SEEKING;
00903 if (rtsp_read_play(s) != 0)
00904 return -1;
00905 break;
00906 case RTSP_STATE_PAUSED:
00907 rt->state = RTSP_STATE_IDLE;
00908 break;
00909 }
00910 return 0;
00911 }
00912
00913 static const AVClass rtsp_demuxer_class = {
00914 .class_name = "RTSP demuxer",
00915 .item_name = av_default_item_name,
00916 .option = ff_rtsp_options,
00917 .version = LIBAVUTIL_VERSION_INT,
00918 };
00919
00920 AVInputFormat ff_rtsp_demuxer = {
00921 .name = "rtsp",
00922 .long_name = NULL_IF_CONFIG_SMALL("RTSP input"),
00923 .priv_data_size = sizeof(RTSPState),
00924 .read_probe = rtsp_probe,
00925 .read_header = rtsp_read_header,
00926 .read_packet = rtsp_read_packet,
00927 .read_close = rtsp_read_close,
00928 .read_seek = rtsp_read_seek,
00929 .flags = AVFMT_NOFILE,
00930 .read_play = rtsp_read_play,
00931 .read_pause = rtsp_read_pause,
00932 .priv_class = &rtsp_demuxer_class,
00933 };