ffserver.c 147 KB
Newer Older
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
1 2
/*
 * Multiple format streaming server
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
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
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
20
 */
21

22
#include "config.h"
23
#ifndef HAVE_CLOSESOCKET
24 25 26 27
#define closesocket close
#endif
#include <string.h>
#include <stdlib.h>
28
#include "avformat.h"
29 30
#include "rtsp.h"
#include "rtp.h"
31
#include "os_support.h"
32

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
33 34 35 36
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
37
#ifdef HAVE_SYS_POLL_H
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
38
#include <sys/poll.h>
39
#endif
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
40 41
#include <errno.h>
#include <sys/time.h>
42
#undef time //needed because HAVE_AV_CONFIG_H is defined on top
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
43
#include <time.h>
44
#include <sys/wait.h>
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
45
#include <signal.h>
46
#ifdef HAVE_DLFCN_H
47
#include <dlfcn.h>
48
#endif
49

50
#include "network.h"
51
#include "version.h"
52
#include "ffserver.h"
53
#include "random.h"
54
#include "avstring.h"
55
#include "cmdutils.h"
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
56

Michael Niedermayer's avatar
Michael Niedermayer committed
57 58
#undef exit

59 60 61
static const char program_name[] = "FFserver";
static const int program_birth_year = 2000;

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
62 63 64 65 66 67 68
/* maximum number of simultaneous HTTP connections */
#define HTTP_MAX_CONNECTIONS 2000

enum HTTPState {
    HTTPSTATE_WAIT_REQUEST,
    HTTPSTATE_SEND_HEADER,
    HTTPSTATE_SEND_DATA_HEADER,
69
    HTTPSTATE_SEND_DATA,          /* sending TCP or UDP data */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
70
    HTTPSTATE_SEND_DATA_TRAILER,
71
    HTTPSTATE_RECEIVE_DATA,
72 73 74 75 76
    HTTPSTATE_WAIT_FEED,          /* wait for data from the feed */
    HTTPSTATE_READY,

    RTSPSTATE_WAIT_REQUEST,
    RTSPSTATE_SEND_REPLY,
77
    RTSPSTATE_SEND_PACKET,
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
78 79 80
};

const char *http_state[] = {
81 82 83
    "HTTP_WAIT_REQUEST",
    "HTTP_SEND_HEADER",

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
84 85 86 87 88
    "SEND_DATA_HEADER",
    "SEND_DATA",
    "SEND_DATA_TRAILER",
    "RECEIVE_DATA",
    "WAIT_FEED",
89 90 91 92
    "READY",

    "RTSP_WAIT_REQUEST",
    "RTSP_SEND_REPLY",
93
    "RTSP_SEND_PACKET",
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
94 95
};

Philip Gladstone's avatar
Philip Gladstone committed
96
#define IOBUFFER_INIT_SIZE 8192
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
97 98

/* timeouts are in ms */
99 100 101
#define HTTP_REQUEST_TIMEOUT (15 * 1000)
#define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000)

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
102 103
#define SYNC_TIMEOUT (10 * 1000)

