2
2
* UDP prototype streaming system
3
3
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
5
* This file is part of FFmpeg.
5
* This file is part of Libav.
7
* FFmpeg is free software; you can redistribute it and/or
7
* Libav is free software; you can redistribute it and/or
8
8
* modify it under the terms of the GNU Lesser General Public
9
9
* License as published by the Free Software Foundation; either
10
10
* version 2.1 of the License, or (at your option) any later version.
12
* FFmpeg is distributed in the hope that it will be useful,
12
* Libav is distributed in the hope that it will be useful,
13
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
15
* Lesser General Public License for more details.
17
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
18
* License along with Libav; if not, write to the Free Software
19
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
256
238
* 'pkt_size=n' : set max packet size
257
239
* 'reuse=1' : enable reusing the socket
259
* @param s1 media file context
241
* @param h media file context
260
242
* @param uri of the remote server
261
243
* @return zero if no error.
263
int udp_set_remote_url(URLContext *h, const char *uri)
245
int ff_udp_set_remote_url(URLContext *h, const char *uri)
265
247
UDPContext *s = h->priv_data;
248
char hostname[256], buf[10];
269
ff_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
252
av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
271
254
/* set the destination address */
272
255
s->dest_addr_len = udp_set_url(&s->dest_addr, hostname, port);
273
256
if (s->dest_addr_len < 0) {
274
257
return AVERROR(EIO);
276
s->is_multicast = is_multicast_address(&s->dest_addr);
259
s->is_multicast = ff_is_multicast_address((struct sockaddr*) &s->dest_addr);
260
p = strchr(uri, '?');
262
if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
263
int was_connected = s->is_connected;
264
s->is_connected = strtol(buf, NULL, 10);
265
if (s->is_connected && !was_connected) {
266
if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr,
269
av_log(NULL, AV_LOG_ERROR, "connect: %s\n", strerror(errno));
282
* Return the local port used by the UDP connexion
283
* @param s1 media file context
280
* Return the local port used by the UDP connection
281
* @param h media file context
284
282
* @return the local port number
286
int udp_get_local_port(URLContext *h)
284
int ff_udp_get_local_port(URLContext *h)
288
286
UDPContext *s = h->priv_data;
289
287
return s->local_port;
332
331
p = strchr(uri, '?');
334
s->reuse_socket = find_info_tag(buf, sizeof(buf), "reuse", p);
335
if (find_info_tag(buf, sizeof(buf), "ttl", p)) {
333
if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) {
334
const char *endptr=NULL;
335
s->reuse_socket = strtol(buf, &endptr, 10);
336
/* assume if no digits were found it is a request to enable it */
341
if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
336
342
s->ttl = strtol(buf, NULL, 10);
338
if (find_info_tag(buf, sizeof(buf), "localport", p)) {
344
if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
339
345
s->local_port = strtol(buf, NULL, 10);
341
if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
347
if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
342
348
h->max_packet_size = strtol(buf, NULL, 10);
344
if (find_info_tag(buf, sizeof(buf), "buffer_size", p)) {
350
if (av_find_info_tag(buf, sizeof(buf), "buffer_size", p)) {
345
351
s->buffer_size = strtol(buf, NULL, 10);
353
if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
354
s->is_connected = strtol(buf, NULL, 10);
349
358
/* fill the dest addr */
350
ff_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
359
av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
352
/* XXX: fix ff_url_split */
361
/* XXX: fix av_url_split */
353
362
if (hostname[0] == '\0' || hostname[0] == '?') {
354
363
/* only accepts null hostname if input */
355
if (flags & URL_WRONLY)
364
if (flags & AVIO_WRONLY)
358
udp_set_remote_url(h, uri);
367
if (ff_udp_set_remote_url(h, uri) < 0)
361
if (s->is_multicast && !(h->flags & URL_WRONLY))
371
if (s->is_multicast && !(h->flags & AVIO_WRONLY))
362
372
s->local_port = port;
363
373
udp_fd = udp_socket_create(s, &my_addr, &len);
377
/* Follow the requested reuse option, unless it's multicast in which
378
* case enable reuse unless explicitely disabled.
380
if (s->reuse_socket || (s->is_multicast && !reuse_specified)) {
368
382
if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
371
386
/* the bind is needed to give a port to the socket now */
372
387
/* if multicast, try the multicast address bind first */
373
if (s->is_multicast && !(h->flags & URL_WRONLY)) {
388
if (s->is_multicast && !(h->flags & AVIO_WRONLY)) {
374
389
bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len);
376
391
/* bind to the local address if not multicast or if the multicast
424
445
static int udp_read(URLContext *h, uint8_t *buf, int size)
426
447
UDPContext *s = h->priv_data;
433
if (url_interrupt_cb())
434
return AVERROR(EINTR);
436
FD_SET(s->udp_fd, &rfds);
438
tv.tv_usec = 100 * 1000;
439
ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv);
441
if (ff_neterrno() == FF_NETERROR(EINTR))
445
if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds)))
447
len = recv(s->udp_fd, buf, size, 0);
449
if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
450
ff_neterrno() != FF_NETERROR(EINTR))
450
if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
451
ret = ff_network_wait_fd(s->udp_fd, 0);
455
ret = recv(s->udp_fd, buf, size, 0);
456
return ret < 0 ? ff_neterrno() : ret;
459
static int udp_write(URLContext *h, uint8_t *buf, int size)
459
static int udp_write(URLContext *h, const uint8_t *buf, int size)
461
461
UDPContext *s = h->priv_data;
464
if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
465
ret = ff_network_wait_fd(s->udp_fd, 1);
470
if (!s->is_connected) {
465
471
ret = sendto (s->udp_fd, buf, size, 0,
466
472
(struct sockaddr *) &s->dest_addr,
467
473
s->dest_addr_len);
469
if (ff_neterrno() != FF_NETERROR(EINTR) &&
470
ff_neterrno() != FF_NETERROR(EAGAIN))
475
ret = send(s->udp_fd, buf, size, 0);
477
return ret < 0 ? ff_neterrno() : ret;
479
480
static int udp_close(URLContext *h)
481
482
UDPContext *s = h->priv_data;
483
if (s->is_multicast && !(h->flags & URL_WRONLY))
484
if (s->is_multicast && !(h->flags & AVIO_WRONLY))
484
485
udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
485
486
closesocket(s->udp_fd);
490
URLProtocol udp_protocol = {
491
URLProtocol ff_udp_protocol = {
493
.url_open = udp_open,
494
.url_read = udp_read,
495
.url_write = udp_write,
496
.url_close = udp_close,
497
497
.url_get_file_handle = udp_get_file_handle,