1 /*
2 * Session Announcement Protocol (RFC 2974) demuxer
3 * Copyright (c) 2010 Martin Storsjo
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
32 #if HAVE_POLL_H
33 #include <poll.h>
34 #endif
35
43 };
44
46 {
49 return 0;
50 }
51
53 {
61 return 0;
62 }
63
65 {
67 char host[1024], path[1024], url[1024];
69 int port;
72
75
78 if (port < 0)
79 port = 9875;
80
81 if (!host[0]) {
82 /* Listen for announcements on sap.mcast.net if no host was specified */
83 av_strlcpy(host,
"224.2.127.254",
sizeof(host));
84 }
85
87 port);
90 if (ret)
91 goto fail;
92
93 while (1) {
94 int addr_type, auth_len;
95 int pos;
96
99 continue;
100 if (ret < 0)
101 goto fail;
102 recvbuf[
ret] =
'0円';
/* Null terminate for easier parsing */
103 if (ret < 8) {
105 continue;
106 }
107
108 if ((recvbuf[0] & 0xe0) != 0x20) {
110 "received\n");
111 continue;
112 }
113
114 if (recvbuf[0] & 0x04) {
116 "announcement\n");
117 continue;
118 }
119 addr_type = recvbuf[0] & 0x10;
120 auth_len = recvbuf[1];
122 pos = 4;
123 if (addr_type)
124 pos += 16; /* IPv6 */
125 else
126 pos += 4; /* IPv4 */
127 pos += auth_len * 4;
128 if (pos + 4 >= ret) {
130 continue;
131 }
132 #define MIME "application/sdp"
133 if (strcmp(&recvbuf[pos],
MIME) == 0) {
134 pos += strlen(
MIME) + 1;
135 } else if (strncmp(&recvbuf[pos], "v=0\r\n", 5) == 0) {
136 // Direct SDP without a mime type
137 } else {
139 &recvbuf[pos]);
140 continue;
141 }
142
144 break;
145 }
146
150
152 if (!infmt)
153 goto fail;
157 goto fail;
158 }
162
164 goto fail;
165
167 if (ret < 0)
168 goto fail;
173 if (!st) {
175 goto fail;
176 }
180 }
181
182 return 0;
183
184 fail:
187 }
188
190 {
194 struct pollfd p = {fd, POLLIN, 0};
196
199
200 while (1) {
201 n = poll(&p, 1, 0);
202 if (n <= 0 || !(p.revents & POLLIN))
203 break;
205 if (ret >= 8) {
207 /* Should ideally check the source IP address, too */
208 if (recvbuf[0] & 0x04 && hash == sap->
hash) {
209 /* Stream deletion */
212 }
213 }
214 }
216 if (ret < 0)
222 if (!st) {
225 }
229 }
230 }
232 }
233
237 .priv_data_size =
sizeof(
struct SAPState),
243 };