104
typedef struct {
105
    int64_t count1, count2;
106
    int64_t time1, time2;
107 108
} DataRateData;

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
109 110 111 112 113 114
/* context associated with one connection */
typedef struct HTTPContext {
    enum HTTPState state;
    int fd; /* socket file descriptor */
    struct sockaddr_in from_addr; /* origin */
    struct pollfd *poll_entry; /* used when polling */
115
    int64_t timeout;
116
    uint8_t *buffer_ptr, *buffer_end;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
117
    int http_error;
118
    int post;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
119
    struct HTTPContext *next;
120
    int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
121
    int64_t data_count;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
122 123 124 125
    /* feed input */
    int feed_fd;
    /* input format handling */
    AVFormatContext *fmt_in;
126
    int64_t start_time;            /* In milliseconds - this wraps fairly often */
127
    int64_t first_pts;            /* initial pts value */
128 129 130 131 132 133 134
    int64_t cur_pts;             /* current pts value from the stream in us */
    int64_t cur_frame_duration;  /* duration of the current frame in us */
    int cur_frame_bytes;       /* output frame size, needed to compute
                                  the time at which we send each
                                  packet */
    int pts_stream_index;        /* stream we choose as clock reference */
    int64_t cur_clock;           /* current clock reference value in us */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
135 136
    /* output format handling */
    struct FFStream *stream;
Philip Gladstone's avatar
Philip Gladstone committed
137 138 139 140
    /* -1 is invalid stream */
    int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
    int switch_feed_streams[MAX_STREAMS]; /* index of streams in the feed */
    int switch_pending;
141
    AVFormatContext fmt_ctx; /* instance of FFStream for one user */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
142
    int last_packet_sent; /* true if last data packet was sent */
143
    int suppress_log;
144
    DataRateData datarate;
145
    int wmp_client_id;
146 147 148
    char protocol[16];
    char method[16];
    char url[128];
Philip Gladstone's avatar
Philip Gladstone committed
149
    int buffer_size;
150
    uint8_t *buffer;
151 152
    int is_packetized; /* if true, the stream is packetized */
    int packet_stream_index; /* current stream for output in state machine */
153

154
    /* RTSP state specific */
155
    uint8_t *pb_buffer; /* XXX: use that in all the code */
156 157
    ByteIOContext *pb;
    int seq; /* RTSP sequence number */
158

159 160 161 162
    /* RTP state specific */
    enum RTSPProtocol rtp_protocol;
    char session_id[32]; /* session id */
    AVFormatContext *rtp_ctx[MAX_STREAMS];
163

164 165 166 167 168 169
    /* RTP/UDP specific */
    URLContext *rtp_handles[MAX_STREAMS];

    /* RTP/TCP specific */
    struct HTTPContext *rtsp_c;
    uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
170 171
} HTTPContext;

172 173
static AVFrame dummy_frame;

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
174 175 176 177
/* each generated stream is described here */
enum StreamType {
    STREAM_TYPE_LIVE,
    STREAM_TYPE_STATUS,
Philip Gladstone's avatar
Philip Gladstone committed
178
    STREAM_TYPE_REDIRECT,
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
179 180
};

181 182 183 184 185 186 187 188
enum IPAddressAction {
    IP_ALLOW = 1,
    IP_DENY,
};

typedef struct IPAddressACL {
    struct IPAddressACL *next;
    enum IPAddressAction action;
189
    /* These are in host order */
190 191 192 193
    struct in_addr first;
    struct in_addr last;
} IPAddressACL;

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
194 195 196 197
/* description of each stream of the ffserver.conf file */
typedef struct FFStream {
    enum StreamType stream_type;
    char filename[1024];     /* stream filename */
198 199
    struct FFStream *feed;   /* feed we are using (can be null if
                                coming from file) */
200 201
    AVFormatParameters *ap_in; /* input parameters */
    AVInputFormat *ifmt;       /* if non NULL, force input format */
202
    AVOutputFormat *fmt;
203
    IPAddressACL *acl;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
204
    int nb_streams;
205
    int prebuffer;      /* Number of millseconds early to start */
206
    int64_t max_time;      /* Number of milliseconds to run */
207
    int send_on_key;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
208 209 210 211
    AVStream *streams[MAX_STREAMS];
    int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
    char feed_filename[1024]; /* file name of the feed storage, or
                                 input file name for a stream */
212 213 214 215
    char author[512];
    char title[512];
    char copyright[512];
    char comment[512];
Philip Gladstone's avatar
Philip Gladstone committed
216
    pid_t pid;  /* Of ffmpeg process */
217
    time_t pid_start;  /* Of ffmpeg process */
Philip Gladstone's avatar
Philip Gladstone committed
218
    char **child_argv;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
219
    struct FFStream *next;
220
    int bandwidth; /* bandwidth, in kbits/s */
221 222
    /* RTSP options */
    char *rtsp_option;
223 224 225 226
    /* multicast specific */
    int is_multicast;
    struct in_addr multicast_ip;
    int multicast_port; /* first port used for multicast */
227 228
    int multicast_ttl;
    int loop; /* if true, send the stream in loops (only meaningful if file) */
229

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
230
    /* feed specific */
231
    int feed_opened;     /* true if someone is writing to the feed */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
232
    int is_feed;         /* true if it is a feed */
233
    int readonly;        /* True if writing is prohibited to the file */
234
    int conns_served;
235
    int64_t bytes_served;
236
    int64_t feed_max_size;      /* maximum storage size, zero means unlimited */
Diego Biurrun's avatar
Diego Biurrun committed
237
    int64_t feed_write_index;   /* current write position in feed (it wraps around) */
238
    int64_t feed_size;          /* current size of feed */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
239 240 241 242 243
    struct FFStream *next_feed;
} FFStream;

