| OLD | NEW |
| 1 /* | 1 /* |
| 2 * RTSP/SDP client | 2 * RTSP/SDP client |
| 3 * Copyright (c) 2002 Fabrice Bellard | 3 * Copyright (c) 2002 Fabrice Bellard |
| 4 * | 4 * |
| 5 * This file is part of FFmpeg. | 5 * This file is part of FFmpeg. |
| 6 * | 6 * |
| 7 * FFmpeg is free software; you can redistribute it and/or | 7 * FFmpeg is free software; you can redistribute it and/or |
| 8 * modify it under the terms of the GNU Lesser General Public | 8 * modify it under the terms of the GNU Lesser General Public |
| 9 * License as published by the Free Software Foundation; either | 9 * License as published by the Free Software Foundation; either |
| 10 * version 2.1 of the License, or (at your option) any later version. | 10 * version 2.1 of the License, or (at your option) any later version. |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 (*p)++; | 266 (*p)++; |
| 267 return 1; | 267 return 1; |
| 268 } | 268 } |
| 269 return 0; | 269 return 0; |
| 270 } | 270 } |
| 271 | 271 |
| 272 /* parse a SDP line and save stream attributes */ | 272 /* parse a SDP line and save stream attributes */ |
| 273 static void sdp_parse_fmtp(AVStream *st, const char *p) | 273 static void sdp_parse_fmtp(AVStream *st, const char *p) |
| 274 { | 274 { |
| 275 char attr[256]; | 275 char attr[256]; |
| 276 /* Vorbis setup headers can be up to 12KB and are sent base64 | 276 char value[4096]; |
| 277 * encoded, giving a 12KB * (4/3) = 16KB FMTP line. */ | |
| 278 char value[16384]; | |
| 279 int i; | 277 int i; |
| 280 RTSPStream *rtsp_st = st->priv_data; | 278 RTSPStream *rtsp_st = st->priv_data; |
| 281 AVCodecContext *codec = st->codec; | 279 AVCodecContext *codec = st->codec; |
| 282 RTPPayloadData *rtp_payload_data = &rtsp_st->rtp_payload_data; | 280 RTPPayloadData *rtp_payload_data = &rtsp_st->rtp_payload_data; |
| 283 | 281 |
| 284 /* loop on each attribute */ | 282 /* loop on each attribute */ |
| 285 while (ff_rtsp_next_attr_and_value(&p, attr, sizeof(attr), | 283 while (ff_rtsp_next_attr_and_value(&p, attr, sizeof(attr), |
| 286 value, sizeof(value))) { | 284 value, sizeof(value))) { |
| 287 /* grab the codec extra_data from the config parameter of the fmtp | 285 /* grab the codec extra_data from the config parameter of the fmtp |
| 288 * line */ | 286 * line */ |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 static int sdp_parse(AVFormatContext *s, const char *content) | 532 static int sdp_parse(AVFormatContext *s, const char *content) |
| 535 { | 533 { |
| 536 const char *p; | 534 const char *p; |
| 537 int letter; | 535 int letter; |
| 538 /* Some SDP lines, particularly for Realmedia or ASF RTSP streams, | 536 /* Some SDP lines, particularly for Realmedia or ASF RTSP streams, |
| 539 * contain long SDP lines containing complete ASF Headers (several | 537 * contain long SDP lines containing complete ASF Headers (several |
| 540 * kB) or arrays of MDPR (RM stream descriptor) headers plus | 538 * kB) or arrays of MDPR (RM stream descriptor) headers plus |
| 541 * "rulebooks" describing their properties. Therefore, the SDP line | 539 * "rulebooks" describing their properties. Therefore, the SDP line |
| 542 * buffer is large. | 540 * buffer is large. |
| 543 * | 541 * |
| 544 * The Vorbis FMTP line can be up to 16KB - see sdp_parse_fmtp. */ | 542 * The Vorbis FMTP line can be up to 16KB - see xiph_parse_sdp_line |
| 543 * in rtpdec_xiph.c. */ |
| 545 char buf[16384], *q; | 544 char buf[16384], *q; |
| 546 SDPParseState sdp_parse_state, *s1 = &sdp_parse_state; | 545 SDPParseState sdp_parse_state, *s1 = &sdp_parse_state; |
| 547 | 546 |
| 548 memset(s1, 0, sizeof(SDPParseState)); | 547 memset(s1, 0, sizeof(SDPParseState)); |
| 549 p = content; | 548 p = content; |
| 550 for (;;) { | 549 for (;;) { |
| 551 skip_spaces(&p); | 550 skip_spaces(&p); |
| 552 letter = *p; | 551 letter = *p; |
| 553 if (letter == '\0') | 552 if (letter == '\0') |
| 554 break; | 553 break; |
| (...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 } | 1476 } |
| 1478 | 1477 |
| 1479 return 0; | 1478 return 0; |
| 1480 } | 1479 } |
| 1481 | 1480 |
| 1482 void ff_rtsp_close_connections(AVFormatContext *s) | 1481 void ff_rtsp_close_connections(AVFormatContext *s) |
| 1483 { | 1482 { |
| 1484 RTSPState *rt = s->priv_data; | 1483 RTSPState *rt = s->priv_data; |
| 1485 if (rt->rtsp_hd_out != rt->rtsp_hd) url_close(rt->rtsp_hd_out); | 1484 if (rt->rtsp_hd_out != rt->rtsp_hd) url_close(rt->rtsp_hd_out); |
| 1486 url_close(rt->rtsp_hd); | 1485 url_close(rt->rtsp_hd); |
| 1486 rt->rtsp_hd = rt->rtsp_hd_out = NULL; |
| 1487 } | 1487 } |
| 1488 | 1488 |
| 1489 int ff_rtsp_connect(AVFormatContext *s) | 1489 int ff_rtsp_connect(AVFormatContext *s) |
| 1490 { | 1490 { |
| 1491 RTSPState *rt = s->priv_data; | 1491 RTSPState *rt = s->priv_data; |
| 1492 char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128]; | 1492 char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128]; |
| 1493 char *option_list, *option, *filename; | 1493 char *option_list, *option, *filename; |
| 1494 URLContext *rtsp_hd, *rtsp_hd_out; | |
| 1495 int port, err, tcp_fd; | 1494 int port, err, tcp_fd; |
| 1496 RTSPMessageHeader reply1 = {}, *reply = &reply1; | 1495 RTSPMessageHeader reply1 = {}, *reply = &reply1; |
| 1497 int lower_transport_mask = 0; | 1496 int lower_transport_mask = 0; |
| 1498 char real_challenge[64]; | 1497 char real_challenge[64]; |
| 1499 struct sockaddr_storage peer; | 1498 struct sockaddr_storage peer; |
| 1500 socklen_t peer_len = sizeof(peer); | 1499 socklen_t peer_len = sizeof(peer); |
| 1501 | 1500 |
| 1502 if (!ff_network_init()) | 1501 if (!ff_network_init()) |
| 1503 return AVERROR(EIO); | 1502 return AVERROR(EIO); |
| 1504 redirect: | 1503 redirect: |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1567 * stripped out. */ | 1566 * stripped out. */ |
| 1568 ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL, | 1567 ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL, |
| 1569 host, port, "%s", path); | 1568 host, port, "%s", path); |
| 1570 | 1569 |
| 1571 if (rt->control_transport == RTSP_MODE_TUNNEL) { | 1570 if (rt->control_transport == RTSP_MODE_TUNNEL) { |
| 1572 /* set up initial handshake for tunneling */ | 1571 /* set up initial handshake for tunneling */ |
| 1573 char httpname[1024]; | 1572 char httpname[1024]; |
| 1574 char sessioncookie[17]; | 1573 char sessioncookie[17]; |
| 1575 char headers[1024]; | 1574 char headers[1024]; |
| 1576 | 1575 |
| 1577 ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s",
path); | 1576 ff_url_join(httpname, sizeof(httpname), "http", auth, host, port, "%s",
path); |
| 1578 snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x", | 1577 snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x", |
| 1579 av_get_random_seed(), av_get_random_seed()); | 1578 av_get_random_seed(), av_get_random_seed()); |
| 1580 | 1579 |
| 1581 /* GET requests */ | 1580 /* GET requests */ |
| 1582 if (url_open(&rtsp_hd, httpname, URL_RDONLY) < 0) { | 1581 if (url_open(&rt->rtsp_hd, httpname, URL_RDONLY) < 0) { |
| 1583 err = AVERROR(EIO); | 1582 err = AVERROR(EIO); |
| 1584 goto fail; | 1583 goto fail; |
| 1585 } | 1584 } |
| 1586 | 1585 |
| 1587 /* generate GET headers */ | 1586 /* generate GET headers */ |
| 1588 snprintf(headers, sizeof(headers), | 1587 snprintf(headers, sizeof(headers), |
| 1589 "x-sessioncookie: %s\r\n" | 1588 "x-sessioncookie: %s\r\n" |
| 1590 "Accept: application/x-rtsp-tunnelled\r\n" | 1589 "Accept: application/x-rtsp-tunnelled\r\n" |
| 1591 "Pragma: no-cache\r\n" | 1590 "Pragma: no-cache\r\n" |
| 1592 "Cache-Control: no-cache\r\n", | 1591 "Cache-Control: no-cache\r\n", |
| 1593 sessioncookie); | 1592 sessioncookie); |
| 1594 ff_http_set_headers(rtsp_hd, headers); | 1593 ff_http_set_headers(rt->rtsp_hd, headers); |
| 1595 | 1594 |
| 1596 /* complete the connection */ | 1595 /* complete the connection */ |
| 1597 if (url_read(rtsp_hd, NULL, 0)) { | 1596 if (url_read(rt->rtsp_hd, NULL, 0)) { |
| 1598 err = AVERROR(EIO); | 1597 err = AVERROR(EIO); |
| 1599 goto fail; | 1598 goto fail; |
| 1600 } | 1599 } |
| 1601 | 1600 |
| 1602 /* POST requests */ | 1601 /* POST requests */ |
| 1603 if (url_open(&rtsp_hd_out, httpname, URL_WRONLY) < 0 ) { | 1602 if (url_open(&rt->rtsp_hd_out, httpname, URL_WRONLY) < 0 ) { |
| 1604 err = AVERROR(EIO); | 1603 err = AVERROR(EIO); |
| 1605 goto fail; | 1604 goto fail; |
| 1606 } | 1605 } |
| 1607 | 1606 |
| 1608 /* generate POST headers */ | 1607 /* generate POST headers */ |
| 1609 snprintf(headers, sizeof(headers), | 1608 snprintf(headers, sizeof(headers), |
| 1610 "x-sessioncookie: %s\r\n" | 1609 "x-sessioncookie: %s\r\n" |
| 1611 "Content-Type: application/x-rtsp-tunnelled\r\n" | 1610 "Content-Type: application/x-rtsp-tunnelled\r\n" |
| 1612 "Pragma: no-cache\r\n" | 1611 "Pragma: no-cache\r\n" |
| 1613 "Cache-Control: no-cache\r\n" | 1612 "Cache-Control: no-cache\r\n" |
| 1614 "Content-Length: 32767\r\n" | 1613 "Content-Length: 32767\r\n" |
| 1615 "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n", | 1614 "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n", |
| 1616 sessioncookie); | 1615 sessioncookie); |
| 1617 ff_http_set_headers(rtsp_hd_out, headers); | 1616 ff_http_set_headers(rt->rtsp_hd_out, headers); |
| 1618 ff_http_set_chunked_transfer_encoding(rtsp_hd_out, 0); | 1617 ff_http_set_chunked_transfer_encoding(rt->rtsp_hd_out, 0); |
| 1619 | 1618 |
| 1620 } else { | 1619 } else { |
| 1621 /* open the tcp connexion */ | 1620 /* open the tcp connection */ |
| 1622 ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL); | 1621 ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL); |
| 1623 if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0) { | 1622 if (url_open(&rt->rtsp_hd, tcpname, URL_RDWR) < 0) { |
| 1624 err = AVERROR(EIO); | 1623 err = AVERROR(EIO); |
| 1625 goto fail; | 1624 goto fail; |
| 1625 } |
| 1626 rt->rtsp_hd_out = rt->rtsp_hd; |
| 1626 } | 1627 } |
| 1627 rtsp_hd_out = rtsp_hd; | |
| 1628 } | |
| 1629 rt->rtsp_hd = rtsp_hd; | |
| 1630 rt->rtsp_hd_out = rtsp_hd_out; | |
| 1631 rt->seq = 0; | 1628 rt->seq = 0; |
| 1632 | 1629 |
| 1633 tcp_fd = url_get_file_handle(rtsp_hd); | 1630 tcp_fd = url_get_file_handle(rt->rtsp_hd); |
| 1634 if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) { | 1631 if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) { |
| 1635 getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host), | 1632 getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host), |
| 1636 NULL, 0, NI_NUMERICHOST); | 1633 NULL, 0, NI_NUMERICHOST); |
| 1637 } | 1634 } |
| 1638 | 1635 |
| 1639 /* request options supported by the server; this also detects server | 1636 /* request options supported by the server; this also detects server |
| 1640 * type */ | 1637 * type */ |
| 1641 for (rt->server_type = RTSP_SERVER_RTP;;) { | 1638 for (rt->server_type = RTSP_SERVER_RTP;;) { |
| 1642 cmd[0] = 0; | 1639 cmd[0] = 0; |
| 1643 if (rt->server_type == RTSP_SERVER_REAL) | 1640 if (rt->server_type == RTSP_SERVER_REAL) |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2170 | 2167 |
| 2171 AVInputFormat sdp_demuxer = { | 2168 AVInputFormat sdp_demuxer = { |
| 2172 "sdp", | 2169 "sdp", |
| 2173 NULL_IF_CONFIG_SMALL("SDP"), | 2170 NULL_IF_CONFIG_SMALL("SDP"), |
| 2174 sizeof(RTSPState), | 2171 sizeof(RTSPState), |
| 2175 sdp_probe, | 2172 sdp_probe, |
| 2176 sdp_read_header, | 2173 sdp_read_header, |
| 2177 rtsp_fetch_packet, | 2174 rtsp_fetch_packet, |
| 2178 sdp_read_close, | 2175 sdp_read_close, |
| 2179 }; | 2176 }; |
| OLD | NEW |