Mercurial > libavformat.hg
comparison rtsp.c @ 6411:f0669792a6bd libavformat
Handle IPv6 in the SDP demuxer
author | mstorsjo |
---|---|
date | Wed, 25 Aug 2010 15:32:00 +0000 |
parents | 31aef55204bd |
children | 6d6b63b7e5e3 |
comparison
equal
deleted
inserted
replaced
6410:31aef55204bd | 6411:f0669792a6bd |
---|---|
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, |
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; |
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); |
1169 if (reply->transports[0].destination) { | 1181 if (reply->transports[0].destination) { |
1170 in.s_addr = htonl(reply->transports[0].destination); | 1182 in.s_addr = htonl(reply->transports[0].destination); |
1171 port = reply->transports[0].port_min; | 1183 port = reply->transports[0].port_min; |
1172 ttl = reply->transports[0].ttl; | 1184 ttl = reply->transports[0].ttl; |
1173 } else { | 1185 } else { |
1174 in = rtsp_st->sdp_ip; | 1186 in = ((struct sockaddr_in*)&rtsp_st->sdp_ip)->sin_addr; |
1175 port = rtsp_st->sdp_port; | 1187 port = rtsp_st->sdp_port; |
1176 ttl = rtsp_st->sdp_ttl; | 1188 ttl = rtsp_st->sdp_ttl; |
1177 } | 1189 } |
1178 ff_url_join(url, sizeof(url), "rtp", NULL, inet_ntoa(in), | 1190 ff_url_join(url, sizeof(url), "rtp", NULL, inet_ntoa(in), |
1179 port, "?ttl=%d", ttl); | 1191 port, "?ttl=%d", ttl); |
1994 | 2006 |
1995 static int sdp_probe(AVProbeData *p1) | 2007 static int sdp_probe(AVProbeData *p1) |
1996 { | 2008 { |
1997 const char *p = p1->buf, *p_end = p1->buf + p1->buf_size; | 2009 const char *p = p1->buf, *p_end = p1->buf + p1->buf_size; |
1998 | 2010 |
1999 /* we look for a line beginning "c=IN IP4" */ | 2011 /* we look for a line beginning "c=IN IP" */ |
2000 while (p < p_end && *p != '\0') { | 2012 while (p < p_end && *p != '\0') { |
2001 if (p + sizeof("c=IN IP4") - 1 < p_end && | 2013 if (p + sizeof("c=IN IP") - 1 < p_end && |
2002 av_strstart(p, "c=IN IP4", NULL)) | 2014 av_strstart(p, "c=IN IP", NULL)) |
2003 return AVPROBE_SCORE_MAX / 2; | 2015 return AVPROBE_SCORE_MAX / 2; |
2004 | 2016 |
2005 while (p < p_end - 1 && *p != '\n') p++; | 2017 while (p < p_end - 1 && *p != '\n') p++; |
2006 if (++p >= p_end) | 2018 if (++p >= p_end) |
2007 break; | 2019 break; |
2035 sdp_parse(s, content); | 2047 sdp_parse(s, content); |
2036 av_free(content); | 2048 av_free(content); |
2037 | 2049 |
2038 /* open each RTP stream */ | 2050 /* open each RTP stream */ |
2039 for (i = 0; i < rt->nb_rtsp_streams; i++) { | 2051 for (i = 0; i < rt->nb_rtsp_streams; i++) { |
2052 char namebuf[50]; | |
2040 rtsp_st = rt->rtsp_streams[i]; | 2053 rtsp_st = rt->rtsp_streams[i]; |
2041 | 2054 |
2055 getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip, sizeof(rtsp_st->sdp_ip), | |
2056 namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST); | |
2042 ff_url_join(url, sizeof(url), "rtp", NULL, | 2057 ff_url_join(url, sizeof(url), "rtp", NULL, |
2043 inet_ntoa(rtsp_st->sdp_ip), rtsp_st->sdp_port, | 2058 namebuf, rtsp_st->sdp_port, |
2044 "?localport=%d&ttl=%d", rtsp_st->sdp_port, | 2059 "?localport=%d&ttl=%d", rtsp_st->sdp_port, |
2045 rtsp_st->sdp_ttl); | 2060 rtsp_st->sdp_ttl); |
2046 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { | 2061 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { |
2047 err = AVERROR_INVALIDDATA; | 2062 err = AVERROR_INVALIDDATA; |
2048 goto fail; | 2063 goto fail; |