typedef struct FeedData {
    long long data_count;
Diego Biurrun's avatar
Diego Biurrun committed
244
    float avg_frame_size;   /* frame size averaged over last frames with exponential mean */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
245 246
} FeedData;

247 248
static struct sockaddr_in my_http_addr;
static struct sockaddr_in my_rtsp_addr;
249

250 251 252 253
static char logfilename[1024];
static HTTPContext *first_http_ctx;
static FFStream *first_feed;   /* contains only feeds */
static FFStream *first_stream; /* contains all streams, including feeds */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
254

255 256 257 258 259
static void new_connection(int server_fd, int is_rtsp);
static void close_connection(HTTPContext *c);

/* HTTP handling */
static int handle_connection(HTTPContext *c);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
260
static int http_parse_request(HTTPContext *c);
261
static int http_send_data(HTTPContext *c);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
262 263 264 265
static void compute_stats(HTTPContext *c);
static int open_input_stream(HTTPContext *c, const char *info);
static int http_start_receive_data(HTTPContext *c);
static int http_receive_data(HTTPContext *c);
266 267 268 269

/* RTSP handling */
static int rtsp_parse_request(HTTPContext *c);
static void rtsp_cmd_describe(HTTPContext *c, const char *url);
270
static void rtsp_cmd_options(HTTPContext *c, const char *url);
271 272 273 274 275
static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPHeader *h);
static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPHeader *h);
static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPHeader *h);
static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPHeader *h);

276
/* SDP handling */
277
static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
278 279
                                   struct in_addr my_ip);

280
/* RTP handling */
281
static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
282 283
                                       FFStream *stream, const char *session_id,
                                       enum RTSPProtocol rtp_protocol);
284
static int rtp_new_av_stream(HTTPContext *c,
285 286
                             int stream_index, struct sockaddr_in *dest_addr,
                             HTTPContext *rtsp_c);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
287

Philip Gladstone's avatar
Philip Gladstone committed
288
static const char *my_program_name;
289
static const char *my_program_dir;
Philip Gladstone's avatar
Philip Gladstone committed
290

291
static int ffserver_debug;
292
static int ffserver_daemon;
293
static int no_launch;
294
static int need_to_start_children;
295

296 297
static int nb_max_connections;
static int nb_connections;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
298

299 300
static int max_bandwidth;
static int current_bandwidth;
301

302
static int64_t cur_time;           // Making this global saves on passing it around everywhere
303

304 305
static AVRandomState random_state;

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
306 307
static FILE *logfile = NULL;

308
static void __attribute__ ((format (printf, 1, 2))) http_log(const char *fmt, ...)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
309 310 311
{
    va_list ap;
    va_start(ap, fmt);
312

313
    if (logfile) {
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
314
        vfprintf(logfile, fmt, ap);
315 316
        fflush(logfile);
    }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
317 318 319
    va_end(ap);
}

320
static char *ctime1(char *buf2)
321 322
{
    time_t ti;
323
    char *p;
324 325 326 327 328 329 330

    ti = time(NULL);
    p = ctime(&ti);
    strcpy(buf2, p);
    p = buf2 + strlen(p) - 1;
    if (*p == '\n')
        *p = '\0';
331 332 333 334 335 336 337
    return buf2;
}

