Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: source/patched-ffmpeg-mt/libavformat/rtsp.c

Issue 3384002: ffmpeg source update for sep 09 (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/ffmpeg/
Patch Set: Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 *start = parse_date(buf, 1); 197 *start = parse_date(buf, 1);
198 if (*p == '-') { 198 if (*p == '-') {
199 p++; 199 p++;
200 get_word_sep(buf, sizeof(buf), "-", &p); 200 get_word_sep(buf, sizeof(buf), "-", &p);
201 *end = parse_date(buf, 1); 201 *end = parse_date(buf, 1);
202 } 202 }
203 // av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start); 203 // av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start);
204 // av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end); 204 // av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end);
205 } 205 }
206 206
207 static int get_sockaddr(const char *buf, struct sockaddr_storage *sock)
208 {
209 struct addrinfo hints, *ai = NULL;
210 memset(&hints, 0, sizeof(hints));
211 hints.ai_flags = AI_NUMERICHOST;
212 if (getaddrinfo(buf, NULL, &hints, &ai))
213 return -1;
214 memcpy(sock, ai->ai_addr, FFMIN(sizeof(*sock), ai->ai_addrlen));
215 freeaddrinfo(ai);
216 return 0;
217 }
218
207 typedef struct SDPParseState { 219 typedef struct SDPParseState {
208 /* SDP only */ 220 /* SDP only */
209 struct in_addr default_ip; 221 struct sockaddr_storage default_ip;
210 int default_ttl; 222 int default_ttl;
211 int skip_media; ///< set if an unknown m= line occurs 223 int skip_media; ///< set if an unknown m= line occurs
212 } SDPParseState; 224 } SDPParseState;
213 225
214 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, 226 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
215 int letter, const char *buf) 227 int letter, const char *buf)
216 { 228 {
217 RTSPState *rt = s->priv_data; 229 RTSPState *rt = s->priv_data;
218 char buf1[64], st_type[64]; 230 char buf1[64], st_type[64];
219 const char *p; 231 const char *p;
220 enum AVMediaType codec_type; 232 enum AVMediaType codec_type;
221 int payload_type, i; 233 int payload_type, i;
222 AVStream *st; 234 AVStream *st;
223 RTSPStream *rtsp_st; 235 RTSPStream *rtsp_st;
224 struct in_addr sdp_ip; 236 struct sockaddr_storage sdp_ip;
225 int ttl; 237 int ttl;
226 238
227 dprintf(s, "sdp: %c='%s'\n", letter, buf); 239 dprintf(s, "sdp: %c='%s'\n", letter, buf);
228 240
229 p = buf; 241 p = buf;
230 if (s1->skip_media && letter != 'm') 242 if (s1->skip_media && letter != 'm')
231 return; 243 return;
232 switch (letter) { 244 switch (letter) {
233 case 'c': 245 case 'c':
234 get_word(buf1, sizeof(buf1), &p); 246 get_word(buf1, sizeof(buf1), &p);
235 if (strcmp(buf1, "IN") != 0) 247 if (strcmp(buf1, "IN") != 0)
236 return; 248 return;
237 get_word(buf1, sizeof(buf1), &p); 249 get_word(buf1, sizeof(buf1), &p);
238 if (strcmp(buf1, "IP4") != 0) 250 if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6"))
239 return; 251 return;
240 get_word_sep(buf1, sizeof(buf1), "/", &p); 252 get_word_sep(buf1, sizeof(buf1), "/", &p);
241 if (ff_inet_aton(buf1, &sdp_ip) == 0) 253 if (get_sockaddr(buf1, &sdp_ip))
242 return; 254 return;
243 ttl = 16; 255 ttl = 16;
244 if (*p == '/') { 256 if (*p == '/') {
245 p++; 257 p++;
246 get_word_sep(buf1, sizeof(buf1), "/", &p); 258 get_word_sep(buf1, sizeof(buf1), "/", &p);
247 ttl = atoi(buf1); 259 ttl = atoi(buf1);
248 } 260 }
249 if (s->nb_streams == 0) { 261 if (s->nb_streams == 0) {
250 s1->default_ip = sdp_ip; 262 s1->default_ip = sdp_ip;
251 s1->default_ttl = ttl; 263 s1->default_ttl = ttl;
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 } 689 }
678 } else if (!strcmp(parameter, "multicast")) { 690 } else if (!strcmp(parameter, "multicast")) {
679 if (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP) 691 if (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP)
680 th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST; 692 th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST;
681 } else if (!strcmp(parameter, "ttl")) { 693 } else if (!strcmp(parameter, "ttl")) {
682 if (*p == '=') { 694 if (*p == '=') {
683 p++; 695 p++;
684 th->ttl = strtol(p, (char **)&p, 10); 696 th->ttl = strtol(p, (char **)&p, 10);
685 } 697 }
686 } else if (!strcmp(parameter, "destination")) { 698 } else if (!strcmp(parameter, "destination")) {
687 struct in_addr ipaddr;
688
689 if (*p == '=') { 699 if (*p == '=') {
690 p++; 700 p++;
691 get_word_sep(buf, sizeof(buf), ";,", &p); 701 get_word_sep(buf, sizeof(buf), ";,", &p);
692 if (ff_inet_aton(buf, &ipaddr)) 702 get_sockaddr(buf, &th->destination);
693 th->destination = ntohl(ipaddr.s_addr); 703 }
704 } else if (!strcmp(parameter, "source")) {
705 if (*p == '=') {
706 p++;
707 get_word_sep(buf, sizeof(buf), ";,", &p);
708 av_strlcpy(th->source, buf, sizeof(th->source));
694 } 709 }
695 } 710 }
711
696 while (*p != ';' && *p != '\0' && *p != ',') 712 while (*p != ';' && *p != '\0' && *p != ',')
697 p++; 713 p++;
698 if (*p == ';') 714 if (*p == ';')
699 p++; 715 p++;
700 } 716 }
701 if (*p == ',') 717 if (*p == ',')
702 p++; 718 p++;
703 719
704 reply->nb_transports++; 720 reply->nb_transports++;
705 } 721 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
790 /* parse reply (XXX: use buffers) */ 806 /* parse reply (XXX: use buffers) */
791 rt->last_reply[0] = '\0'; 807 rt->last_reply[0] = '\0';
792 for (;;) { 808 for (;;) {
793 q = buf; 809 q = buf;
794 for (;;) { 810 for (;;) {
795 ret = url_read_complete(rt->rtsp_hd, &ch, 1); 811 ret = url_read_complete(rt->rtsp_hd, &ch, 1);
796 #ifdef DEBUG_RTP_TCP 812 #ifdef DEBUG_RTP_TCP
797 dprintf(s, "ret=%d c=%02x [%c]\n", ret, ch, ch); 813 dprintf(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
798 #endif 814 #endif
799 if (ret != 1) 815 if (ret != 1)
800 return -1; 816 return AVERROR_EOF;
801 if (ch == '\n') 817 if (ch == '\n')
802 break; 818 break;
803 if (ch == '$') { 819 if (ch == '$') {
804 /* XXX: only parse it if first char on line ? */ 820 /* XXX: only parse it if first char on line ? */
805 if (return_on_interleaved_data) { 821 if (return_on_interleaved_data) {
806 return 1; 822 return 1;
807 } else 823 } else
808 ff_rtsp_skip_packet(s); 824 ff_rtsp_skip_packet(s);
809 } else if (ch != '\r') { 825 } else if (ch != '\r') {
810 if ((q - buf) < sizeof(buf) - 1) 826 if ((q - buf) < sizeof(buf) - 1)
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 1154
1139 switch(reply->transports[0].lower_transport) { 1155 switch(reply->transports[0].lower_transport) {
1140 case RTSP_LOWER_TRANSPORT_TCP: 1156 case RTSP_LOWER_TRANSPORT_TCP:
1141 rtsp_st->interleaved_min = reply->transports[0].interleaved_min; 1157 rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
1142 rtsp_st->interleaved_max = reply->transports[0].interleaved_max; 1158 rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
1143 break; 1159 break;
1144 1160
1145 case RTSP_LOWER_TRANSPORT_UDP: { 1161 case RTSP_LOWER_TRANSPORT_UDP: {
1146 char url[1024]; 1162 char url[1024];
1147 1163
1148 /* XXX: also use address if specified */ 1164 /* Use source address if specified */
1149 ff_url_join(url, sizeof(url), "rtp", NULL, host, 1165 if (reply->transports[0].source[0]) {
1150 reply->transports[0].server_port_min, NULL); 1166 ff_url_join(url, sizeof(url), "rtp", NULL,
1167 reply->transports[0].source,
1168 reply->transports[0].server_port_min, NULL);
1169 } else {
1170 ff_url_join(url, sizeof(url), "rtp", NULL, host,
1171 reply->transports[0].server_port_min, NULL);
1172 }
1151 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && 1173 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
1152 rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) { 1174 rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
1153 err = AVERROR_INVALIDDATA; 1175 err = AVERROR_INVALIDDATA;
1154 goto fail; 1176 goto fail;
1155 } 1177 }
1156 /* Try to initialize the connection state in a 1178 /* Try to initialize the connection state in a
1157 * potential NAT router by sending dummy packets. 1179 * potential NAT router by sending dummy packets.
1158 * RTP/RTCP dummy packets are used for RDT, too. 1180 * RTP/RTCP dummy packets are used for RDT, too.
1159 */ 1181 */
1160 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat) 1182 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat)
1161 rtp_send_punch_packets(rtsp_st->rtp_handle); 1183 rtp_send_punch_packets(rtsp_st->rtp_handle);
1162 break; 1184 break;
1163 } 1185 }
1164 case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: { 1186 case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
1165 char url[1024]; 1187 char url[1024], namebuf[50];
1166 struct in_addr in; 1188 struct sockaddr_storage addr;
1167 int port, ttl; 1189 int port, ttl;
1168 1190
1169 if (reply->transports[0].destination) { 1191 if (reply->transports[0].destination.ss_family) {
1170 in.s_addr = htonl(reply->transports[0].destination); 1192 addr = reply->transports[0].destination;
1171 port = reply->transports[0].port_min; 1193 port = reply->transports[0].port_min;
1172 ttl = reply->transports[0].ttl; 1194 ttl = reply->transports[0].ttl;
1173 } else { 1195 } else {
1174 in = rtsp_st->sdp_ip; 1196 addr = rtsp_st->sdp_ip;
1175 port = rtsp_st->sdp_port; 1197 port = rtsp_st->sdp_port;
1176 ttl = rtsp_st->sdp_ttl; 1198 ttl = rtsp_st->sdp_ttl;
1177 } 1199 }
1178 ff_url_join(url, sizeof(url), "rtp", NULL, inet_ntoa(in), 1200 getnameinfo((struct sockaddr*) &addr, sizeof(addr),
1201 namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
1202 ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
1179 port, "?ttl=%d", ttl); 1203 port, "?ttl=%d", ttl);
1180 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { 1204 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
1181 err = AVERROR_INVALIDDATA; 1205 err = AVERROR_INVALIDDATA;
1182 goto fail; 1206 goto fail;
1183 } 1207 }
1184 break; 1208 break;
1185 } 1209 }
1186 } 1210 }
1187 1211
1188 if ((err = rtsp_open_transport_ctx(s, rtsp_st))) 1212 if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
(...skipping 19 matching lines...) Expand all
1208 } 1232 }
1209 1233
1210 static int rtsp_read_play(AVFormatContext *s) 1234 static int rtsp_read_play(AVFormatContext *s)
1211 { 1235 {
1212 RTSPState *rt = s->priv_data; 1236 RTSPState *rt = s->priv_data;
1213 RTSPMessageHeader reply1, *reply = &reply1; 1237 RTSPMessageHeader reply1, *reply = &reply1;
1214 int i; 1238 int i;
1215 char cmd[1024]; 1239 char cmd[1024];
1216 1240
1217 av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state); 1241 av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
1242 rt->nb_byes = 0;
1218 1243
1219 if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { 1244 if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
1220 if (rt->state == RTSP_STATE_PAUSED) { 1245 if (rt->state == RTSP_STATE_PAUSED) {
1221 cmd[0] = 0; 1246 cmd[0] = 0;
1222 } else { 1247 } else {
1223 snprintf(cmd, sizeof(cmd), 1248 snprintf(cmd, sizeof(cmd),
1224 "Range: npt=%0.3f-\r\n", 1249 "Range: npt=%0.3f-\r\n",
1225 (double)rt->seek_timestamp / AV_TIME_BASE); 1250 (double)rt->seek_timestamp / AV_TIME_BASE);
1226 } 1251 }
1227 ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL); 1252 ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 } 1629 }
1605 ff_network_close(); 1630 ff_network_close();
1606 return err; 1631 return err;
1607 } 1632 }
1608 #endif 1633 #endif
1609 1634
1610 #if CONFIG_RTSP_DEMUXER 1635 #if CONFIG_RTSP_DEMUXER
1611 static int rtsp_read_header(AVFormatContext *s, 1636 static int rtsp_read_header(AVFormatContext *s,
1612 AVFormatParameters *ap) 1637 AVFormatParameters *ap)
1613 { 1638 {
1639 RTSPState *rt = s->priv_data;
1614 int ret; 1640 int ret;
1615 1641
1616 ret = ff_rtsp_connect(s); 1642 ret = ff_rtsp_connect(s);
1617 if (ret) 1643 if (ret)
1618 return ret; 1644 return ret;
1619 1645
1646 rt->real_setup_cache = av_mallocz(2 * s->nb_streams * sizeof(*rt->real_setup _cache));
1647 if (!rt->real_setup_cache)
1648 return AVERROR(ENOMEM);
1649 rt->real_setup = rt->real_setup_cache + s->nb_streams * sizeof(*rt->real_set up);
1650
1620 if (ap->initial_pause) { 1651 if (ap->initial_pause) {
1621 /* do not start immediately */ 1652 /* do not start immediately */
1622 } else { 1653 } else {
1623 if (rtsp_read_play(s) < 0) { 1654 if (rtsp_read_play(s) < 0) {
1624 ff_rtsp_close_streams(s); 1655 ff_rtsp_close_streams(s);
1625 ff_rtsp_close_connections(s); 1656 ff_rtsp_close_connections(s);
1626 return AVERROR_INVALIDDATA; 1657 return AVERROR_INVALIDDATA;
1627 } 1658 }
1628 } 1659 }
1629 1660
1630 return 0; 1661 return 0;
1631 } 1662 }
1632 1663
1633 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, 1664 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
1634 uint8_t *buf, int buf_size) 1665 uint8_t *buf, int buf_size)
1635 { 1666 {
1636 RTSPState *rt = s->priv_data; 1667 RTSPState *rt = s->priv_data;
1637 RTSPStream *rtsp_st; 1668 RTSPStream *rtsp_st;
1638 fd_set rfds; 1669 fd_set rfds;
1639 int fd, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0; 1670 int fd, fd_rtcp, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0;
1640 struct timeval tv; 1671 struct timeval tv;
1641 1672
1642 for (;;) { 1673 for (;;) {
1643 if (url_interrupt_cb()) 1674 if (url_interrupt_cb())
1644 return AVERROR(EINTR); 1675 return AVERROR(EINTR);
1645 FD_ZERO(&rfds); 1676 FD_ZERO(&rfds);
1646 if (rt->rtsp_hd) { 1677 if (rt->rtsp_hd) {
1647 tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd); 1678 tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
1648 FD_SET(tcp_fd, &rfds); 1679 FD_SET(tcp_fd, &rfds);
1649 } else { 1680 } else {
1650 fd_max = 0; 1681 fd_max = 0;
1651 tcp_fd = -1; 1682 tcp_fd = -1;
1652 } 1683 }
1653 for (i = 0; i < rt->nb_rtsp_streams; i++) { 1684 for (i = 0; i < rt->nb_rtsp_streams; i++) {
1654 rtsp_st = rt->rtsp_streams[i]; 1685 rtsp_st = rt->rtsp_streams[i];
1655 if (rtsp_st->rtp_handle) { 1686 if (rtsp_st->rtp_handle) {
1656 /* currently, we cannot probe RTCP handle because of
1657 * blocking restrictions */
1658 fd = url_get_file_handle(rtsp_st->rtp_handle); 1687 fd = url_get_file_handle(rtsp_st->rtp_handle);
1659 if (fd > fd_max) 1688 fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
1660 fd_max = fd; 1689 if (FFMAX(fd, fd_rtcp) > fd_max)
1690 fd_max = FFMAX(fd, fd_rtcp);
1661 FD_SET(fd, &rfds); 1691 FD_SET(fd, &rfds);
1692 FD_SET(fd_rtcp, &rfds);
1662 } 1693 }
1663 } 1694 }
1664 tv.tv_sec = 0; 1695 tv.tv_sec = 0;
1665 tv.tv_usec = SELECT_TIMEOUT_MS * 1000; 1696 tv.tv_usec = SELECT_TIMEOUT_MS * 1000;
1666 n = select(fd_max + 1, &rfds, NULL, NULL, &tv); 1697 n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
1667 if (n > 0) { 1698 if (n > 0) {
1668 timeout_cnt = 0; 1699 timeout_cnt = 0;
1669 for (i = 0; i < rt->nb_rtsp_streams; i++) { 1700 for (i = 0; i < rt->nb_rtsp_streams; i++) {
1670 rtsp_st = rt->rtsp_streams[i]; 1701 rtsp_st = rt->rtsp_streams[i];
1671 if (rtsp_st->rtp_handle) { 1702 if (rtsp_st->rtp_handle) {
1672 fd = url_get_file_handle(rtsp_st->rtp_handle); 1703 fd = url_get_file_handle(rtsp_st->rtp_handle);
1673 if (FD_ISSET(fd, &rfds)) { 1704 fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
1705 if (FD_ISSET(fd_rtcp, &rfds) || FD_ISSET(fd, &rfds)) {
1674 ret = url_read(rtsp_st->rtp_handle, buf, buf_size); 1706 ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
1675 if (ret > 0) { 1707 if (ret > 0) {
1676 *prtsp_st = rtsp_st; 1708 *prtsp_st = rtsp_st;
1677 return ret; 1709 return ret;
1678 } 1710 }
1679 } 1711 }
1680 } 1712 }
1681 } 1713 }
1682 #if CONFIG_RTSP_DEMUXER 1714 #if CONFIG_RTSP_DEMUXER
1683 if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) { 1715 if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) {
(...skipping 22 matching lines...) Expand all
1706 RTSPStream *rtsp_st; 1738 RTSPStream *rtsp_st;
1707 1739
1708 #ifdef DEBUG_RTP_TCP 1740 #ifdef DEBUG_RTP_TCP
1709 dprintf(s, "tcp_read_packet:\n"); 1741 dprintf(s, "tcp_read_packet:\n");
1710 #endif 1742 #endif
1711 redo: 1743 redo:
1712 for (;;) { 1744 for (;;) {
1713 RTSPMessageHeader reply; 1745 RTSPMessageHeader reply;
1714 1746
1715 ret = ff_rtsp_read_reply(s, &reply, NULL, 1); 1747 ret = ff_rtsp_read_reply(s, &reply, NULL, 1);
1716 if (ret == -1) 1748 if (ret < 0)
1717 return -1; 1749 return ret;
1718 if (ret == 1) /* received '$' */ 1750 if (ret == 1) /* received '$' */
1719 break; 1751 break;
1720 /* XXX: parse message */ 1752 /* XXX: parse message */
1721 if (rt->state != RTSP_STATE_STREAMING) 1753 if (rt->state != RTSP_STATE_STREAMING)
1722 return 0; 1754 return 0;
1723 } 1755 }
1724 ret = url_read_complete(rt->rtsp_hd, buf, 3); 1756 ret = url_read_complete(rt->rtsp_hd, buf, 3);
1725 if (ret != 3) 1757 if (ret != 3)
1726 return -1; 1758 return -1;
1727 id = buf[0]; 1759 id = buf[0];
(...skipping 24 matching lines...) Expand all
1752 return len; 1784 return len;
1753 } 1785 }
1754 1786
1755 static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) 1787 static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
1756 { 1788 {
1757 RTSPState *rt = s->priv_data; 1789 RTSPState *rt = s->priv_data;
1758 int ret, len; 1790 int ret, len;
1759 uint8_t buf[10 * RTP_MAX_PACKET_LENGTH]; 1791 uint8_t buf[10 * RTP_MAX_PACKET_LENGTH];
1760 RTSPStream *rtsp_st; 1792 RTSPStream *rtsp_st;
1761 1793
1794 if (rt->nb_byes == rt->nb_rtsp_streams)
1795 return AVERROR_EOF;
1796
1762 /* get next frames from the same RTP packet */ 1797 /* get next frames from the same RTP packet */
1763 if (rt->cur_transport_priv) { 1798 if (rt->cur_transport_priv) {
1764 if (rt->transport == RTSP_TRANSPORT_RDT) { 1799 if (rt->transport == RTSP_TRANSPORT_RDT) {
1765 ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); 1800 ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1766 } else 1801 } else
1767 ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); 1802 ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1768 if (ret == 0) { 1803 if (ret == 0) {
1769 rt->cur_transport_priv = NULL; 1804 rt->cur_transport_priv = NULL;
1770 return 0; 1805 return 0;
1771 } else if (ret == 1) { 1806 } else if (ret == 1) {
(...skipping 30 matching lines...) Expand all
1802 /* Either bad packet, or a RTCP packet. Check if the 1837 /* Either bad packet, or a RTCP packet. Check if the
1803 * first_rtcp_ntp_time field was initialized. */ 1838 * first_rtcp_ntp_time field was initialized. */
1804 RTPDemuxContext *rtpctx = rtsp_st->transport_priv; 1839 RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
1805 if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) { 1840 if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) {
1806 /* first_rtcp_ntp_time has been initialized for this stream, 1841 /* first_rtcp_ntp_time has been initialized for this stream,
1807 * copy the same value to all other uninitialized streams, 1842 * copy the same value to all other uninitialized streams,
1808 * in order to map their timestamp origin to the same ntp time 1843 * in order to map their timestamp origin to the same ntp time
1809 * as this one. */ 1844 * as this one. */
1810 int i; 1845 int i;
1811 for (i = 0; i < rt->nb_rtsp_streams; i++) { 1846 for (i = 0; i < rt->nb_rtsp_streams; i++) {
1812 RTPDemuxContext *rtpctx2 = rtsp_st->transport_priv; 1847 RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_pr iv;
1813 if (rtpctx2 && 1848 if (rtpctx2 &&
1814 rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) 1849 rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE)
1815 rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_ti me; 1850 rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_ti me;
1816 } 1851 }
1817 } 1852 }
1853 if (ret == -RTCP_BYE) {
1854 rt->nb_byes++;
1855
1856 av_log(s, AV_LOG_DEBUG, "Received BYE for stream %d (%d/%d)\n",
1857 rtsp_st->stream_index, rt->nb_byes, rt->nb_rtsp_streams);
1858
1859 if (rt->nb_byes == rt->nb_rtsp_streams)
1860 return AVERROR_EOF;
1861 }
1818 } 1862 }
1819 } 1863 }
1820 if (ret < 0) 1864 if (ret < 0)
1821 goto redo; 1865 goto redo;
1822 if (ret == 1) 1866 if (ret == 1)
1823 /* more packets may follow, so we save the RTP context */ 1867 /* more packets may follow, so we save the RTP context */
1824 rt->cur_transport_priv = rtsp_st->transport_priv; 1868 rt->cur_transport_priv = rtsp_st->transport_priv;
1825 1869
1826 return ret; 1870 return ret;
1827 } 1871 }
1828 1872
1829 static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) 1873 static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
1830 { 1874 {
1831 RTSPState *rt = s->priv_data; 1875 RTSPState *rt = s->priv_data;
1832 int ret; 1876 int ret;
1833 RTSPMessageHeader reply1, *reply = &reply1; 1877 RTSPMessageHeader reply1, *reply = &reply1;
1834 char cmd[1024]; 1878 char cmd[1024];
1835 1879
1836 if (rt->server_type == RTSP_SERVER_REAL) { 1880 if (rt->server_type == RTSP_SERVER_REAL) {
1837 int i; 1881 int i;
1838 enum AVDiscard cache[MAX_STREAMS];
1839 1882
1840 for (i = 0; i < s->nb_streams; i++) 1883 for (i = 0; i < s->nb_streams; i++)
1841 cache[i] = s->streams[i]->discard; 1884 rt->real_setup[i] = s->streams[i]->discard;
1842 1885
1843 if (!rt->need_subscription) { 1886 if (!rt->need_subscription) {
1844 if (memcmp (cache, rt->real_setup_cache, 1887 if (memcmp (rt->real_setup, rt->real_setup_cache,
1845 sizeof(enum AVDiscard) * s->nb_streams)) { 1888 sizeof(enum AVDiscard) * s->nb_streams)) {
1846 snprintf(cmd, sizeof(cmd), 1889 snprintf(cmd, sizeof(cmd),
1847 "Unsubscribe: %s\r\n", 1890 "Unsubscribe: %s\r\n",
1848 rt->last_subscription); 1891 rt->last_subscription);
1849 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri, 1892 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
1850 cmd, reply, NULL); 1893 cmd, reply, NULL);
1851 if (reply->status_code != RTSP_STATUS_OK) 1894 if (reply->status_code != RTSP_STATUS_OK)
1852 return AVERROR_INVALIDDATA; 1895 return AVERROR_INVALIDDATA;
1853 rt->need_subscription = 1; 1896 rt->need_subscription = 1;
1854 } 1897 }
1855 } 1898 }
1856 1899
1857 if (rt->need_subscription) { 1900 if (rt->need_subscription) {
1858 int r, rule_nr, first = 1; 1901 int r, rule_nr, first = 1;
1859 1902
1860 memcpy(rt->real_setup_cache, cache, 1903 memcpy(rt->real_setup_cache, rt->real_setup,
1861 sizeof(enum AVDiscard) * s->nb_streams); 1904 sizeof(enum AVDiscard) * s->nb_streams);
1862 rt->last_subscription[0] = 0; 1905 rt->last_subscription[0] = 0;
1863 1906
1864 snprintf(cmd, sizeof(cmd), 1907 snprintf(cmd, sizeof(cmd),
1865 "Subscribe: "); 1908 "Subscribe: ");
1866 for (i = 0; i < rt->nb_rtsp_streams; i++) { 1909 for (i = 0; i < rt->nb_rtsp_streams; i++) {
1867 rule_nr = 0; 1910 rule_nr = 0;
1868 for (r = 0; r < s->nb_streams; r++) { 1911 for (r = 0; r < s->nb_streams; r++) {
1869 if (s->streams[r]->priv_data == rt->rtsp_streams[i]) { 1912 if (s->streams[r]->priv_data == rt->rtsp_streams[i]) {
1870 if (s->streams[r]->discard != AVDISCARD_ALL) { 1913 if (s->streams[r]->discard != AVDISCARD_ALL) {
(...skipping 19 matching lines...) Expand all
1890 if (rt->state == RTSP_STATE_STREAMING) 1933 if (rt->state == RTSP_STATE_STREAMING)
1891 rtsp_read_play (s); 1934 rtsp_read_play (s);
1892 } 1935 }
1893 } 1936 }
1894 1937
1895 ret = rtsp_fetch_packet(s, pkt); 1938 ret = rtsp_fetch_packet(s, pkt);
1896 if (ret < 0) 1939 if (ret < 0)
1897 return ret; 1940 return ret;
1898 1941
1899 /* send dummy request to keep TCP connection alive */ 1942 /* send dummy request to keep TCP connection alive */
1900 if ((rt->server_type == RTSP_SERVER_WMS || 1943 if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
1901 rt->server_type == RTSP_SERVER_REAL) &&
1902 (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
1903 if (rt->server_type == RTSP_SERVER_WMS) { 1944 if (rt->server_type == RTSP_SERVER_WMS) {
1904 ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL); 1945 ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
1905 } else { 1946 } else {
1906 ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL); 1947 ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);
1907 } 1948 }
1908 } 1949 }
1909 1950
1910 return 0; 1951 return 0;
1911 } 1952 }
1912 1953
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1962 /* NOTE: it is valid to flush the buffer here */ 2003 /* NOTE: it is valid to flush the buffer here */
1963 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { 2004 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1964 url_fclose(&rt->rtsp_gb); 2005 url_fclose(&rt->rtsp_gb);
1965 } 2006 }
1966 #endif 2007 #endif
1967 ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); 2008 ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
1968 2009
1969 ff_rtsp_close_streams(s); 2010 ff_rtsp_close_streams(s);
1970 ff_rtsp_close_connections(s); 2011 ff_rtsp_close_connections(s);
1971 ff_network_close(); 2012 ff_network_close();
2013 rt->real_setup = NULL;
2014 av_freep(&rt->real_setup_cache);
1972 return 0; 2015 return 0;
1973 } 2016 }
1974 2017
1975 AVInputFormat rtsp_demuxer = { 2018 AVInputFormat rtsp_demuxer = {
1976 "rtsp", 2019 "rtsp",
1977 NULL_IF_CONFIG_SMALL("RTSP input format"), 2020 NULL_IF_CONFIG_SMALL("RTSP input format"),
1978 sizeof(RTSPState), 2021 sizeof(RTSPState),
1979 rtsp_probe, 2022 rtsp_probe,
1980 rtsp_read_header, 2023 rtsp_read_header,
1981 rtsp_read_packet, 2024 rtsp_read_packet,
1982 rtsp_read_close, 2025 rtsp_read_close,
1983 rtsp_read_seek, 2026 rtsp_read_seek,
1984 .flags = AVFMT_NOFILE, 2027 .flags = AVFMT_NOFILE,
1985 .read_play = rtsp_read_play, 2028 .read_play = rtsp_read_play,
1986 .read_pause = rtsp_read_pause, 2029 .read_pause = rtsp_read_pause,
1987 }; 2030 };
1988 #endif 2031 #endif
1989 2032
1990 static int sdp_probe(AVProbeData *p1) 2033 static int sdp_probe(AVProbeData *p1)
1991 { 2034 {
1992 const char *p = p1->buf, *p_end = p1->buf + p1->buf_size; 2035 const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
1993 2036
1994 /* we look for a line beginning "c=IN IP4" */ 2037 /* we look for a line beginning "c=IN IP" */
1995 while (p < p_end && *p != '\0') { 2038 while (p < p_end && *p != '\0') {
1996 if (p + sizeof("c=IN IP4") - 1 < p_end && 2039 if (p + sizeof("c=IN IP") - 1 < p_end &&
1997 av_strstart(p, "c=IN IP4", NULL)) 2040 av_strstart(p, "c=IN IP", NULL))
1998 return AVPROBE_SCORE_MAX / 2; 2041 return AVPROBE_SCORE_MAX / 2;
1999 2042
2000 while (p < p_end - 1 && *p != '\n') p++; 2043 while (p < p_end - 1 && *p != '\n') p++;
2001 if (++p >= p_end) 2044 if (++p >= p_end)
2002 break; 2045 break;
2003 if (*p == '\r') 2046 if (*p == '\r')
2004 p++; 2047 p++;
2005 } 2048 }
2006 return 0; 2049 return 0;
2007 } 2050 }
(...skipping 17 matching lines...) Expand all
2025 av_free(content); 2068 av_free(content);
2026 return AVERROR_INVALIDDATA; 2069 return AVERROR_INVALIDDATA;
2027 } 2070 }
2028 content[size] ='\0'; 2071 content[size] ='\0';
2029 2072
2030 sdp_parse(s, content); 2073 sdp_parse(s, content);
2031 av_free(content); 2074 av_free(content);
2032 2075
2033 /* open each RTP stream */ 2076 /* open each RTP stream */
2034 for (i = 0; i < rt->nb_rtsp_streams; i++) { 2077 for (i = 0; i < rt->nb_rtsp_streams; i++) {
2078 char namebuf[50];
2035 rtsp_st = rt->rtsp_streams[i]; 2079 rtsp_st = rt->rtsp_streams[i];
2036 2080
2081 getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip, sizeof(rtsp_st->sdp_ip) ,
2082 namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
2037 ff_url_join(url, sizeof(url), "rtp", NULL, 2083 ff_url_join(url, sizeof(url), "rtp", NULL,
2038 inet_ntoa(rtsp_st->sdp_ip), rtsp_st->sdp_port, 2084 namebuf, rtsp_st->sdp_port,
2039 "?localport=%d&ttl=%d", rtsp_st->sdp_port, 2085 "?localport=%d&ttl=%d", rtsp_st->sdp_port,
2040 rtsp_st->sdp_ttl); 2086 rtsp_st->sdp_ttl);
2041 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { 2087 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
2042 err = AVERROR_INVALIDDATA; 2088 err = AVERROR_INVALIDDATA;
2043 goto fail; 2089 goto fail;
2044 } 2090 }
2045 if ((err = rtsp_open_transport_ctx(s, rtsp_st))) 2091 if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
2046 goto fail; 2092 goto fail;
2047 } 2093 }
2048 return 0; 2094 return 0;
(...skipping 12 matching lines...) Expand all
2061 2107
2062 AVInputFormat sdp_demuxer = { 2108 AVInputFormat sdp_demuxer = {
2063 "sdp", 2109 "sdp",
2064 NULL_IF_CONFIG_SMALL("SDP"), 2110 NULL_IF_CONFIG_SMALL("SDP"),
2065 sizeof(RTSPState), 2111 sizeof(RTSPState),
2066 sdp_probe, 2112 sdp_probe,
2067 sdp_read_header, 2113 sdp_read_header,
2068 rtsp_fetch_packet, 2114 rtsp_fetch_packet,
2069 sdp_read_close, 2115 sdp_read_close,
2070 }; 2116 };
OLDNEW
« no previous file with comments | « source/patched-ffmpeg-mt/libavformat/rtsp.h ('k') | source/patched-ffmpeg-mt/libavformat/rtspenc.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698