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;