static void log_connection(HTTPContext *c)
{
    char buf2[32];

338
    if (c->suppress_log)
339 340
        return;

341 342 343
    http_log("%s - - [%s] \"%s %s %s\" %d %"PRId64"\n",
             inet_ntoa(c->from_addr.sin_addr),
             ctime1(buf2), c->method, c->url,
344
             c->protocol, (c->http_error ? c->http_error : 200), c->data_count);
Philip Gladstone's avatar
Philip Gladstone committed
345 346
}

347
static void update_datarate(DataRateData *drd, int64_t count)
348 349 350 351
{
    if (!drd->time1 && !drd->count1) {
        drd->time1 = drd->time2 = cur_time;
        drd->count1 = drd->count2 = count;
352
    } else if (cur_time - drd->time2 > 5000) {
Alex Beregszaszi's avatar
Alex Beregszaszi committed
353 354 355 356
        drd->time1 = drd->time2;
        drd->count1 = drd->count2;
        drd->time2 = cur_time;
        drd->count2 = count;
357 358 359 360
    }
}

/* In bytes per second */
361
static int compute_datarate(DataRateData *drd, int64_t count)
362 363 364
{
    if (cur_time == drd->time1)
        return 0;
365

366 367 368
    return ((count - drd->count1) * 1000) / (cur_time - drd->time1);
}

369

Philip Gladstone's avatar
Philip Gladstone committed
370 371
static void start_children(FFStream *feed)
{
372 373 374
    if (no_launch)
        return;

Philip Gladstone's avatar
Philip Gladstone committed
375
    for (; feed; feed = feed->next) {
376 377 378
        if (feed->child_argv && !feed->pid) {
            feed->pid_start = time(0);

Philip Gladstone's avatar
Philip Gladstone committed
379 380 381 382 383 384 385 386 387 388 389 390
            feed->pid = fork();

            if (feed->pid < 0) {
                fprintf(stderr, "Unable to create children\n");
                exit(1);
            }
            if (!feed->pid) {
                /* In child */
                char pathname[1024];
                char *slash;
                int i;

391
                for (i = 3; i < 256; i++)
392
                    close(i);
Philip Gladstone's avatar
Philip Gladstone committed
393

394
                if (!ffserver_debug) {
395 396 397 398 399
                    i = open("/dev/null", O_RDWR);
                    if (i)
                        dup2(i, 0);
                    dup2(i, 1);
                    dup2(i, 2);
400 401
                    if (i)
                        close(i);
402
                }
Philip Gladstone's avatar
Philip Gladstone committed
403

404
                av_strlcpy(pathname, my_program_name, sizeof(pathname));
Philip Gladstone's avatar
Philip Gladstone committed
405 406

                slash = strrchr(pathname, '/');
407
                if (!slash)
Philip Gladstone's avatar
Philip Gladstone committed
408
                    slash = pathname;
409
                else
Philip Gladstone's avatar
Philip Gladstone committed
410 411 412
                    slash++;
                strcpy(slash, "ffmpeg");

413 414 415
                /* This is needed to make relative pathnames work */
                chdir(my_program_dir);

416 417
                signal(SIGPIPE, SIG_DFL);

Philip Gladstone's avatar
Philip Gladstone committed
418 419 420 421 422 423
                execvp(pathname, feed->child_argv);

                _exit(1);
            }
        }
    }
424 425
}

426 427
/* open a listening socket */
static int socket_open_listen(struct sockaddr_in *my_addr)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
428
{
429
    int server_fd, tmp;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
430 431 432 433 434 435

    server_fd = socket(AF_INET,SOCK_STREAM,0);
    if (server_fd < 0) {
        perror ("socket");
        return -1;
    }
436

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
437 438 439
    tmp = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));

440
    if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) {
441 442 443
        char bindmsg[32];
        snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port));
        perror (bindmsg);
444
        closesocket(server_fd);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
445 446
        return -1;
    }
447

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
448 449
    if (listen (server_fd, 5) < 0) {
        perror ("listen");
450
        closesocket(server_fd);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
451 452
        return -1;
    }
453
    ff_socket_nonblock(server_fd, 1);
454 455 456 457

    return server_fd;
}

458 459 460 461 462 463 464 465 466 467 468 469 470
/* start all multicast streams */
static void start_multicast(void)
{
    FFStream *stream;
    char session_id[32];
    HTTPContext *rtp_c;
    struct sockaddr_in dest_addr;
    int default_port, stream_index;

    default_port = 6000;
    for(stream = first_stream; stream != NULL; stream = stream->next) {
        if (stream->is_multicast) {
            /* open the RTP connection */
471 472
            snprintf(session_id, sizeof(session_id), "%08x%08x",
                     av_random(&random_state), av_random(&random_state));
473 474 475 476 477 478 479 480 481 482 483

            /* choose a port if none given */
            if (stream->multicast_port == 0) {
                stream->multicast_port = default_port;
                default_port += 100;
            }

            dest_addr.sin_family = AF_INET;
            dest_addr.sin_addr = stream->multicast_ip;
            dest_addr.sin_port = htons(stream->multicast_port);

484
            rtp_c = rtp_new_connection(&dest_addr, stream, session_id,
485
                                       RTSP_PROTOCOL_RTP_UDP_MULTICAST);
486
            if (!rtp_c)
487
                continue;
488

489
            if (open_input_stream(rtp_c, "") < 0) {
490
                fprintf(stderr, "Could not open input stream for stream '%s'\n",
491 492 493 494 495
                        stream->filename);
                continue;
            }

            /* open each RTP stream */
496
            for(stream_index = 0; stream_index < stream->nb_streams;
497
                stream_index++) {
498
                dest_addr.sin_port = htons(stream->multicast_port +
499
                                           2 * stream_index);
500
                if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) {
501
                    fprintf(stderr, "Could not open output stream '%s/streamid=%d'\n",
502 503
                            stream->filename, stream_index);
                    exit(1);
504 505 506 507 508 509 510 511
                }
            }

            /* change state to send data */
            rtp_c->state = HTTPSTATE_SEND_DATA;
        }
    }
}
512 513 514 515 516 517 518 519 520 521 522

/* main loop of the http server */
static int http_server(void)
{
    int server_fd, ret, rtsp_server_fd, delay, delay1;
    struct pollfd poll_table[HTTP_MAX_CONNECTIONS + 2], *poll_entry;
    HTTPContext *c, *c_next;

    server_fd = socket_open_listen(&my_http_addr);
    if (server_fd < 0)
        return -1;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
523

524 525 526
    rtsp_server_fd = socket_open_listen(&my_rtsp_addr);
    if (rtsp_server_fd < 0)
        return -1;
527

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
528 529
    http_log("ffserver started.\n");

Philip Gladstone's avatar
Philip Gladstone committed
530 531
    start_children(first_feed);

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
532 533
    first_http_ctx = NULL;
    nb_connections = 0;
534 535 536

    start_multicast();

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
537 538 539 540 541 542
    for(;;) {
        poll_entry = poll_table;
        poll_entry->fd = server_fd;
        poll_entry->events = POLLIN;
        poll_entry++;

543 544 545 546
        poll_entry->fd = rtsp_server_fd;
        poll_entry->events = POLLIN;
        poll_entry++;

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
547 548
        /* wait for events on each HTTP handle */
        c = first_http_ctx;
549
        delay = 1000;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
550 551 552 553
        while (c != NULL) {
            int fd;
            fd = c->fd;
            switch(c->state) {
554 555
            case HTTPSTATE_SEND_HEADER:
            case RTSPSTATE_SEND_REPLY:
556
            case RTSPSTATE_SEND_PACKET:
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
557 558
                c->poll_entry = poll_entry;
                poll_entry->fd = fd;
559
                poll_entry->events = POLLOUT;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
560 561 562 563 564
                poll_entry++;
                break;
            case HTTPSTATE_SEND_DATA_HEADER:
            case HTTPSTATE_SEND_DATA:
            case HTTPSTATE_SEND_DATA_TRAILER:
565 566 567 568 569 570 571
                if (!c->is_packetized) {
                    /* for TCP, we output as much as we can (may need to put a limit) */
                    c->poll_entry = poll_entry;
                    poll_entry->fd = fd;
                    poll_entry->events = POLLOUT;
                    poll_entry++;
                } else {
572 573 574 575 576 577
                    /* when ffserver is doing the timing, we work by
                       looking at which packet need to be sent every
                       10 ms */
                    delay1 = 10; /* one tick wait XXX: 10 ms assumed */
                    if (delay1 < delay)
                        delay = delay1;
578
                }
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
579
                break;
580
            case HTTPSTATE_WAIT_REQUEST:
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
581 582
            case HTTPSTATE_RECEIVE_DATA:
            case HTTPSTATE_WAIT_FEED:
583
            case RTSPSTATE_WAIT_REQUEST:
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
584 585 586
                /* need to catch errors */
                c->poll_entry = poll_entry;
                poll_entry->fd = fd;
587
                poll_entry->events = POLLIN;/* Maybe this will work */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
588 589 590 591 592 593 594 595 596 597 598 599
                poll_entry++;
                break;
            default:
                c->poll_entry = NULL;
                break;
            }
            c = c->next;
        }

        /* wait for an event on one connection. We poll at least every
           second to handle timeouts */
        do {
600
            ret = poll(poll_table, poll_entry - poll_table, delay);
601 602
            if (ret < 0 && ff_neterrno() != FF_NETERROR(EAGAIN) &&
                ff_neterrno() != FF_NETERROR(EINTR))
603
                return -1;
604
        } while (ret < 0);
605

606
        cur_time = av_gettime() / 1000;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
607

608 609 610 611 612
        if (need_to_start_children) {
            need_to_start_children = 0;
            start_children(first_feed);
        }

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
613
        /* now handle the events */
614 615 616
        for(c = first_http_ctx; c != NULL; c = c_next) {
            c_next = c->next;
            if (handle_connection(c) < 0) {
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
617
                /* close and free the connection */
618
                log_connection(c);
619
                close_connection(c);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
620 621 622 623
            }
        }

        poll_entry = poll_table;
624
        /* new HTTP connection request ? */
625
        if (poll_entry->revents & POLLIN)
626
            new_connection(server_fd, 0);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
627
        poll_entry++;
628
        /* new RTSP connection request ? */
629
        if (poll_entry->revents & POLLIN)
630
            new_connection(rtsp_server_fd, 1);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
631 632 633
    }
}

634 635
/* start waiting for a new HTTP/RTSP request */
static void start_wait_request(HTTPContext *c, int is_rtsp)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
636
{
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655
    c->buffer_ptr = c->buffer;
    c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */

    if (is_rtsp) {
        c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
        c->state = RTSPSTATE_WAIT_REQUEST;
    } else {
        c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
        c->state = HTTPSTATE_WAIT_REQUEST;
    }
}

static void new_connection(int server_fd, int is_rtsp)
{
    struct sockaddr_in from_addr;
    int fd, len;
    HTTPContext *c = NULL;

    len = sizeof(from_addr);
656
    fd = accept(server_fd, (struct sockaddr *)&from_addr,
657 658 659
                &len);
    if (fd < 0)
        return;
660
    ff_socket_nonblock(fd, 1);
661 662 663 664 665

    /* XXX: should output a warning page when coming
       close to the connection limit */
    if (nb_connections >= nb_max_connections)
        goto fail;
666

667 668 669 670
    /* add a new connection */
    c = av_mallocz(sizeof(HTTPContext));
    if (!c)
        goto fail;
671

672 673 674 675 676 677 678
    c->fd = fd;
    c->poll_entry = NULL;
    c->from_addr = from_addr;
    c->buffer_size = IOBUFFER_INIT_SIZE;
    c->buffer = av_malloc(c->buffer_size);
    if (!c->buffer)
        goto fail;
679 680 681

    c->next = first_http_ctx;
    first_http_ctx = c;
682
    nb_connections++;
683

684 685 686 687 688 689 690 691 692
    start_wait_request(c, is_rtsp);

    return;

 fail:
    if (c) {
        av_free(c->buffer);
        av_free(c);
    }
693
    closesocket(fd);
694 695 696 697 698 699 700 701 702 703 704 705 706 707
}

static void close_connection(HTTPContext *c)
{
    HTTPContext **cp, *c1;
    int i, nb_streams;
    AVFormatContext *ctx;
    URLContext *h;
    AVStream *st;

    /* remove connection from list */
    cp = &first_http_ctx;
    while ((*cp) != NULL) {
        c1 = *cp;
708
        if (c1 == c)
709
            *cp = c->next;
710
        else
711 712 713
            cp = &c1->next;
    }

714 715 716 717 718 719
    /* remove references, if any (XXX: do it faster) */
    for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
        if (c1->rtsp_c == c)
            c1->rtsp_c = NULL;
    }

720 721
    /* remove connection associated resources */
    if (c->fd >= 0)
722
        closesocket(c->fd);
723 724 725 726
    if (c->fmt_in) {
        /* close each frame parser */
        for(i=0;i<c->fmt_in->nb_streams;i++) {
            st = c->fmt_in->streams[i];
727
            if (st->codec->codec)
728
                avcodec_close(st->codec);
729 730 731 732 733 734
        }
        av_close_input_file(c->fmt_in);
    }

    /* free RTP output streams if any */
    nb_streams = 0;
735
    if (c->stream)
736
        nb_streams = c->stream->nb_streams;
737

738 739 740 741 742 743 744
    for(i=0;i<nb_streams;i++) {
        ctx = c->rtp_ctx[i];
        if (ctx) {
            av_write_trailer(ctx);
            av_free(ctx);
        }
        h = c->rtp_handles[i];
745
        if (h)
746 747
            url_close(h);
    }
748

749 750
    ctx = &c->fmt_ctx;

751 752 753 754 755
    if (!c->last_packet_sent) {
        if (ctx->oformat) {
            /* prepare header */
            if (url_open_dyn_buf(&ctx->pb) >= 0) {
                av_write_trailer(ctx);
756
                url_close_dyn_buf(ctx->pb, &c->pb_buffer);
757 758 759 760
            }
        }
    }

761
    for(i=0; i<ctx->nb_streams; i++)
Alex Beregszaszi's avatar
Alex Beregszaszi committed
762
        av_free(ctx->streams[i]);
763

764
    if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
765
        current_bandwidth -= c->stream->bandwidth;
766 767 768 769 770 771 772

    /* signal that there is no feed if we are the feeder socket */
    if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
        c->stream->feed_opened = 0;
        close(c->feed_fd);
    }

773
    av_freep(&c->pb_buffer);
774
    av_freep(&c->packet_buffer);
775 776 777 778 779 780 781 782
    av_free(c->buffer);
    av_free(c);
    nb_connections--;
}

static int handle_connection(HTTPContext *c)
{
    int len, ret;
783

Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
784 785
    switch(c->state) {
    case HTTPSTATE_WAIT_REQUEST:
786
    case RTSPSTATE_WAIT_REQUEST:
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
787 788 789 790 791 792 793 794 795 796
        /* timeout ? */
        if ((c->timeout - cur_time) < 0)
            return -1;
        if (c->poll_entry->revents & (POLLERR | POLLHUP))
            return -1;

        /* no need to read if no events */
        if (!(c->poll_entry->revents & POLLIN))
            return 0;
        /* read the data */
797
    read_loop:
798
        len = recv(c->fd, c->buffer_ptr, 1, 0);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
799
        if (len < 0) {
800 801
            if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
                ff_neterrno() != FF_NETERROR(EINTR))
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
802 803 804 805
                return -1;
        } else if (len == 0) {
            return -1;
        } else {
Giancarlo Formicuccia's avatar
Giancarlo Formicuccia committed
806
            /* search for end of request. */
807
            uint8_t *ptr;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
808 809 810 811 812
            c->buffer_ptr += len;
            ptr = c->buffer_ptr;
            if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
                (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
                /* request found : parse it and reply */
813 814 815 816 817 818
                if (c->state == HTTPSTATE_WAIT_REQUEST) {
                    ret = http_parse_request(c);
                } else {
                    ret = rtsp_parse_request(c);
                }
                if (ret < 0)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
819 820 821 822
                    return -1;
            } else if (ptr >= c->buffer_end) {
                /* request too long: cannot do anything */
                return -1;
823
            } else goto read_loop;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
824 825 826 827 828 829 830
        }
        break;

    case HTTPSTATE_SEND_HEADER:
        if (c->poll_entry->revents & (POLLERR | POLLHUP))
            return -1;

831
        /* no need to write if no events */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
832 833
        if (!(c->poll_entry->revents & POLLOUT))
            return 0;
834
        len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
835
        if (len < 0) {
836 837
            if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
                ff_neterrno() != FF_NETERROR(EINTR)) {
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
838
                /* error : close connection */
839
                av_freep(&c->pb_buffer);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
840 841 842 843
                return -1;
            }
        } else {
            c->buffer_ptr += len;
844 845
            if (c->stream)
                c->stream->bytes_served += len;
846
            c->data_count += len;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
847
            if (c->buffer_ptr >= c->buffer_end) {
848
                av_freep(&c->pb_buffer);
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
849
                /* if error, exit */
850
                if (c->http_error)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
851
                    return -1;
852
                /* all the buffer was sent : synchronize to the incoming stream */
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
853 854 855 856 857 858 859 860 861
                c->state = HTTPSTATE_SEND_DATA_HEADER;
                c->buffer_ptr = c->buffer_end = c->buffer;
            }
        }
        break;

    case HTTPSTATE_SEND_DATA:
    case HTTPSTATE_SEND_DATA_HEADER:
    case HTTPSTATE_SEND_DATA_TRAILER:
862 863 864 865 866 867
        /* for packetized output, we consider we can always write (the
           input streams sets the speed). It may be better to verify
           that we do not rely too much on the kernel queues */
        if (!c->is_packetized) {
            if (c->poll_entry->revents & (POLLERR | POLLHUP))
                return -1;
868

869 870 871 872
            /* no need to read if no events */
            if (!(c->poll_entry->revents & POLLOUT))
                return 0;
        }
873
        if (http_send_data(c) < 0)
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
874
            return -1;
875 876 877
        /* close connection if trailer sent */
        if (c->state == HTTPSTATE_SEND_DATA_TRAILER)
            return -1;
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
878 879 880 881 882 883 884 885 886 887 888 889
        break;
    case HTTPSTATE_RECEIVE_DATA:
        /* no need to read if no events */
        if (c->poll_entry->revents & (POLLERR | POLLHUP))
            return -1;
        if (!(c->poll_entry->revents & POLLIN))
            return 0;
        if (http_receive_data(c) < 0)
            return -1;
        break;
    case HTTPSTATE_WAIT_FEED:
        /* no need to read if no events */
890
        if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))
Fabrice Bellard's avatar
merge  
Fabrice Bellard committed
891 892 893 894
            return -1;

        /* nothing to do, we'll be waken up by incoming feed packets */
        break;
895 896 897 898 899 900 901 902 903

    case RTSPSTATE_SEND_REPLY:
        if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
            av_freep(&c->pb_buffer);
            return -1;
        }
        /* no need to write if no events */
        if (!(c->poll_entry->revents & POLLOUT))
            return 0;