]> git.sesse.net Git - ffmpeg/blob - ffserver.c
Merge commit 'c3e15f7b39aac2012f09ee4ca86d2bc674ffdbd4'
[ffmpeg] / ffserver.c
1 /*
2  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * multiple format streaming server based on the FFmpeg libraries
24  */
25
26 #include "config.h"
27 #if !HAVE_CLOSESOCKET
28 #define closesocket close
29 #endif
30 #include <string.h>
31 #include <stdlib.h>
32 #include "libavformat/avformat.h"
33 // FIXME those are internal headers, ffserver _really_ shouldn't use them
34 #include "libavformat/ffm.h"
35 #include "libavformat/network.h"
36 #include "libavformat/os_support.h"
37 #include "libavformat/rtpdec.h"
38 #include "libavformat/rtsp.h"
39 #include "libavformat/avio_internal.h"
40 #include "libavformat/internal.h"
41 #include "libavformat/url.h"
42
43 #include "libavutil/avassert.h"
44 #include "libavutil/avstring.h"
45 #include "libavutil/lfg.h"
46 #include "libavutil/dict.h"
47 #include "libavutil/intreadwrite.h"
48 #include "libavutil/mathematics.h"
49 #include "libavutil/random_seed.h"
50 #include "libavutil/parseutils.h"
51 #include "libavutil/opt.h"
52 #include "libavutil/time.h"
53
54 #include <stdarg.h>
55 #include <unistd.h>
56 #include <fcntl.h>
57 #include <sys/ioctl.h>
58 #if HAVE_POLL_H
59 #include <poll.h>
60 #endif
61 #include <errno.h>
62 #include <time.h>
63 #include <sys/wait.h>
64 #include <signal.h>
65 #if HAVE_DLFCN_H
66 #include <dlfcn.h>
67 #endif
68
69 #include "cmdutils.h"
70
71 const char program_name[] = "ffserver";
72 const int program_birth_year = 2000;
73
74 static const OptionDef options[];
75
76 enum HTTPState {
77     HTTPSTATE_WAIT_REQUEST,
78     HTTPSTATE_SEND_HEADER,
79     HTTPSTATE_SEND_DATA_HEADER,
80     HTTPSTATE_SEND_DATA,          /* sending TCP or UDP data */
81     HTTPSTATE_SEND_DATA_TRAILER,
82     HTTPSTATE_RECEIVE_DATA,
83     HTTPSTATE_WAIT_FEED,          /* wait for data from the feed */
84     HTTPSTATE_READY,
85
86     RTSPSTATE_WAIT_REQUEST,
87     RTSPSTATE_SEND_REPLY,
88     RTSPSTATE_SEND_PACKET,
89 };
90
91 static const char *http_state[] = {
92     "HTTP_WAIT_REQUEST",
93     "HTTP_SEND_HEADER",
94
95     "SEND_DATA_HEADER",
96     "SEND_DATA",
97     "SEND_DATA_TRAILER",
98     "RECEIVE_DATA",
99     "WAIT_FEED",
100     "READY",
101
102     "RTSP_WAIT_REQUEST",
103     "RTSP_SEND_REPLY",
104     "RTSP_SEND_PACKET",
105 };
106
107 #define MAX_STREAMS 20
108
109 #define IOBUFFER_INIT_SIZE 8192
110
111 /* timeouts are in ms */
112 #define HTTP_REQUEST_TIMEOUT (15 * 1000)
113 #define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000)
114
115 #define SYNC_TIMEOUT (10 * 1000)
116
117 typedef struct RTSPActionServerSetup {
118     uint32_t ipaddr;
119     char transport_option[512];
120 } RTSPActionServerSetup;
121
122 typedef struct {
123     int64_t count1, count2;
124     int64_t time1, time2;
125 } DataRateData;
126
127 /* context associated with one connection */
128 typedef struct HTTPContext {
129     enum HTTPState state;
130     int fd; /* socket file descriptor */
131     struct sockaddr_in from_addr; /* origin */
132     struct pollfd *poll_entry; /* used when polling */
133     int64_t timeout;
134     uint8_t *buffer_ptr, *buffer_end;
135     int http_error;
136     int post;
137     int chunked_encoding;
138     int chunk_size;               /* 0 if it needs to be read */
139     struct HTTPContext *next;
140     int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
141     int64_t data_count;
142     /* feed input */
143     int feed_fd;
144     /* input format handling */
145     AVFormatContext *fmt_in;
146     int64_t start_time;            /* In milliseconds - this wraps fairly often */
147     int64_t first_pts;            /* initial pts value */
148     int64_t cur_pts;             /* current pts value from the stream in us */
149     int64_t cur_frame_duration;  /* duration of the current frame in us */
150     int cur_frame_bytes;       /* output frame size, needed to compute
151                                   the time at which we send each
152                                   packet */
153     int pts_stream_index;        /* stream we choose as clock reference */
154     int64_t cur_clock;           /* current clock reference value in us */
155     /* output format handling */
156     struct FFStream *stream;
157     /* -1 is invalid stream */
158     int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
159     int switch_feed_streams[MAX_STREAMS]; /* index of streams in the feed */
160     int switch_pending;
161     AVFormatContext fmt_ctx; /* instance of FFStream for one user */
162     int last_packet_sent; /* true if last data packet was sent */
163     int suppress_log;
164     DataRateData datarate;
165     int wmp_client_id;
166     char protocol[16];
167     char method[16];
168     char url[128];
169     int buffer_size;
170     uint8_t *buffer;
171     int is_packetized; /* if true, the stream is packetized */
172     int packet_stream_index; /* current stream for output in state machine */
173
174     /* RTSP state specific */
175     uint8_t *pb_buffer; /* XXX: use that in all the code */
176     AVIOContext *pb;
177     int seq; /* RTSP sequence number */
178
179     /* RTP state specific */
180     enum RTSPLowerTransport rtp_protocol;
181     char session_id[32]; /* session id */
182     AVFormatContext *rtp_ctx[MAX_STREAMS];
183
184     /* RTP/UDP specific */
185     URLContext *rtp_handles[MAX_STREAMS];
186
187     /* RTP/TCP specific */
188     struct HTTPContext *rtsp_c;
189     uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
190 } HTTPContext;
191
192 /* each generated stream is described here */
193 enum StreamType {
194     STREAM_TYPE_LIVE,
195     STREAM_TYPE_STATUS,
196     STREAM_TYPE_REDIRECT,
197 };
198
199 enum IPAddressAction {
200     IP_ALLOW = 1,
201     IP_DENY,
202 };
203
204 typedef struct IPAddressACL {
205     struct IPAddressACL *next;
206     enum IPAddressAction action;
207     /* These are in host order */
208     struct in_addr first;
209     struct in_addr last;
210 } IPAddressACL;
211
212 /* description of each stream of the ffserver.conf file */
213 typedef struct FFStream {
214     enum StreamType stream_type;
215     char filename[1024];     /* stream filename */
216     struct FFStream *feed;   /* feed we are using (can be null if
217                                 coming from file) */
218     AVDictionary *in_opts;   /* input parameters */
219     AVInputFormat *ifmt;       /* if non NULL, force input format */
220     AVOutputFormat *fmt;
221     IPAddressACL *acl;
222     char dynamic_acl[1024];
223     int nb_streams;
224     int prebuffer;      /* Number of millseconds early to start */
225     int64_t max_time;      /* Number of milliseconds to run */
226     int send_on_key;
227     AVStream *streams[MAX_STREAMS];
228     int feed_streams[MAX_STREAMS]; /* index of streams in the feed */
229     char feed_filename[1024]; /* file name of the feed storage, or
230                                  input file name for a stream */
231     char author[512];
232     char title[512];
233     char copyright[512];
234     char comment[512];
235     pid_t pid;  /* Of ffmpeg process */
236     time_t pid_start;  /* Of ffmpeg process */
237     char **child_argv;
238     struct FFStream *next;
239     unsigned bandwidth; /* bandwidth, in kbits/s */
240     /* RTSP options */
241     char *rtsp_option;
242     /* multicast specific */
243     int is_multicast;
244     struct in_addr multicast_ip;
245     int multicast_port; /* first port used for multicast */
246     int multicast_ttl;
247     int loop; /* if true, send the stream in loops (only meaningful if file) */
248
249     /* feed specific */
250     int feed_opened;     /* true if someone is writing to the feed */
251     int is_feed;         /* true if it is a feed */
252     int readonly;        /* True if writing is prohibited to the file */
253     int truncate;        /* True if feeder connection truncate the feed file */
254     int conns_served;
255     int64_t bytes_served;
256     int64_t feed_max_size;      /* maximum storage size, zero means unlimited */
257     int64_t feed_write_index;   /* current write position in feed (it wraps around) */
258     int64_t feed_size;          /* current size of feed */
259     struct FFStream *next_feed;
260 } FFStream;
261
262 typedef struct FeedData {
263     long long data_count;
264     float avg_frame_size;   /* frame size averaged over last frames with exponential mean */
265 } FeedData;
266
267 static struct sockaddr_in my_http_addr;
268 static struct sockaddr_in my_rtsp_addr;
269
270 static char logfilename[1024];
271 static HTTPContext *first_http_ctx;
272 static FFStream *first_feed;   /* contains only feeds */
273 static FFStream *first_stream; /* contains all streams, including feeds */
274
275 static void new_connection(int server_fd, int is_rtsp);
276 static void close_connection(HTTPContext *c);
277
278 /* HTTP handling */
279 static int handle_connection(HTTPContext *c);
280 static int http_parse_request(HTTPContext *c);
281 static int http_send_data(HTTPContext *c);
282 static void compute_status(HTTPContext *c);
283 static int open_input_stream(HTTPContext *c, const char *info);
284 static int http_start_receive_data(HTTPContext *c);
285 static int http_receive_data(HTTPContext *c);
286
287 /* RTSP handling */
288 static int rtsp_parse_request(HTTPContext *c);
289 static void rtsp_cmd_describe(HTTPContext *c, const char *url);
290 static void rtsp_cmd_options(HTTPContext *c, const char *url);
291 static void rtsp_cmd_setup(HTTPContext *c, const char *url, RTSPMessageHeader *h);
292 static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h);
293 static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h);
294 static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h);
295
296 /* SDP handling */
297 static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
298                                    struct in_addr my_ip);
299
300 /* RTP handling */
301 static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
302                                        FFStream *stream, const char *session_id,
303                                        enum RTSPLowerTransport rtp_protocol);
304 static int rtp_new_av_stream(HTTPContext *c,
305                              int stream_index, struct sockaddr_in *dest_addr,
306                              HTTPContext *rtsp_c);
307
308 static const char *my_program_name;
309 static const char *my_program_dir;
310
311 static const char *config_filename = "/etc/ffserver.conf";
312
313 static int ffserver_debug;
314 static int ffserver_daemon;
315 static int no_launch;
316 static int need_to_start_children;
317
318 /* maximum number of simultaneous HTTP connections */
319 static unsigned int nb_max_http_connections = 2000;
320 static unsigned int nb_max_connections = 5;
321 static unsigned int nb_connections;
322
323 static uint64_t max_bandwidth = 1000;
324 static uint64_t current_bandwidth;
325
326 static int64_t cur_time;           // Making this global saves on passing it around everywhere
327
328 static AVLFG random_state;
329
330 static FILE *logfile = NULL;
331
332 static int64_t ffm_read_write_index(int fd)
333 {
334     uint8_t buf[8];
335
336     if (lseek(fd, 8, SEEK_SET) < 0)
337         return AVERROR(EIO);
338     if (read(fd, buf, 8) != 8)
339         return AVERROR(EIO);
340     return AV_RB64(buf);
341 }
342
343 static int ffm_write_write_index(int fd, int64_t pos)
344 {
345     uint8_t buf[8];
346     int i;
347
348     for(i=0;i<8;i++)
349         buf[i] = (pos >> (56 - i * 8)) & 0xff;
350     if (lseek(fd, 8, SEEK_SET) < 0)
351         return AVERROR(EIO);
352     if (write(fd, buf, 8) != 8)
353         return AVERROR(EIO);
354     return 8;
355 }
356
357 static void ffm_set_write_index(AVFormatContext *s, int64_t pos,
358                                 int64_t file_size)
359 {
360     FFMContext *ffm = s->priv_data;
361     ffm->write_index = pos;
362     ffm->file_size = file_size;
363 }
364
365 /* FIXME: make ffserver work with IPv6 */
366 /* resolve host with also IP address parsing */
367 static int resolve_host(struct in_addr *sin_addr, const char *hostname)
368 {
369
370     if (!ff_inet_aton(hostname, sin_addr)) {
371 #if HAVE_GETADDRINFO
372         struct addrinfo *ai, *cur;
373         struct addrinfo hints = { 0 };
374         hints.ai_family = AF_INET;
375         if (getaddrinfo(hostname, NULL, &hints, &ai))
376             return -1;
377         /* getaddrinfo returns a linked list of addrinfo structs.
378          * Even if we set ai_family = AF_INET above, make sure
379          * that the returned one actually is of the correct type. */
380         for (cur = ai; cur; cur = cur->ai_next) {
381             if (cur->ai_family == AF_INET) {
382                 *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
383                 freeaddrinfo(ai);
384                 return 0;
385             }
386         }
387         freeaddrinfo(ai);
388         return -1;
389 #else
390         struct hostent *hp;
391         hp = gethostbyname(hostname);
392         if (!hp)
393             return -1;
394         memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
395 #endif
396     }
397     return 0;
398 }
399
400 static char *ctime1(char *buf2)
401 {
402     time_t ti;
403     char *p;
404
405     ti = time(NULL);
406     p = ctime(&ti);
407     strcpy(buf2, p);
408     p = buf2 + strlen(p) - 1;
409     if (*p == '\n')
410         *p = '\0';
411     return buf2;
412 }
413
414 static void http_vlog(const char *fmt, va_list vargs)
415 {
416     static int print_prefix = 1;
417     if (logfile) {
418         if (print_prefix) {
419             char buf[32];
420             ctime1(buf);
421             fprintf(logfile, "%s ", buf);
422         }
423         print_prefix = strstr(fmt, "\n") != NULL;
424         vfprintf(logfile, fmt, vargs);
425         fflush(logfile);
426     }
427 }
428
429 #ifdef __GNUC__
430 __attribute__ ((format (printf, 1, 2)))
431 #endif
432 static void http_log(const char *fmt, ...)
433 {
434     va_list vargs;
435     va_start(vargs, fmt);
436     http_vlog(fmt, vargs);
437     va_end(vargs);
438 }
439
440 static void http_av_log(void *ptr, int level, const char *fmt, va_list vargs)
441 {
442     static int print_prefix = 1;
443     AVClass *avc = ptr ? *(AVClass**)ptr : NULL;
444     if (level > av_log_get_level())
445         return;
446     if (print_prefix && avc)
447         http_log("[%s @ %p]", avc->item_name(ptr), ptr);
448     print_prefix = strstr(fmt, "\n") != NULL;
449     http_vlog(fmt, vargs);
450 }
451
452 static void log_connection(HTTPContext *c)
453 {
454     if (c->suppress_log)
455         return;
456
457     http_log("%s - - [%s] \"%s %s\" %d %"PRId64"\n",
458              inet_ntoa(c->from_addr.sin_addr), c->method, c->url,
459              c->protocol, (c->http_error ? c->http_error : 200), c->data_count);
460 }
461
462 static void update_datarate(DataRateData *drd, int64_t count)
463 {
464     if (!drd->time1 && !drd->count1) {
465         drd->time1 = drd->time2 = cur_time;
466         drd->count1 = drd->count2 = count;
467     } else if (cur_time - drd->time2 > 5000) {
468         drd->time1 = drd->time2;
469         drd->count1 = drd->count2;
470         drd->time2 = cur_time;
471         drd->count2 = count;
472     }
473 }
474
475 /* In bytes per second */
476 static int compute_datarate(DataRateData *drd, int64_t count)
477 {
478     if (cur_time == drd->time1)
479         return 0;
480
481     return ((count - drd->count1) * 1000) / (cur_time - drd->time1);
482 }
483
484
485 static void start_children(FFStream *feed)
486 {
487     if (no_launch)
488         return;
489
490     for (; feed; feed = feed->next) {
491         if (feed->child_argv && !feed->pid) {
492             feed->pid_start = time(0);
493
494             feed->pid = fork();
495
496             if (feed->pid < 0) {
497                 http_log("Unable to create children\n");
498                 exit(1);
499             }
500             if (!feed->pid) {
501                 /* In child */
502                 char pathname[1024];
503                 char *slash;
504                 int i;
505
506                 av_strlcpy(pathname, my_program_name, sizeof(pathname));
507
508                 slash = strrchr(pathname, '/');
509                 if (!slash)
510                     slash = pathname;
511                 else
512                     slash++;
513                 strcpy(slash, "ffmpeg");
514
515                 http_log("Launch command line: ");
516                 http_log("%s ", pathname);
517                 for (i = 1; feed->child_argv[i] && feed->child_argv[i][0]; i++)
518                     http_log("%s ", feed->child_argv[i]);
519                 http_log("\n");
520
521                 for (i = 3; i < 256; i++)
522                     close(i);
523
524                 if (!ffserver_debug) {
525                     i = open("/dev/null", O_RDWR);
526                     if (i != -1) {
527                         dup2(i, 0);
528                         dup2(i, 1);
529                         dup2(i, 2);
530                         close(i);
531                     }
532                 }
533
534                 /* This is needed to make relative pathnames work */
535                 if (chdir(my_program_dir) < 0) {
536                     http_log("chdir failed\n");
537                     exit(1);
538                 }
539
540                 signal(SIGPIPE, SIG_DFL);
541
542                 execvp(pathname, feed->child_argv);
543
544                 _exit(1);
545             }
546         }
547     }
548 }
549
550 /* open a listening socket */
551 static int socket_open_listen(struct sockaddr_in *my_addr)
552 {
553     int server_fd, tmp;
554
555     server_fd = socket(AF_INET,SOCK_STREAM,0);
556     if (server_fd < 0) {
557         perror ("socket");
558         return -1;
559     }
560
561     tmp = 1;
562     setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
563
564     my_addr->sin_family = AF_INET;
565     if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) {
566         char bindmsg[32];
567         snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port));
568         perror (bindmsg);
569         closesocket(server_fd);
570         return -1;
571     }
572
573     if (listen (server_fd, 5) < 0) {
574         perror ("listen");
575         closesocket(server_fd);
576         return -1;
577     }
578     ff_socket_nonblock(server_fd, 1);
579
580     return server_fd;
581 }
582
583 /* start all multicast streams */
584 static void start_multicast(void)
585 {
586     FFStream *stream;
587     char session_id[32];
588     HTTPContext *rtp_c;
589     struct sockaddr_in dest_addr;
590     int default_port, stream_index;
591
592     default_port = 6000;
593     for(stream = first_stream; stream != NULL; stream = stream->next) {
594         if (stream->is_multicast) {
595             unsigned random0 = av_lfg_get(&random_state);
596             unsigned random1 = av_lfg_get(&random_state);
597             /* open the RTP connection */
598             snprintf(session_id, sizeof(session_id), "%08x%08x",
599                      random0, random1);
600
601             /* choose a port if none given */
602             if (stream->multicast_port == 0) {
603                 stream->multicast_port = default_port;
604                 default_port += 100;
605             }
606
607             dest_addr.sin_family = AF_INET;
608             dest_addr.sin_addr = stream->multicast_ip;
609             dest_addr.sin_port = htons(stream->multicast_port);
610
611             rtp_c = rtp_new_connection(&dest_addr, stream, session_id,
612                                        RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
613             if (!rtp_c)
614                 continue;
615
616             if (open_input_stream(rtp_c, "") < 0) {
617                 http_log("Could not open input stream for stream '%s'\n",
618                          stream->filename);
619                 continue;
620             }
621
622             /* open each RTP stream */
623             for(stream_index = 0; stream_index < stream->nb_streams;
624                 stream_index++) {
625                 dest_addr.sin_port = htons(stream->multicast_port +
626                                            2 * stream_index);
627                 if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, NULL) < 0) {
628                     http_log("Could not open output stream '%s/streamid=%d'\n",
629                              stream->filename, stream_index);
630                     exit(1);
631                 }
632             }
633
634             /* change state to send data */
635             rtp_c->state = HTTPSTATE_SEND_DATA;
636         }
637     }
638 }
639
640 /* main loop of the http server */
641 static int http_server(void)
642 {
643     int server_fd = 0, rtsp_server_fd = 0;
644     int ret, delay, delay1;
645     struct pollfd *poll_table, *poll_entry;
646     HTTPContext *c, *c_next;
647
648     if(!(poll_table = av_mallocz((nb_max_http_connections + 2)*sizeof(*poll_table)))) {
649         http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections);
650         return -1;
651     }
652
653     if (my_http_addr.sin_port) {
654         server_fd = socket_open_listen(&my_http_addr);
655         if (server_fd < 0)
656             return -1;
657     }
658
659     if (my_rtsp_addr.sin_port) {
660         rtsp_server_fd = socket_open_listen(&my_rtsp_addr);
661         if (rtsp_server_fd < 0)
662             return -1;
663     }
664
665     if (!rtsp_server_fd && !server_fd) {
666         http_log("HTTP and RTSP disabled.\n");
667         return -1;
668     }
669
670     http_log("FFserver started.\n");
671
672     start_children(first_feed);
673
674     start_multicast();
675
676     for(;;) {
677         poll_entry = poll_table;
678         if (server_fd) {
679             poll_entry->fd = server_fd;
680             poll_entry->events = POLLIN;
681             poll_entry++;
682         }
683         if (rtsp_server_fd) {
684             poll_entry->fd = rtsp_server_fd;
685             poll_entry->events = POLLIN;
686             poll_entry++;
687         }
688
689         /* wait for events on each HTTP handle */
690         c = first_http_ctx;
691         delay = 1000;
692         while (c != NULL) {
693             int fd;
694             fd = c->fd;
695             switch(c->state) {
696             case HTTPSTATE_SEND_HEADER:
697             case RTSPSTATE_SEND_REPLY:
698             case RTSPSTATE_SEND_PACKET:
699                 c->poll_entry = poll_entry;
700                 poll_entry->fd = fd;
701                 poll_entry->events = POLLOUT;
702                 poll_entry++;
703                 break;
704             case HTTPSTATE_SEND_DATA_HEADER:
705             case HTTPSTATE_SEND_DATA:
706             case HTTPSTATE_SEND_DATA_TRAILER:
707                 if (!c->is_packetized) {
708                     /* for TCP, we output as much as we can (may need to put a limit) */
709                     c->poll_entry = poll_entry;
710                     poll_entry->fd = fd;
711                     poll_entry->events = POLLOUT;
712                     poll_entry++;
713                 } else {
714                     /* when ffserver is doing the timing, we work by
715                        looking at which packet need to be sent every
716                        10 ms */
717                     delay1 = 10; /* one tick wait XXX: 10 ms assumed */
718                     if (delay1 < delay)
719                         delay = delay1;
720                 }
721                 break;
722             case HTTPSTATE_WAIT_REQUEST:
723             case HTTPSTATE_RECEIVE_DATA:
724             case HTTPSTATE_WAIT_FEED:
725             case RTSPSTATE_WAIT_REQUEST:
726                 /* need to catch errors */
727                 c->poll_entry = poll_entry;
728                 poll_entry->fd = fd;
729                 poll_entry->events = POLLIN;/* Maybe this will work */
730                 poll_entry++;
731                 break;
732             default:
733                 c->poll_entry = NULL;
734                 break;
735             }
736             c = c->next;
737         }
738
739         /* wait for an event on one connection. We poll at least every
740            second to handle timeouts */
741         do {
742             ret = poll(poll_table, poll_entry - poll_table, delay);
743             if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
744                 ff_neterrno() != AVERROR(EINTR))
745                 return -1;
746         } while (ret < 0);
747
748         cur_time = av_gettime() / 1000;
749
750         if (need_to_start_children) {
751             need_to_start_children = 0;
752             start_children(first_feed);
753         }
754
755         /* now handle the events */
756         for(c = first_http_ctx; c != NULL; c = c_next) {
757             c_next = c->next;
758             if (handle_connection(c) < 0) {
759                 /* close and free the connection */
760                 log_connection(c);
761                 close_connection(c);
762             }
763         }
764
765         poll_entry = poll_table;
766         if (server_fd) {
767             /* new HTTP connection request ? */
768             if (poll_entry->revents & POLLIN)
769                 new_connection(server_fd, 0);
770             poll_entry++;
771         }
772         if (rtsp_server_fd) {
773             /* new RTSP connection request ? */
774             if (poll_entry->revents & POLLIN)
775                 new_connection(rtsp_server_fd, 1);
776         }
777     }
778 }
779
780 /* start waiting for a new HTTP/RTSP request */
781 static void start_wait_request(HTTPContext *c, int is_rtsp)
782 {
783     c->buffer_ptr = c->buffer;
784     c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */
785
786     if (is_rtsp) {
787         c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
788         c->state = RTSPSTATE_WAIT_REQUEST;
789     } else {
790         c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
791         c->state = HTTPSTATE_WAIT_REQUEST;
792     }
793 }
794
795 static void http_send_too_busy_reply(int fd)
796 {
797     char buffer[400];
798     int len = snprintf(buffer, sizeof(buffer),
799                        "HTTP/1.0 503 Server too busy\r\n"
800                        "Content-type: text/html\r\n"
801                        "\r\n"
802                        "<html><head><title>Too busy</title></head><body>\r\n"
803                        "<p>The server is too busy to serve your request at this time.</p>\r\n"
804                        "<p>The number of current connections is %d, and this exceeds the limit of %d.</p>\r\n"
805                        "</body></html>\r\n",
806                        nb_connections, nb_max_connections);
807     av_assert0(len < sizeof(buffer));
808     send(fd, buffer, len, 0);
809 }
810
811
812 static void new_connection(int server_fd, int is_rtsp)
813 {
814     struct sockaddr_in from_addr;
815     int fd, len;
816     HTTPContext *c = NULL;
817
818     len = sizeof(from_addr);
819     fd = accept(server_fd, (struct sockaddr *)&from_addr,
820                 &len);
821     if (fd < 0) {
822         http_log("error during accept %s\n", strerror(errno));
823         return;
824     }
825     ff_socket_nonblock(fd, 1);
826
827     if (nb_connections >= nb_max_connections) {
828         http_send_too_busy_reply(fd);
829         goto fail;
830     }
831
832     /* add a new connection */
833     c = av_mallocz(sizeof(HTTPContext));
834     if (!c)
835         goto fail;
836
837     c->fd = fd;
838     c->poll_entry = NULL;
839     c->from_addr = from_addr;
840     c->buffer_size = IOBUFFER_INIT_SIZE;
841     c->buffer = av_malloc(c->buffer_size);
842     if (!c->buffer)
843         goto fail;
844
845     c->next = first_http_ctx;
846     first_http_ctx = c;
847     nb_connections++;
848
849     start_wait_request(c, is_rtsp);
850
851     return;
852
853  fail:
854     if (c) {
855         av_free(c->buffer);
856         av_free(c);
857     }
858     closesocket(fd);
859 }
860
861 static void close_connection(HTTPContext *c)
862 {
863     HTTPContext **cp, *c1;
864     int i, nb_streams;
865     AVFormatContext *ctx;
866     URLContext *h;
867     AVStream *st;
868
869     /* remove connection from list */
870     cp = &first_http_ctx;
871     while ((*cp) != NULL) {
872         c1 = *cp;
873         if (c1 == c)
874             *cp = c->next;
875         else
876             cp = &c1->next;
877     }
878
879     /* remove references, if any (XXX: do it faster) */
880     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
881         if (c1->rtsp_c == c)
882             c1->rtsp_c = NULL;
883     }
884
885     /* remove connection associated resources */
886     if (c->fd >= 0)
887         closesocket(c->fd);
888     if (c->fmt_in) {
889         /* close each frame parser */
890         for(i=0;i<c->fmt_in->nb_streams;i++) {
891             st = c->fmt_in->streams[i];
892             if (st->codec->codec)
893                 avcodec_close(st->codec);
894         }
895         avformat_close_input(&c->fmt_in);
896     }
897
898     /* free RTP output streams if any */
899     nb_streams = 0;
900     if (c->stream)
901         nb_streams = c->stream->nb_streams;
902
903     for(i=0;i<nb_streams;i++) {
904         ctx = c->rtp_ctx[i];
905         if (ctx) {
906             av_write_trailer(ctx);
907             av_dict_free(&ctx->metadata);
908             av_free(ctx->streams[0]);
909             av_free(ctx);
910         }
911         h = c->rtp_handles[i];
912         if (h)
913             ffurl_close(h);
914     }
915
916     ctx = &c->fmt_ctx;
917
918     if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
919         if (ctx->oformat) {
920             /* prepare header */
921             if (avio_open_dyn_buf(&ctx->pb) >= 0) {
922                 av_write_trailer(ctx);
923                 av_freep(&c->pb_buffer);
924                 avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
925             }
926         }
927     }
928
929     for(i=0; i<ctx->nb_streams; i++)
930         av_free(ctx->streams[i]);
931
932     if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
933         current_bandwidth -= c->stream->bandwidth;
934
935     /* signal that there is no feed if we are the feeder socket */
936     if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
937         c->stream->feed_opened = 0;
938         close(c->feed_fd);
939     }
940
941     av_freep(&c->pb_buffer);
942     av_freep(&c->packet_buffer);
943     av_free(c->buffer);
944     av_free(c);
945     nb_connections--;
946 }
947
948 static int handle_connection(HTTPContext *c)
949 {
950     int len, ret;
951
952     switch(c->state) {
953     case HTTPSTATE_WAIT_REQUEST:
954     case RTSPSTATE_WAIT_REQUEST:
955         /* timeout ? */
956         if ((c->timeout - cur_time) < 0)
957             return -1;
958         if (c->poll_entry->revents & (POLLERR | POLLHUP))
959             return -1;
960
961         /* no need to read if no events */
962         if (!(c->poll_entry->revents & POLLIN))
963             return 0;
964         /* read the data */
965     read_loop:
966         len = recv(c->fd, c->buffer_ptr, 1, 0);
967         if (len < 0) {
968             if (ff_neterrno() != AVERROR(EAGAIN) &&
969                 ff_neterrno() != AVERROR(EINTR))
970                 return -1;
971         } else if (len == 0) {
972             return -1;
973         } else {
974             /* search for end of request. */
975             uint8_t *ptr;
976             c->buffer_ptr += len;
977             ptr = c->buffer_ptr;
978             if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
979                 (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
980                 /* request found : parse it and reply */
981                 if (c->state == HTTPSTATE_WAIT_REQUEST) {
982                     ret = http_parse_request(c);
983                 } else {
984                     ret = rtsp_parse_request(c);
985                 }
986                 if (ret < 0)
987                     return -1;
988             } else if (ptr >= c->buffer_end) {
989                 /* request too long: cannot do anything */
990                 return -1;
991             } else goto read_loop;
992         }
993         break;
994
995     case HTTPSTATE_SEND_HEADER:
996         if (c->poll_entry->revents & (POLLERR | POLLHUP))
997             return -1;
998
999         /* no need to write if no events */
1000         if (!(c->poll_entry->revents & POLLOUT))
1001             return 0;
1002         len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
1003         if (len < 0) {
1004             if (ff_neterrno() != AVERROR(EAGAIN) &&
1005                 ff_neterrno() != AVERROR(EINTR)) {
1006                 /* error : close connection */
1007                 av_freep(&c->pb_buffer);
1008                 return -1;
1009             }
1010         } else {
1011             c->buffer_ptr += len;
1012             if (c->stream)
1013                 c->stream->bytes_served += len;
1014             c->data_count += len;
1015             if (c->buffer_ptr >= c->buffer_end) {
1016                 av_freep(&c->pb_buffer);
1017                 /* if error, exit */
1018                 if (c->http_error)
1019                     return -1;
1020                 /* all the buffer was sent : synchronize to the incoming stream */
1021                 c->state = HTTPSTATE_SEND_DATA_HEADER;
1022                 c->buffer_ptr = c->buffer_end = c->buffer;
1023             }
1024         }
1025         break;
1026
1027     case HTTPSTATE_SEND_DATA:
1028     case HTTPSTATE_SEND_DATA_HEADER:
1029     case HTTPSTATE_SEND_DATA_TRAILER:
1030         /* for packetized output, we consider we can always write (the
1031            input streams sets the speed). It may be better to verify
1032            that we do not rely too much on the kernel queues */
1033         if (!c->is_packetized) {
1034             if (c->poll_entry->revents & (POLLERR | POLLHUP))
1035                 return -1;
1036
1037             /* no need to read if no events */
1038             if (!(c->poll_entry->revents & POLLOUT))
1039                 return 0;
1040         }
1041         if (http_send_data(c) < 0)
1042             return -1;
1043         /* close connection if trailer sent */
1044         if (c->state == HTTPSTATE_SEND_DATA_TRAILER)
1045             return -1;
1046         break;
1047     case HTTPSTATE_RECEIVE_DATA:
1048         /* no need to read if no events */
1049         if (c->poll_entry->revents & (POLLERR | POLLHUP))
1050             return -1;
1051         if (!(c->poll_entry->revents & POLLIN))
1052             return 0;
1053         if (http_receive_data(c) < 0)
1054             return -1;
1055         break;
1056     case HTTPSTATE_WAIT_FEED:
1057         /* no need to read if no events */
1058         if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))
1059             return -1;
1060
1061         /* nothing to do, we'll be waken up by incoming feed packets */
1062         break;
1063
1064     case RTSPSTATE_SEND_REPLY:
1065         if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
1066             av_freep(&c->pb_buffer);
1067             return -1;
1068         }
1069         /* no need to write if no events */
1070         if (!(c->poll_entry->revents & POLLOUT))
1071             return 0;
1072         len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
1073         if (len < 0) {
1074             if (ff_neterrno() != AVERROR(EAGAIN) &&
1075                 ff_neterrno() != AVERROR(EINTR)) {
1076                 /* error : close connection */
1077                 av_freep(&c->pb_buffer);
1078                 return -1;
1079             }
1080         } else {
1081             c->buffer_ptr += len;
1082             c->data_count += len;
1083             if (c->buffer_ptr >= c->buffer_end) {
1084                 /* all the buffer was sent : wait for a new request */
1085                 av_freep(&c->pb_buffer);
1086                 start_wait_request(c, 1);
1087             }
1088         }
1089         break;
1090     case RTSPSTATE_SEND_PACKET:
1091         if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
1092             av_freep(&c->packet_buffer);
1093             return -1;
1094         }
1095         /* no need to write if no events */
1096         if (!(c->poll_entry->revents & POLLOUT))
1097             return 0;
1098         len = send(c->fd, c->packet_buffer_ptr,
1099                     c->packet_buffer_end - c->packet_buffer_ptr, 0);
1100         if (len < 0) {
1101             if (ff_neterrno() != AVERROR(EAGAIN) &&
1102                 ff_neterrno() != AVERROR(EINTR)) {
1103                 /* error : close connection */
1104                 av_freep(&c->packet_buffer);
1105                 return -1;
1106             }
1107         } else {
1108             c->packet_buffer_ptr += len;
1109             if (c->packet_buffer_ptr >= c->packet_buffer_end) {
1110                 /* all the buffer was sent : wait for a new request */
1111                 av_freep(&c->packet_buffer);
1112                 c->state = RTSPSTATE_WAIT_REQUEST;
1113             }
1114         }
1115         break;
1116     case HTTPSTATE_READY:
1117         /* nothing to do */
1118         break;
1119     default:
1120         return -1;
1121     }
1122     return 0;
1123 }
1124
1125 static int extract_rates(char *rates, int ratelen, const char *request)
1126 {
1127     const char *p;
1128
1129     for (p = request; *p && *p != '\r' && *p != '\n'; ) {
1130         if (av_strncasecmp(p, "Pragma:", 7) == 0) {
1131             const char *q = p + 7;
1132
1133             while (*q && *q != '\n' && isspace(*q))
1134                 q++;
1135
1136             if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) {
1137                 int stream_no;
1138                 int rate_no;
1139
1140                 q += 20;
1141
1142                 memset(rates, 0xff, ratelen);
1143
1144                 while (1) {
1145                     while (*q && *q != '\n' && *q != ':')
1146                         q++;
1147
1148                     if (sscanf(q, ":%d:%d", &stream_no, &rate_no) != 2)
1149                         break;
1150
1151                     stream_no--;
1152                     if (stream_no < ratelen && stream_no >= 0)
1153                         rates[stream_no] = rate_no;
1154
1155                     while (*q && *q != '\n' && !isspace(*q))
1156                         q++;
1157                 }
1158
1159                 return 1;
1160             }
1161         }
1162         p = strchr(p, '\n');
1163         if (!p)
1164             break;
1165
1166         p++;
1167     }
1168
1169     return 0;
1170 }
1171
1172 static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate)
1173 {
1174     int i;
1175     int best_bitrate = 100000000;
1176     int best = -1;
1177
1178     for (i = 0; i < feed->nb_streams; i++) {
1179         AVCodecContext *feed_codec = feed->streams[i]->codec;
1180
1181         if (feed_codec->codec_id != codec->codec_id ||
1182             feed_codec->sample_rate != codec->sample_rate ||
1183             feed_codec->width != codec->width ||
1184             feed_codec->height != codec->height)
1185             continue;
1186
1187         /* Potential stream */
1188
1189         /* We want the fastest stream less than bit_rate, or the slowest
1190          * faster than bit_rate
1191          */
1192
1193         if (feed_codec->bit_rate <= bit_rate) {
1194             if (best_bitrate > bit_rate || feed_codec->bit_rate > best_bitrate) {
1195                 best_bitrate = feed_codec->bit_rate;
1196                 best = i;
1197             }
1198         } else {
1199             if (feed_codec->bit_rate < best_bitrate) {
1200                 best_bitrate = feed_codec->bit_rate;
1201                 best = i;
1202             }
1203         }
1204     }
1205
1206     return best;
1207 }
1208
1209 static int modify_current_stream(HTTPContext *c, char *rates)
1210 {
1211     int i;
1212     FFStream *req = c->stream;
1213     int action_required = 0;
1214
1215     /* Not much we can do for a feed */
1216     if (!req->feed)
1217         return 0;
1218
1219     for (i = 0; i < req->nb_streams; i++) {
1220         AVCodecContext *codec = req->streams[i]->codec;
1221
1222         switch(rates[i]) {
1223             case 0:
1224                 c->switch_feed_streams[i] = req->feed_streams[i];
1225                 break;
1226             case 1:
1227                 c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 2);
1228                 break;
1229             case 2:
1230                 /* Wants off or slow */
1231                 c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 4);
1232 #ifdef WANTS_OFF
1233                 /* This doesn't work well when it turns off the only stream! */
1234                 c->switch_feed_streams[i] = -2;
1235                 c->feed_streams[i] = -2;
1236 #endif
1237                 break;
1238         }
1239
1240         if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i])
1241             action_required = 1;
1242     }
1243
1244     return action_required;
1245 }
1246
1247 /* XXX: factorize in utils.c ? */
1248 /* XXX: take care with different space meaning */
1249 static void skip_spaces(const char **pp)
1250 {
1251     const char *p;
1252     p = *pp;
1253     while (*p == ' ' || *p == '\t')
1254         p++;
1255     *pp = p;
1256 }
1257
1258 static void get_word(char *buf, int buf_size, const char **pp)
1259 {
1260     const char *p;
1261     char *q;
1262
1263     p = *pp;
1264     skip_spaces(&p);
1265     q = buf;
1266     while (!isspace(*p) && *p != '\0') {
1267         if ((q - buf) < buf_size - 1)
1268             *q++ = *p;
1269         p++;
1270     }
1271     if (buf_size > 0)
1272         *q = '\0';
1273     *pp = p;
1274 }
1275
1276 static void get_arg(char *buf, int buf_size, const char **pp)
1277 {
1278     const char *p;
1279     char *q;
1280     int quote;
1281
1282     p = *pp;
1283     while (isspace(*p)) p++;
1284     q = buf;
1285     quote = 0;
1286     if (*p == '\"' || *p == '\'')
1287         quote = *p++;
1288     for(;;) {
1289         if (quote) {
1290             if (*p == quote)
1291                 break;
1292         } else {
1293             if (isspace(*p))
1294                 break;
1295         }
1296         if (*p == '\0')
1297             break;
1298         if ((q - buf) < buf_size - 1)
1299             *q++ = *p;
1300         p++;
1301     }
1302     *q = '\0';
1303     if (quote && *p == quote)
1304         p++;
1305     *pp = p;
1306 }
1307
1308 static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
1309                          const char *p, const char *filename, int line_num)
1310 {
1311     char arg[1024];
1312     IPAddressACL acl;
1313     int errors = 0;
1314
1315     get_arg(arg, sizeof(arg), &p);
1316     if (av_strcasecmp(arg, "allow") == 0)
1317         acl.action = IP_ALLOW;
1318     else if (av_strcasecmp(arg, "deny") == 0)
1319         acl.action = IP_DENY;
1320     else {
1321         fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
1322                 filename, line_num, arg);
1323         errors++;
1324     }
1325
1326     get_arg(arg, sizeof(arg), &p);
1327
1328     if (resolve_host(&acl.first, arg) != 0) {
1329         fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
1330                 filename, line_num, arg);
1331         errors++;
1332     } else
1333         acl.last = acl.first;
1334
1335     get_arg(arg, sizeof(arg), &p);
1336
1337     if (arg[0]) {
1338         if (resolve_host(&acl.last, arg) != 0) {
1339             fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
1340                     filename, line_num, arg);
1341             errors++;
1342         }
1343     }
1344
1345     if (!errors) {
1346         IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
1347         IPAddressACL **naclp = 0;
1348
1349         acl.next = 0;
1350         *nacl = acl;
1351
1352         if (stream)
1353             naclp = &stream->acl;
1354         else if (feed)
1355             naclp = &feed->acl;
1356         else if (ext_acl)
1357             naclp = &ext_acl;
1358         else {
1359             fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
1360                     filename, line_num);
1361             errors++;
1362         }
1363
1364         if (naclp) {
1365             while (*naclp)
1366                 naclp = &(*naclp)->next;
1367
1368             *naclp = nacl;
1369         }
1370     }
1371 }
1372
1373
1374 static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
1375 {
1376     FILE* f;
1377     char line[1024];
1378     char  cmd[1024];
1379     IPAddressACL *acl = NULL;
1380     int line_num = 0;
1381     const char *p;
1382
1383     f = fopen(stream->dynamic_acl, "r");
1384     if (!f) {
1385         perror(stream->dynamic_acl);
1386         return NULL;
1387     }
1388
1389     acl = av_mallocz(sizeof(IPAddressACL));
1390
1391     /* Build ACL */
1392     for(;;) {
1393         if (fgets(line, sizeof(line), f) == NULL)
1394             break;
1395         line_num++;
1396         p = line;
1397         while (isspace(*p))
1398             p++;
1399         if (*p == '\0' || *p == '#')
1400             continue;
1401         get_arg(cmd, sizeof(cmd), &p);
1402
1403         if (!av_strcasecmp(cmd, "ACL"))
1404             parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
1405     }
1406     fclose(f);
1407     return acl;
1408 }
1409
1410
1411 static void free_acl_list(IPAddressACL *in_acl)
1412 {
1413     IPAddressACL *pacl,*pacl2;
1414
1415     pacl = in_acl;
1416     while(pacl) {
1417         pacl2 = pacl;
1418         pacl = pacl->next;
1419         av_freep(pacl2);
1420     }
1421 }
1422
1423 static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)
1424 {
1425     enum IPAddressAction last_action = IP_DENY;
1426     IPAddressACL *acl;
1427     struct in_addr *src = &c->from_addr.sin_addr;
1428     unsigned long src_addr = src->s_addr;
1429
1430     for (acl = in_acl; acl; acl = acl->next) {
1431         if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr)
1432             return (acl->action == IP_ALLOW) ? 1 : 0;
1433         last_action = acl->action;
1434     }
1435
1436     /* Nothing matched, so return not the last action */
1437     return (last_action == IP_DENY) ? 1 : 0;
1438 }
1439
1440 static int validate_acl(FFStream *stream, HTTPContext *c)
1441 {
1442     int ret = 0;
1443     IPAddressACL *acl;
1444
1445
1446     /* if stream->acl is null validate_acl_list will return 1 */
1447     ret = validate_acl_list(stream->acl, c);
1448
1449     if (stream->dynamic_acl[0]) {
1450         acl = parse_dynamic_acl(stream, c);
1451
1452         ret = validate_acl_list(acl, c);
1453
1454         free_acl_list(acl);
1455     }
1456
1457     return ret;
1458 }
1459
1460 /* compute the real filename of a file by matching it without its
1461    extensions to all the stream filenames */
1462 static void compute_real_filename(char *filename, int max_size)
1463 {
1464     char file1[1024];
1465     char file2[1024];
1466     char *p;
1467     FFStream *stream;
1468
1469     /* compute filename by matching without the file extensions */
1470     av_strlcpy(file1, filename, sizeof(file1));
1471     p = strrchr(file1, '.');
1472     if (p)
1473         *p = '\0';
1474     for(stream = first_stream; stream != NULL; stream = stream->next) {
1475         av_strlcpy(file2, stream->filename, sizeof(file2));
1476         p = strrchr(file2, '.');
1477         if (p)
1478             *p = '\0';
1479         if (!strcmp(file1, file2)) {
1480             av_strlcpy(filename, stream->filename, max_size);
1481             break;
1482         }
1483     }
1484 }
1485
1486 enum RedirType {
1487     REDIR_NONE,
1488     REDIR_ASX,
1489     REDIR_RAM,
1490     REDIR_ASF,
1491     REDIR_RTSP,
1492     REDIR_SDP,
1493 };
1494
1495 /* parse http request and prepare header */
1496 static int http_parse_request(HTTPContext *c)
1497 {
1498     char *p;
1499     enum RedirType redir_type;
1500     char cmd[32];
1501     char info[1024], filename[1024];
1502     char url[1024], *q;
1503     char protocol[32];
1504     char msg[1024];
1505     const char *mime_type;
1506     FFStream *stream;
1507     int i;
1508     char ratebuf[32];
1509     char *useragent = 0;
1510
1511     p = c->buffer;
1512     get_word(cmd, sizeof(cmd), (const char **)&p);
1513     av_strlcpy(c->method, cmd, sizeof(c->method));
1514
1515     if (!strcmp(cmd, "GET"))
1516         c->post = 0;
1517     else if (!strcmp(cmd, "POST"))
1518         c->post = 1;
1519     else
1520         return -1;
1521
1522     get_word(url, sizeof(url), (const char **)&p);
1523     av_strlcpy(c->url, url, sizeof(c->url));
1524
1525     get_word(protocol, sizeof(protocol), (const char **)&p);
1526     if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
1527         return -1;
1528
1529     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
1530
1531     if (ffserver_debug)
1532         http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
1533
1534     /* find the filename and the optional info string in the request */
1535     p = strchr(url, '?');
1536     if (p) {
1537         av_strlcpy(info, p, sizeof(info));
1538         *p = '\0';
1539     } else
1540         info[0] = '\0';
1541
1542     av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
1543
1544     for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1545         if (av_strncasecmp(p, "User-Agent:", 11) == 0) {
1546             useragent = p + 11;
1547             if (*useragent && *useragent != '\n' && isspace(*useragent))
1548                 useragent++;
1549             break;
1550         }
1551         p = strchr(p, '\n');
1552         if (!p)
1553             break;
1554
1555         p++;
1556     }
1557
1558     redir_type = REDIR_NONE;
1559     if (av_match_ext(filename, "asx")) {
1560         redir_type = REDIR_ASX;
1561         filename[strlen(filename)-1] = 'f';
1562     } else if (av_match_ext(filename, "asf") &&
1563         (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) {
1564         /* if this isn't WMP or lookalike, return the redirector file */
1565         redir_type = REDIR_ASF;
1566     } else if (av_match_ext(filename, "rpm,ram")) {
1567         redir_type = REDIR_RAM;
1568         strcpy(filename + strlen(filename)-2, "m");
1569     } else if (av_match_ext(filename, "rtsp")) {
1570         redir_type = REDIR_RTSP;
1571         compute_real_filename(filename, sizeof(filename) - 1);
1572     } else if (av_match_ext(filename, "sdp")) {
1573         redir_type = REDIR_SDP;
1574         compute_real_filename(filename, sizeof(filename) - 1);
1575     }
1576
1577     // "redirect" / request to index.html
1578     if (!strlen(filename))
1579         av_strlcpy(filename, "index.html", sizeof(filename) - 1);
1580
1581     stream = first_stream;
1582     while (stream != NULL) {
1583         if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
1584             break;
1585         stream = stream->next;
1586     }
1587     if (stream == NULL) {
1588         snprintf(msg, sizeof(msg), "File '%s' not found", url);
1589         http_log("File '%s' not found\n", url);
1590         goto send_error;
1591     }
1592
1593     c->stream = stream;
1594     memcpy(c->feed_streams, stream->feed_streams, sizeof(c->feed_streams));
1595     memset(c->switch_feed_streams, -1, sizeof(c->switch_feed_streams));
1596
1597     if (stream->stream_type == STREAM_TYPE_REDIRECT) {
1598         c->http_error = 301;
1599         q = c->buffer;
1600         snprintf(q, c->buffer_size,
1601                       "HTTP/1.0 301 Moved\r\n"
1602                       "Location: %s\r\n"
1603                       "Content-type: text/html\r\n"
1604                       "\r\n"
1605                       "<html><head><title>Moved</title></head><body>\r\n"
1606                       "You should be <a href=\"%s\">redirected</a>.\r\n"
1607                       "</body></html>\r\n", stream->feed_filename, stream->feed_filename);
1608         q += strlen(q);
1609         /* prepare output buffer */
1610         c->buffer_ptr = c->buffer;
1611         c->buffer_end = q;
1612         c->state = HTTPSTATE_SEND_HEADER;
1613         return 0;
1614     }
1615
1616     /* If this is WMP, get the rate information */
1617     if (extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
1618         if (modify_current_stream(c, ratebuf)) {
1619             for (i = 0; i < FF_ARRAY_ELEMS(c->feed_streams); i++) {
1620                 if (c->switch_feed_streams[i] >= 0)
1621                     c->switch_feed_streams[i] = -1;
1622             }
1623         }
1624     }
1625
1626     if (c->post == 0 && stream->stream_type == STREAM_TYPE_LIVE)
1627         current_bandwidth += stream->bandwidth;
1628
1629     /* If already streaming this feed, do not let start another feeder. */
1630     if (stream->feed_opened) {
1631         snprintf(msg, sizeof(msg), "This feed is already being received.");
1632         http_log("Feed '%s' already being received\n", stream->feed_filename);
1633         goto send_error;
1634     }
1635
1636     if (c->post == 0 && max_bandwidth < current_bandwidth) {
1637         c->http_error = 503;
1638         q = c->buffer;
1639         snprintf(q, c->buffer_size,
1640                       "HTTP/1.0 503 Server too busy\r\n"
1641                       "Content-type: text/html\r\n"
1642                       "\r\n"
1643                       "<html><head><title>Too busy</title></head><body>\r\n"
1644                       "<p>The server is too busy to serve your request at this time.</p>\r\n"
1645                       "<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, "
1646                       "and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n"
1647                       "</body></html>\r\n", current_bandwidth, max_bandwidth);
1648         q += strlen(q);
1649         /* prepare output buffer */
1650         c->buffer_ptr = c->buffer;
1651         c->buffer_end = q;
1652         c->state = HTTPSTATE_SEND_HEADER;
1653         return 0;
1654     }
1655
1656     if (redir_type != REDIR_NONE) {
1657         char *hostinfo = 0;
1658
1659         for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1660             if (av_strncasecmp(p, "Host:", 5) == 0) {
1661                 hostinfo = p + 5;
1662                 break;
1663             }
1664             p = strchr(p, '\n');
1665             if (!p)
1666                 break;
1667
1668             p++;
1669         }
1670
1671         if (hostinfo) {
1672             char *eoh;
1673             char hostbuf[260];
1674
1675             while (isspace(*hostinfo))
1676                 hostinfo++;
1677
1678             eoh = strchr(hostinfo, '\n');
1679             if (eoh) {
1680                 if (eoh[-1] == '\r')
1681                     eoh--;
1682
1683                 if (eoh - hostinfo < sizeof(hostbuf) - 1) {
1684                     memcpy(hostbuf, hostinfo, eoh - hostinfo);
1685                     hostbuf[eoh - hostinfo] = 0;
1686
1687                     c->http_error = 200;
1688                     q = c->buffer;
1689                     switch(redir_type) {
1690                     case REDIR_ASX:
1691                         snprintf(q, c->buffer_size,
1692                                       "HTTP/1.0 200 ASX Follows\r\n"
1693                                       "Content-type: video/x-ms-asf\r\n"
1694                                       "\r\n"
1695                                       "<ASX Version=\"3\">\r\n"
1696                                       //"<!-- Autogenerated by ffserver -->\r\n"
1697                                       "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n"
1698                                       "</ASX>\r\n", hostbuf, filename, info);
1699                         q += strlen(q);
1700                         break;
1701                     case REDIR_RAM:
1702                         snprintf(q, c->buffer_size,
1703                                       "HTTP/1.0 200 RAM Follows\r\n"
1704                                       "Content-type: audio/x-pn-realaudio\r\n"
1705                                       "\r\n"
1706                                       "# Autogenerated by ffserver\r\n"
1707                                       "http://%s/%s%s\r\n", hostbuf, filename, info);
1708                         q += strlen(q);
1709                         break;
1710                     case REDIR_ASF:
1711                         snprintf(q, c->buffer_size,
1712                                       "HTTP/1.0 200 ASF Redirect follows\r\n"
1713                                       "Content-type: video/x-ms-asf\r\n"
1714                                       "\r\n"
1715                                       "[Reference]\r\n"
1716                                       "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info);
1717                         q += strlen(q);
1718                         break;
1719                     case REDIR_RTSP:
1720                         {
1721                             char hostname[256], *p;
1722                             /* extract only hostname */
1723                             av_strlcpy(hostname, hostbuf, sizeof(hostname));
1724                             p = strrchr(hostname, ':');
1725                             if (p)
1726                                 *p = '\0';
1727                             snprintf(q, c->buffer_size,
1728                                           "HTTP/1.0 200 RTSP Redirect follows\r\n"
1729                                           /* XXX: incorrect mime type ? */
1730                                           "Content-type: application/x-rtsp\r\n"
1731                                           "\r\n"
1732                                           "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename);
1733                             q += strlen(q);
1734                         }
1735                         break;
1736                     case REDIR_SDP:
1737                         {
1738                             uint8_t *sdp_data;
1739                             int sdp_data_size, len;
1740                             struct sockaddr_in my_addr;
1741
1742                             snprintf(q, c->buffer_size,
1743                                           "HTTP/1.0 200 OK\r\n"
1744                                           "Content-type: application/sdp\r\n"
1745                                           "\r\n");
1746                             q += strlen(q);
1747
1748                             len = sizeof(my_addr);
1749                             getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
1750
1751                             /* XXX: should use a dynamic buffer */
1752                             sdp_data_size = prepare_sdp_description(stream,
1753                                                                     &sdp_data,
1754                                                                     my_addr.sin_addr);
1755                             if (sdp_data_size > 0) {
1756                                 memcpy(q, sdp_data, sdp_data_size);
1757                                 q += sdp_data_size;
1758                                 *q = '\0';
1759                                 av_free(sdp_data);
1760                             }
1761                         }
1762                         break;
1763                     default:
1764                         abort();
1765                         break;
1766                     }
1767
1768                     /* prepare output buffer */
1769                     c->buffer_ptr = c->buffer;
1770                     c->buffer_end = q;
1771                     c->state = HTTPSTATE_SEND_HEADER;
1772                     return 0;
1773                 }
1774             }
1775         }
1776
1777         snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
1778         goto send_error;
1779     }
1780
1781     stream->conns_served++;
1782
1783     /* XXX: add there authenticate and IP match */
1784
1785     if (c->post) {
1786         /* if post, it means a feed is being sent */
1787         if (!stream->is_feed) {
1788             /* However it might be a status report from WMP! Let us log the
1789              * data as it might come in handy one day. */
1790             char *logline = 0;
1791             int client_id = 0;
1792
1793             for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1794                 if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) {
1795                     logline = p;
1796                     break;
1797                 }
1798                 if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0)
1799                     client_id = strtol(p + 18, 0, 10);
1800                 p = strchr(p, '\n');
1801                 if (!p)
1802                     break;
1803
1804                 p++;
1805             }
1806
1807             if (logline) {
1808                 char *eol = strchr(logline, '\n');
1809
1810                 logline += 17;
1811
1812                 if (eol) {
1813                     if (eol[-1] == '\r')
1814                         eol--;
1815                     http_log("%.*s\n", (int) (eol - logline), logline);
1816                     c->suppress_log = 1;
1817                 }
1818             }
1819
1820 #ifdef DEBUG
1821             http_log("\nGot request:\n%s\n", c->buffer);
1822 #endif
1823
1824             if (client_id && extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
1825                 HTTPContext *wmpc;
1826
1827                 /* Now we have to find the client_id */
1828                 for (wmpc = first_http_ctx; wmpc; wmpc = wmpc->next) {
1829                     if (wmpc->wmp_client_id == client_id)
1830                         break;
1831                 }
1832
1833                 if (wmpc && modify_current_stream(wmpc, ratebuf))
1834                     wmpc->switch_pending = 1;
1835             }
1836
1837             snprintf(msg, sizeof(msg), "POST command not handled");
1838             c->stream = 0;
1839             goto send_error;
1840         }
1841         if (http_start_receive_data(c) < 0) {
1842             snprintf(msg, sizeof(msg), "could not open feed");
1843             goto send_error;
1844         }
1845         c->http_error = 0;
1846         c->state = HTTPSTATE_RECEIVE_DATA;
1847         return 0;
1848     }
1849
1850 #ifdef DEBUG
1851     if (strcmp(stream->filename + strlen(stream->filename) - 4, ".asf") == 0)
1852         http_log("\nGot request:\n%s\n", c->buffer);
1853 #endif
1854
1855     if (c->stream->stream_type == STREAM_TYPE_STATUS)
1856         goto send_status;
1857
1858     /* open input stream */
1859     if (open_input_stream(c, info) < 0) {
1860         snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
1861         goto send_error;
1862     }
1863
1864     /* prepare http header */
1865     c->buffer[0] = 0;
1866     av_strlcatf(c->buffer, c->buffer_size, "HTTP/1.0 200 OK\r\n");
1867     mime_type = c->stream->fmt->mime_type;
1868     if (!mime_type)
1869         mime_type = "application/x-octet-stream";
1870     av_strlcatf(c->buffer, c->buffer_size, "Pragma: no-cache\r\n");
1871
1872     /* for asf, we need extra headers */
1873     if (!strcmp(c->stream->fmt->name,"asf_stream")) {
1874         /* Need to allocate a client id */
1875
1876         c->wmp_client_id = av_lfg_get(&random_state);
1877
1878         av_strlcatf(c->buffer, c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id);
1879     }
1880     av_strlcatf(c->buffer, c->buffer_size, "Content-Type: %s\r\n", mime_type);
1881     av_strlcatf(c->buffer, c->buffer_size, "\r\n");
1882     q = c->buffer + strlen(c->buffer);
1883
1884     /* prepare output buffer */
1885     c->http_error = 0;
1886     c->buffer_ptr = c->buffer;
1887     c->buffer_end = q;
1888     c->state = HTTPSTATE_SEND_HEADER;
1889     return 0;
1890  send_error:
1891     c->http_error = 404;
1892     q = c->buffer;
1893     snprintf(q, c->buffer_size,
1894                   "HTTP/1.0 404 Not Found\r\n"
1895                   "Content-type: text/html\r\n"
1896                   "\r\n"
1897                   "<html>\n"
1898                   "<head><title>404 Not Found</title></head>\n"
1899                   "<body>%s</body>\n"
1900                   "</html>\n", msg);
1901     q += strlen(q);
1902     /* prepare output buffer */
1903     c->buffer_ptr = c->buffer;
1904     c->buffer_end = q;
1905     c->state = HTTPSTATE_SEND_HEADER;
1906     return 0;
1907  send_status:
1908     compute_status(c);
1909     c->http_error = 200; /* horrible : we use this value to avoid
1910                             going to the send data state */
1911     c->state = HTTPSTATE_SEND_HEADER;
1912     return 0;
1913 }
1914
1915 static void fmt_bytecount(AVIOContext *pb, int64_t count)
1916 {
1917     static const char suffix[] = " kMGTP";
1918     const char *s;
1919
1920     for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++);
1921
1922     avio_printf(pb, "%"PRId64"%c", count, *s);
1923 }
1924
1925 static void compute_status(HTTPContext *c)
1926 {
1927     HTTPContext *c1;
1928     FFStream *stream;
1929     char *p;
1930     time_t ti;
1931     int i, len;
1932     AVIOContext *pb;
1933
1934     if (avio_open_dyn_buf(&pb) < 0) {
1935         /* XXX: return an error ? */
1936         c->buffer_ptr = c->buffer;
1937         c->buffer_end = c->buffer;
1938         return;
1939     }
1940
1941     avio_printf(pb, "HTTP/1.0 200 OK\r\n");
1942     avio_printf(pb, "Content-type: %s\r\n", "text/html");
1943     avio_printf(pb, "Pragma: no-cache\r\n");
1944     avio_printf(pb, "\r\n");
1945
1946     avio_printf(pb, "<html><head><title>%s Status</title>\n", program_name);
1947     if (c->stream->feed_filename[0])
1948         avio_printf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
1949     avio_printf(pb, "</head>\n<body>");
1950     avio_printf(pb, "<h1>%s Status</h1>\n", program_name);
1951     /* format status */
1952     avio_printf(pb, "<h2>Available Streams</h2>\n");
1953     avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
1954     avio_printf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<th valign=top>Format<th>Bit rate<br>kbits/s<th align=left>Video<br>kbits/s<th><br>Codec<th align=left>Audio<br>kbits/s<th><br>Codec<th align=left valign=top>Feed\n");
1955     stream = first_stream;
1956     while (stream != NULL) {
1957         char sfilename[1024];
1958         char *eosf;
1959
1960         if (stream->feed != stream) {
1961             av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);
1962             eosf = sfilename + strlen(sfilename);
1963             if (eosf - sfilename >= 4) {
1964                 if (strcmp(eosf - 4, ".asf") == 0)
1965                     strcpy(eosf - 4, ".asx");
1966                 else if (strcmp(eosf - 3, ".rm") == 0)
1967                     strcpy(eosf - 3, ".ram");
1968                 else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
1969                     /* generate a sample RTSP director if
1970                        unicast. Generate an SDP redirector if
1971                        multicast */
1972                     eosf = strrchr(sfilename, '.');
1973                     if (!eosf)
1974                         eosf = sfilename + strlen(sfilename);
1975                     if (stream->is_multicast)
1976                         strcpy(eosf, ".sdp");
1977                     else
1978                         strcpy(eosf, ".rtsp");
1979                 }
1980             }
1981
1982             avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
1983                          sfilename, stream->filename);
1984             avio_printf(pb, "<td align=right> %d <td align=right> ",
1985                         stream->conns_served);
1986             fmt_bytecount(pb, stream->bytes_served);
1987             switch(stream->stream_type) {
1988             case STREAM_TYPE_LIVE: {
1989                     int audio_bit_rate = 0;
1990                     int video_bit_rate = 0;
1991                     const char *audio_codec_name = "";
1992                     const char *video_codec_name = "";
1993                     const char *audio_codec_name_extra = "";
1994                     const char *video_codec_name_extra = "";
1995
1996                     for(i=0;i<stream->nb_streams;i++) {
1997                         AVStream *st = stream->streams[i];
1998                         AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
1999                         switch(st->codec->codec_type) {
2000                         case AVMEDIA_TYPE_AUDIO:
2001                             audio_bit_rate += st->codec->bit_rate;
2002                             if (codec) {
2003                                 if (*audio_codec_name)
2004                                     audio_codec_name_extra = "...";
2005                                 audio_codec_name = codec->name;
2006                             }
2007                             break;
2008                         case AVMEDIA_TYPE_VIDEO:
2009                             video_bit_rate += st->codec->bit_rate;
2010                             if (codec) {
2011                                 if (*video_codec_name)
2012                                     video_codec_name_extra = "...";
2013                                 video_codec_name = codec->name;
2014                             }
2015                             break;
2016                         case AVMEDIA_TYPE_DATA:
2017                             video_bit_rate += st->codec->bit_rate;
2018                             break;
2019                         default:
2020                             abort();
2021                         }
2022                     }
2023                     avio_printf(pb, "<td align=center> %s <td align=right> %d <td align=right> %d <td> %s %s <td align=right> %d <td> %s %s",
2024                                  stream->fmt->name,
2025                                  stream->bandwidth,
2026                                  video_bit_rate / 1000, video_codec_name, video_codec_name_extra,
2027                                  audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra);
2028                     if (stream->feed)
2029                         avio_printf(pb, "<td>%s", stream->feed->filename);
2030                     else
2031                         avio_printf(pb, "<td>%s", stream->feed_filename);
2032                     avio_printf(pb, "\n");
2033                 }
2034                 break;
2035             default:
2036                 avio_printf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
2037                 break;
2038             }
2039         }
2040         stream = stream->next;
2041     }
2042     avio_printf(pb, "</table>\n");
2043
2044     stream = first_stream;
2045     while (stream != NULL) {
2046         if (stream->feed == stream) {
2047             avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
2048             if (stream->pid) {
2049                 avio_printf(pb, "Running as pid %d.\n", stream->pid);
2050
2051 #if defined(linux) && !defined(CONFIG_NOCUTILS)
2052                 {
2053                     FILE *pid_stat;
2054                     char ps_cmd[64];
2055
2056                     /* This is somewhat linux specific I guess */
2057                     snprintf(ps_cmd, sizeof(ps_cmd),
2058                              "ps -o \"%%cpu,cputime\" --no-headers %d",
2059                              stream->pid);
2060
2061                     pid_stat = popen(ps_cmd, "r");
2062                     if (pid_stat) {
2063                         char cpuperc[10];
2064                         char cpuused[64];
2065
2066                         if (fscanf(pid_stat, "%9s %63s", cpuperc,
2067                                    cpuused) == 2) {
2068                             avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
2069                                          cpuperc, cpuused);
2070                         }
2071                         fclose(pid_stat);
2072                     }
2073                 }
2074 #endif
2075
2076                 avio_printf(pb, "<p>");
2077             }
2078             avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>type<th>kbits/s<th align=left>codec<th align=left>Parameters\n");
2079
2080             for (i = 0; i < stream->nb_streams; i++) {
2081                 AVStream *st = stream->streams[i];
2082                 AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
2083                 const char *type = "unknown";
2084                 char parameters[64];
2085
2086                 parameters[0] = 0;
2087
2088                 switch(st->codec->codec_type) {
2089                 case AVMEDIA_TYPE_AUDIO:
2090                     type = "audio";
2091                     snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate);
2092                     break;
2093                 case AVMEDIA_TYPE_VIDEO:
2094                     type = "video";
2095                     snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height,
2096                                 st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);
2097                     break;
2098                 default:
2099                     abort();
2100                 }
2101                 avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n",
2102                         i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);
2103             }
2104             avio_printf(pb, "</table>\n");
2105
2106         }
2107         stream = stream->next;
2108     }
2109
2110     /* connection status */
2111     avio_printf(pb, "<h2>Connection Status</h2>\n");
2112
2113     avio_printf(pb, "Number of connections: %d / %d<br>\n",
2114                  nb_connections, nb_max_connections);
2115
2116     avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
2117                  current_bandwidth, max_bandwidth);
2118
2119     avio_printf(pb, "<table>\n");
2120     avio_printf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target bits/sec<th>Actual bits/sec<th>Bytes transferred\n");
2121     c1 = first_http_ctx;
2122     i = 0;
2123     while (c1 != NULL) {
2124         int bitrate;
2125         int j;
2126
2127         bitrate = 0;
2128         if (c1->stream) {
2129             for (j = 0; j < c1->stream->nb_streams; j++) {
2130                 if (!c1->stream->feed)
2131                     bitrate += c1->stream->streams[j]->codec->bit_rate;
2132                 else if (c1->feed_streams[j] >= 0)
2133                     bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;
2134             }
2135         }
2136
2137         i++;
2138         p = inet_ntoa(c1->from_addr.sin_addr);
2139         avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>",
2140                     i,
2141                     c1->stream ? c1->stream->filename : "",
2142                     c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",
2143                     p,
2144                     c1->protocol,
2145                     http_state[c1->state]);
2146         fmt_bytecount(pb, bitrate);
2147         avio_printf(pb, "<td align=right>");
2148         fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
2149         avio_printf(pb, "<td align=right>");
2150         fmt_bytecount(pb, c1->data_count);
2151         avio_printf(pb, "\n");
2152         c1 = c1->next;
2153     }
2154     avio_printf(pb, "</table>\n");
2155
2156     /* date */
2157     ti = time(NULL);
2158     p = ctime(&ti);
2159     avio_printf(pb, "<hr size=1 noshade>Generated at %s", p);
2160     avio_printf(pb, "</body>\n</html>\n");
2161
2162     len = avio_close_dyn_buf(pb, &c->pb_buffer);
2163     c->buffer_ptr = c->pb_buffer;
2164     c->buffer_end = c->pb_buffer + len;
2165 }
2166
2167 static int open_input_stream(HTTPContext *c, const char *info)
2168 {
2169     char buf[128];
2170     char input_filename[1024];
2171     AVFormatContext *s = NULL;
2172     int buf_size, i, ret;
2173     int64_t stream_pos;
2174
2175     /* find file name */
2176     if (c->stream->feed) {
2177         strcpy(input_filename, c->stream->feed->feed_filename);
2178         buf_size = FFM_PACKET_SIZE;
2179         /* compute position (absolute time) */
2180         if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
2181             if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0)
2182                 return ret;
2183         } else if (av_find_info_tag(buf, sizeof(buf), "buffer", info)) {
2184             int prebuffer = strtol(buf, 0, 10);
2185             stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
2186         } else
2187             stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000;
2188     } else {
2189         strcpy(input_filename, c->stream->feed_filename);
2190         buf_size = 0;
2191         /* compute position (relative time) */
2192         if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
2193             if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0)
2194                 return ret;
2195         } else
2196             stream_pos = 0;
2197     }
2198     if (input_filename[0] == '\0')
2199         return -1;
2200
2201     /* open stream */
2202     if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) {
2203         http_log("could not open %s: %d\n", input_filename, ret);
2204         return -1;
2205     }
2206
2207     /* set buffer size */
2208     if (buf_size > 0) ffio_set_buf_size(s->pb, buf_size);
2209
2210     s->flags |= AVFMT_FLAG_GENPTS;
2211     c->fmt_in = s;
2212     if (strcmp(s->iformat->name, "ffm") && avformat_find_stream_info(c->fmt_in, NULL) < 0) {
2213         http_log("Could not find stream info '%s'\n", input_filename);
2214         avformat_close_input(&s);
2215         return -1;
2216     }
2217
2218     /* choose stream as clock source (we favorize video stream if
2219        present) for packet sending */
2220     c->pts_stream_index = 0;
2221     for(i=0;i<c->stream->nb_streams;i++) {
2222         if (c->pts_stream_index == 0 &&
2223             c->stream->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
2224             c->pts_stream_index = i;
2225         }
2226     }
2227
2228     if (c->fmt_in->iformat->read_seek)
2229         av_seek_frame(c->fmt_in, -1, stream_pos, 0);
2230     /* set the start time (needed for maxtime and RTP packet timing) */
2231     c->start_time = cur_time;
2232     c->first_pts = AV_NOPTS_VALUE;
2233     return 0;
2234 }
2235
2236 /* return the server clock (in us) */
2237 static int64_t get_server_clock(HTTPContext *c)
2238 {
2239     /* compute current pts value from system time */
2240     return (cur_time - c->start_time) * 1000;
2241 }
2242
2243 /* return the estimated time at which the current packet must be sent
2244    (in us) */
2245 static int64_t get_packet_send_clock(HTTPContext *c)
2246 {
2247     int bytes_left, bytes_sent, frame_bytes;
2248
2249     frame_bytes = c->cur_frame_bytes;
2250     if (frame_bytes <= 0)
2251         return c->cur_pts;
2252     else {
2253         bytes_left = c->buffer_end - c->buffer_ptr;
2254         bytes_sent = frame_bytes - bytes_left;
2255         return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
2256     }
2257 }
2258
2259
2260 static int http_prepare_data(HTTPContext *c)
2261 {
2262     int i, len, ret;
2263     AVFormatContext *ctx;
2264
2265     av_freep(&c->pb_buffer);
2266     switch(c->state) {
2267     case HTTPSTATE_SEND_DATA_HEADER:
2268         memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
2269         av_dict_set(&c->fmt_ctx.metadata, "author"   , c->stream->author   , 0);
2270         av_dict_set(&c->fmt_ctx.metadata, "comment"  , c->stream->comment  , 0);
2271         av_dict_set(&c->fmt_ctx.metadata, "copyright", c->stream->copyright, 0);
2272         av_dict_set(&c->fmt_ctx.metadata, "title"    , c->stream->title    , 0);
2273
2274         c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
2275
2276         for(i=0;i<c->stream->nb_streams;i++) {
2277             AVStream *src;
2278             c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
2279             /* if file or feed, then just take streams from FFStream struct */
2280             if (!c->stream->feed ||
2281                 c->stream->feed == c->stream)
2282                 src = c->stream->streams[i];
2283             else
2284                 src = c->stream->feed->streams[c->stream->feed_streams[i]];
2285
2286             *(c->fmt_ctx.streams[i]) = *src;
2287             c->fmt_ctx.streams[i]->priv_data = 0;
2288             c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in
2289                                            AVStream, not in codec */
2290         }
2291         /* set output format parameters */
2292         c->fmt_ctx.oformat = c->stream->fmt;
2293         c->fmt_ctx.nb_streams = c->stream->nb_streams;
2294
2295         c->got_key_frame = 0;
2296
2297         /* prepare header and save header data in a stream */
2298         if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
2299             /* XXX: potential leak */
2300             return -1;
2301         }
2302         c->fmt_ctx.pb->seekable = 0;
2303
2304         /*
2305          * HACK to avoid mpeg ps muxer to spit many underflow errors
2306          * Default value from FFmpeg
2307          * Try to set it use configuration option
2308          */
2309         c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
2310
2311         if (avformat_write_header(&c->fmt_ctx, NULL) < 0) {
2312             http_log("Error writing output header\n");
2313             return -1;
2314         }
2315         av_dict_free(&c->fmt_ctx.metadata);
2316
2317         len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
2318         c->buffer_ptr = c->pb_buffer;
2319         c->buffer_end = c->pb_buffer + len;
2320
2321         c->state = HTTPSTATE_SEND_DATA;
2322         c->last_packet_sent = 0;
2323         break;
2324     case HTTPSTATE_SEND_DATA:
2325         /* find a new packet */
2326         /* read a packet from the input stream */
2327         if (c->stream->feed)
2328             ffm_set_write_index(c->fmt_in,
2329                                 c->stream->feed->feed_write_index,
2330                                 c->stream->feed->feed_size);
2331
2332         if (c->stream->max_time &&
2333             c->stream->max_time + c->start_time - cur_time < 0)
2334             /* We have timed out */
2335             c->state = HTTPSTATE_SEND_DATA_TRAILER;
2336         else {
2337             AVPacket pkt;
2338         redo:
2339             ret = av_read_frame(c->fmt_in, &pkt);
2340             if (ret < 0) {
2341                 if (c->stream->feed) {
2342                     /* if coming from feed, it means we reached the end of the
2343                        ffm file, so must wait for more data */
2344                     c->state = HTTPSTATE_WAIT_FEED;
2345                     return 1; /* state changed */
2346                 } else if (ret == AVERROR(EAGAIN)) {
2347                     /* input not ready, come back later */
2348                     return 0;
2349                 } else {
2350                     if (c->stream->loop) {
2351                         avformat_close_input(&c->fmt_in);
2352                         if (open_input_stream(c, "") < 0)
2353                             goto no_loop;
2354                         goto redo;
2355                     } else {
2356                     no_loop:
2357                         /* must send trailer now because eof or error */
2358                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2359                     }
2360                 }
2361             } else {
2362                 int source_index = pkt.stream_index;
2363                 /* update first pts if needed */
2364                 if (c->first_pts == AV_NOPTS_VALUE) {
2365                     c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
2366                     c->start_time = cur_time;
2367                 }
2368                 /* send it to the appropriate stream */
2369                 if (c->stream->feed) {
2370                     /* if coming from a feed, select the right stream */
2371                     if (c->switch_pending) {
2372                         c->switch_pending = 0;
2373                         for(i=0;i<c->stream->nb_streams;i++) {
2374                             if (c->switch_feed_streams[i] == pkt.stream_index)
2375                                 if (pkt.flags & AV_PKT_FLAG_KEY)
2376                                     c->switch_feed_streams[i] = -1;
2377                             if (c->switch_feed_streams[i] >= 0)
2378                                 c->switch_pending = 1;
2379                         }
2380                     }
2381                     for(i=0;i<c->stream->nb_streams;i++) {
2382                         if (c->stream->feed_streams[i] == pkt.stream_index) {
2383                             AVStream *st = c->fmt_in->streams[source_index];
2384                             pkt.stream_index = i;
2385                             if (pkt.flags & AV_PKT_FLAG_KEY &&
2386                                 (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
2387                                  c->stream->nb_streams == 1))
2388                                 c->got_key_frame = 1;
2389                             if (!c->stream->send_on_key || c->got_key_frame)
2390                                 goto send_it;
2391                         }
2392                     }
2393                 } else {
2394                     AVCodecContext *codec;
2395                     AVStream *ist, *ost;
2396                 send_it:
2397                     ist = c->fmt_in->streams[source_index];
2398                     /* specific handling for RTP: we use several
2399                        output stream (one for each RTP
2400                        connection). XXX: need more abstract handling */
2401                     if (c->is_packetized) {
2402                         /* compute send time and duration */
2403                         c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
2404                         c->cur_pts -= c->first_pts;
2405                         c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
2406                         /* find RTP context */
2407                         c->packet_stream_index = pkt.stream_index;
2408                         ctx = c->rtp_ctx[c->packet_stream_index];
2409                         if(!ctx) {
2410                             av_free_packet(&pkt);
2411                             break;
2412                         }
2413                         codec = ctx->streams[0]->codec;
2414                         /* only one stream per RTP connection */
2415                         pkt.stream_index = 0;
2416                     } else {
2417                         ctx = &c->fmt_ctx;
2418                         /* Fudge here */
2419                         codec = ctx->streams[pkt.stream_index]->codec;
2420                     }
2421
2422                     if (c->is_packetized) {
2423                         int max_packet_size;
2424                         if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
2425                             max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
2426                         else
2427                             max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
2428                         ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size);
2429                     } else {
2430                         ret = avio_open_dyn_buf(&ctx->pb);
2431                     }
2432                     if (ret < 0) {
2433                         /* XXX: potential leak */
2434                         return -1;
2435                     }
2436                     ost = ctx->streams[pkt.stream_index];
2437
2438                     ctx->pb->seekable = 0;
2439                     if (pkt.dts != AV_NOPTS_VALUE)
2440                         pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base);
2441                     if (pkt.pts != AV_NOPTS_VALUE)
2442                         pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base);
2443                     pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base);
2444                     if (av_write_frame(ctx, &pkt) < 0) {
2445                         http_log("Error writing frame to output\n");
2446                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2447                     }
2448
2449                     len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2450                     c->cur_frame_bytes = len;
2451                     c->buffer_ptr = c->pb_buffer;
2452                     c->buffer_end = c->pb_buffer + len;
2453
2454                     codec->frame_number++;
2455                     if (len == 0) {
2456                         av_free_packet(&pkt);
2457                         goto redo;
2458                     }
2459                 }
2460                 av_free_packet(&pkt);
2461             }
2462         }
2463         break;
2464     default:
2465     case HTTPSTATE_SEND_DATA_TRAILER:
2466         /* last packet test ? */
2467         if (c->last_packet_sent || c->is_packetized)
2468             return -1;
2469         ctx = &c->fmt_ctx;
2470         /* prepare header */
2471         if (avio_open_dyn_buf(&ctx->pb) < 0) {
2472             /* XXX: potential leak */
2473             return -1;
2474         }
2475         c->fmt_ctx.pb->seekable = 0;
2476         av_write_trailer(ctx);
2477         len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2478         c->buffer_ptr = c->pb_buffer;
2479         c->buffer_end = c->pb_buffer + len;
2480
2481         c->last_packet_sent = 1;
2482         break;
2483     }
2484     return 0;
2485 }
2486
2487 /* should convert the format at the same time */
2488 /* send data starting at c->buffer_ptr to the output connection
2489    (either UDP or TCP connection) */
2490 static int http_send_data(HTTPContext *c)
2491 {
2492     int len, ret;
2493
2494     for(;;) {
2495         if (c->buffer_ptr >= c->buffer_end) {
2496             ret = http_prepare_data(c);
2497             if (ret < 0)
2498                 return -1;
2499             else if (ret != 0)
2500                 /* state change requested */
2501                 break;
2502         } else {
2503             if (c->is_packetized) {
2504                 /* RTP data output */
2505                 len = c->buffer_end - c->buffer_ptr;
2506                 if (len < 4) {
2507                     /* fail safe - should never happen */
2508                 fail1:
2509                     c->buffer_ptr = c->buffer_end;
2510                     return 0;
2511                 }
2512                 len = (c->buffer_ptr[0] << 24) |
2513                     (c->buffer_ptr[1] << 16) |
2514                     (c->buffer_ptr[2] << 8) |
2515                     (c->buffer_ptr[3]);
2516                 if (len > (c->buffer_end - c->buffer_ptr))
2517                     goto fail1;
2518                 if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
2519                     /* nothing to send yet: we can wait */
2520                     return 0;
2521                 }
2522
2523                 c->data_count += len;
2524                 update_datarate(&c->datarate, c->data_count);
2525                 if (c->stream)
2526                     c->stream->bytes_served += len;
2527
2528                 if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
2529                     /* RTP packets are sent inside the RTSP TCP connection */
2530                     AVIOContext *pb;
2531                     int interleaved_index, size;
2532                     uint8_t header[4];
2533                     HTTPContext *rtsp_c;
2534
2535                     rtsp_c = c->rtsp_c;
2536                     /* if no RTSP connection left, error */
2537                     if (!rtsp_c)
2538                         return -1;
2539                     /* if already sending something, then wait. */
2540                     if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
2541                         break;
2542                     if (avio_open_dyn_buf(&pb) < 0)
2543                         goto fail1;
2544                     interleaved_index = c->packet_stream_index * 2;
2545                     /* RTCP packets are sent at odd indexes */
2546                     if (c->buffer_ptr[1] == 200)
2547                         interleaved_index++;
2548                     /* write RTSP TCP header */
2549                     header[0] = '$';
2550                     header[1] = interleaved_index;
2551                     header[2] = len >> 8;
2552                     header[3] = len;
2553                     avio_write(pb, header, 4);
2554                     /* write RTP packet data */
2555                     c->buffer_ptr += 4;
2556                     avio_write(pb, c->buffer_ptr, len);
2557                     size = avio_close_dyn_buf(pb, &c->packet_buffer);
2558                     /* prepare asynchronous TCP sending */
2559                     rtsp_c->packet_buffer_ptr = c->packet_buffer;
2560                     rtsp_c->packet_buffer_end = c->packet_buffer + size;
2561                     c->buffer_ptr += len;
2562
2563                     /* send everything we can NOW */
2564                     len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
2565                                 rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
2566                     if (len > 0)
2567                         rtsp_c->packet_buffer_ptr += len;
2568                     if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
2569                         /* if we could not send all the data, we will
2570                            send it later, so a new state is needed to
2571                            "lock" the RTSP TCP connection */
2572                         rtsp_c->state = RTSPSTATE_SEND_PACKET;
2573                         break;
2574                     } else
2575                         /* all data has been sent */
2576                         av_freep(&c->packet_buffer);
2577                 } else {
2578                     /* send RTP packet directly in UDP */
2579                     c->buffer_ptr += 4;
2580                     ffurl_write(c->rtp_handles[c->packet_stream_index],
2581                                 c->buffer_ptr, len);
2582                     c->buffer_ptr += len;
2583                     /* here we continue as we can send several packets per 10 ms slot */
2584                 }
2585             } else {
2586                 /* TCP data output */
2587                 len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
2588                 if (len < 0) {
2589                     if (ff_neterrno() != AVERROR(EAGAIN) &&
2590                         ff_neterrno() != AVERROR(EINTR))
2591                         /* error : close connection */
2592                         return -1;
2593                     else
2594                         return 0;
2595                 } else
2596                     c->buffer_ptr += len;
2597
2598                 c->data_count += len;
2599                 update_datarate(&c->datarate, c->data_count);
2600                 if (c->stream)
2601                     c->stream->bytes_served += len;
2602                 break;
2603             }
2604         }
2605     } /* for(;;) */
2606     return 0;
2607 }
2608
2609 static int http_start_receive_data(HTTPContext *c)
2610 {
2611     int fd;
2612
2613     if (c->stream->feed_opened)
2614         return -1;
2615
2616     /* Don't permit writing to this one */
2617     if (c->stream->readonly)
2618         return -1;
2619
2620     /* open feed */
2621     fd = open(c->stream->feed_filename, O_RDWR);
2622     if (fd < 0) {
2623         http_log("Error opening feeder file: %s\n", strerror(errno));
2624         return -1;
2625     }
2626     c->feed_fd = fd;
2627
2628     if (c->stream->truncate) {
2629         /* truncate feed file */
2630         ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
2631         http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
2632         if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
2633             http_log("Error truncating feed file: %s\n", strerror(errno));
2634             return -1;
2635         }
2636     } else {
2637         if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) {
2638             http_log("Error reading write index from feed file: %s\n", strerror(errno));
2639             return -1;
2640         }
2641     }
2642
2643     c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
2644     c->stream->feed_size = lseek(fd, 0, SEEK_END);
2645     lseek(fd, 0, SEEK_SET);
2646
2647     /* init buffer input */
2648     c->buffer_ptr = c->buffer;
2649     c->buffer_end = c->buffer + FFM_PACKET_SIZE;
2650     c->stream->feed_opened = 1;
2651     c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
2652     return 0;
2653 }
2654
2655 static int http_receive_data(HTTPContext *c)
2656 {
2657     HTTPContext *c1;
2658     int len, loop_run = 0;
2659
2660     while (c->chunked_encoding && !c->chunk_size &&
2661            c->buffer_end > c->buffer_ptr) {
2662         /* read chunk header, if present */
2663         len = recv(c->fd, c->buffer_ptr, 1, 0);
2664
2665         if (len < 0) {
2666             if (ff_neterrno() != AVERROR(EAGAIN) &&
2667                 ff_neterrno() != AVERROR(EINTR))
2668                 /* error : close connection */
2669                 goto fail;
2670             return 0;
2671         } else if (len == 0) {
2672             /* end of connection : close it */
2673             goto fail;
2674         } else if (c->buffer_ptr - c->buffer >= 2 &&
2675                    !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
2676             c->chunk_size = strtol(c->buffer, 0, 16);
2677             if (c->chunk_size == 0) // end of stream
2678                 goto fail;
2679             c->buffer_ptr = c->buffer;
2680             break;
2681         } else if (++loop_run > 10) {
2682             /* no chunk header, abort */
2683             goto fail;
2684         } else {
2685             c->buffer_ptr++;
2686         }
2687     }
2688
2689     if (c->buffer_end > c->buffer_ptr) {
2690         len = recv(c->fd, c->buffer_ptr,
2691                    FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
2692         if (len < 0) {
2693             if (ff_neterrno() != AVERROR(EAGAIN) &&
2694                 ff_neterrno() != AVERROR(EINTR))
2695                 /* error : close connection */
2696                 goto fail;
2697         } else if (len == 0)
2698             /* end of connection : close it */
2699             goto fail;
2700         else {
2701             c->chunk_size -= len;
2702             c->buffer_ptr += len;
2703             c->data_count += len;
2704             update_datarate(&c->datarate, c->data_count);
2705         }
2706     }
2707
2708     if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
2709         if (c->buffer[0] != 'f' ||
2710             c->buffer[1] != 'm') {
2711             http_log("Feed stream has become desynchronized -- disconnecting\n");
2712             goto fail;
2713         }
2714     }
2715
2716     if (c->buffer_ptr >= c->buffer_end) {
2717         FFStream *feed = c->stream;
2718         /* a packet has been received : write it in the store, except
2719            if header */
2720         if (c->data_count > FFM_PACKET_SIZE) {
2721             /* XXX: use llseek or url_seek */
2722             lseek(c->feed_fd, feed->feed_write_index, SEEK_SET);
2723             if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
2724                 http_log("Error writing to feed file: %s\n", strerror(errno));
2725                 goto fail;
2726             }
2727
2728             feed->feed_write_index += FFM_PACKET_SIZE;
2729             /* update file size */
2730             if (feed->feed_write_index > c->stream->feed_size)
2731                 feed->feed_size = feed->feed_write_index;
2732
2733             /* handle wrap around if max file size reached */
2734             if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size)
2735                 feed->feed_write_index = FFM_PACKET_SIZE;
2736
2737             /* write index */
2738             if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
2739                 http_log("Error writing index to feed file: %s\n", strerror(errno));
2740                 goto fail;
2741             }
2742
2743             /* wake up any waiting connections */
2744             for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2745                 if (c1->state == HTTPSTATE_WAIT_FEED &&
2746                     c1->stream->feed == c->stream->feed)
2747                     c1->state = HTTPSTATE_SEND_DATA;
2748             }
2749         } else {
2750             /* We have a header in our hands that contains useful data */
2751             AVFormatContext *s = avformat_alloc_context();
2752             AVIOContext *pb;
2753             AVInputFormat *fmt_in;
2754             int i;
2755
2756             if (!s)
2757                 goto fail;
2758
2759             /* use feed output format name to find corresponding input format */
2760             fmt_in = av_find_input_format(feed->fmt->name);
2761             if (!fmt_in)
2762                 goto fail;
2763
2764             pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
2765                                     0, NULL, NULL, NULL, NULL);
2766             pb->seekable = 0;
2767
2768             s->pb = pb;
2769             if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) {
2770                 av_free(pb);
2771                 goto fail;
2772             }
2773
2774             /* Now we have the actual streams */
2775             if (s->nb_streams != feed->nb_streams) {
2776                 avformat_close_input(&s);
2777                 av_free(pb);
2778                 http_log("Feed '%s' stream number does not match registered feed\n",
2779                          c->stream->feed_filename);
2780                 goto fail;
2781             }
2782
2783             for (i = 0; i < s->nb_streams; i++) {
2784                 AVStream *fst = feed->streams[i];
2785                 AVStream *st = s->streams[i];
2786                 avcodec_copy_context(fst->codec, st->codec);
2787             }
2788
2789             avformat_close_input(&s);
2790             av_free(pb);
2791         }
2792         c->buffer_ptr = c->buffer;
2793     }
2794
2795     return 0;
2796  fail:
2797     c->stream->feed_opened = 0;
2798     close(c->feed_fd);
2799     /* wake up any waiting connections to stop waiting for feed */
2800     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2801         if (c1->state == HTTPSTATE_WAIT_FEED &&
2802             c1->stream->feed == c->stream->feed)
2803             c1->state = HTTPSTATE_SEND_DATA_TRAILER;
2804     }
2805     return -1;
2806 }
2807
2808 /********************************************************************/
2809 /* RTSP handling */
2810
2811 static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
2812 {
2813     const char *str;
2814     time_t ti;
2815     struct tm *tm;
2816     char buf2[32];
2817
2818     switch(error_number) {
2819     case RTSP_STATUS_OK:
2820         str = "OK";
2821         break;
2822     case RTSP_STATUS_METHOD:
2823         str = "Method Not Allowed";
2824         break;
2825     case RTSP_STATUS_BANDWIDTH:
2826         str = "Not Enough Bandwidth";
2827         break;
2828     case RTSP_STATUS_SESSION:
2829         str = "Session Not Found";
2830         break;
2831     case RTSP_STATUS_STATE:
2832         str = "Method Not Valid in This State";
2833         break;
2834     case RTSP_STATUS_AGGREGATE:
2835         str = "Aggregate operation not allowed";
2836         break;
2837     case RTSP_STATUS_ONLY_AGGREGATE:
2838         str = "Only aggregate operation allowed";
2839         break;
2840     case RTSP_STATUS_TRANSPORT:
2841         str = "Unsupported transport";
2842         break;
2843     case RTSP_STATUS_INTERNAL:
2844         str = "Internal Server Error";
2845         break;
2846     case RTSP_STATUS_SERVICE:
2847         str = "Service Unavailable";
2848         break;
2849     case RTSP_STATUS_VERSION:
2850         str = "RTSP Version not supported";
2851         break;
2852     default:
2853         str = "Unknown Error";
2854         break;
2855     }
2856
2857     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
2858     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
2859
2860     /* output GMT time */
2861     ti = time(NULL);
2862     tm = gmtime(&ti);
2863     strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
2864     avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
2865 }
2866
2867 static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
2868 {
2869     rtsp_reply_header(c, error_number);
2870     avio_printf(c->pb, "\r\n");
2871 }
2872
2873 static int rtsp_parse_request(HTTPContext *c)
2874 {
2875     const char *p, *p1, *p2;
2876     char cmd[32];
2877     char url[1024];
2878     char protocol[32];
2879     char line[1024];
2880     int len;
2881     RTSPMessageHeader header1 = { 0 }, *header = &header1;
2882
2883     c->buffer_ptr[0] = '\0';
2884     p = c->buffer;
2885
2886     get_word(cmd, sizeof(cmd), &p);
2887     get_word(url, sizeof(url), &p);
2888     get_word(protocol, sizeof(protocol), &p);
2889
2890     av_strlcpy(c->method, cmd, sizeof(c->method));
2891     av_strlcpy(c->url, url, sizeof(c->url));
2892     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
2893
2894     if (avio_open_dyn_buf(&c->pb) < 0) {
2895         /* XXX: cannot do more */
2896         c->pb = NULL; /* safety */
2897         return -1;
2898     }
2899
2900     /* check version name */
2901     if (strcmp(protocol, "RTSP/1.0") != 0) {
2902         rtsp_reply_error(c, RTSP_STATUS_VERSION);
2903         goto the_end;
2904     }
2905
2906     /* parse each header line */
2907     /* skip to next line */
2908     while (*p != '\n' && *p != '\0')
2909         p++;
2910     if (*p == '\n')
2911         p++;
2912     while (*p != '\0') {
2913         p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
2914         if (!p1)
2915             break;
2916         p2 = p1;
2917         if (p2 > p && p2[-1] == '\r')
2918             p2--;
2919         /* skip empty line */
2920         if (p2 == p)
2921             break;
2922         len = p2 - p;
2923         if (len > sizeof(line) - 1)
2924             len = sizeof(line) - 1;
2925         memcpy(line, p, len);
2926         line[len] = '\0';
2927         ff_rtsp_parse_line(header, line, NULL, NULL);
2928         p = p1 + 1;
2929     }
2930
2931     /* handle sequence number */
2932     c->seq = header->seq;
2933
2934     if (!strcmp(cmd, "DESCRIBE"))
2935         rtsp_cmd_describe(c, url);
2936     else if (!strcmp(cmd, "OPTIONS"))
2937         rtsp_cmd_options(c, url);
2938     else if (!strcmp(cmd, "SETUP"))
2939         rtsp_cmd_setup(c, url, header);
2940     else if (!strcmp(cmd, "PLAY"))
2941         rtsp_cmd_play(c, url, header);
2942     else if (!strcmp(cmd, "PAUSE"))
2943         rtsp_cmd_pause(c, url, header);
2944     else if (!strcmp(cmd, "TEARDOWN"))
2945         rtsp_cmd_teardown(c, url, header);
2946     else
2947         rtsp_reply_error(c, RTSP_STATUS_METHOD);
2948
2949  the_end:
2950     len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
2951     c->pb = NULL; /* safety */
2952     if (len < 0) {
2953         /* XXX: cannot do more */
2954         return -1;
2955     }
2956     c->buffer_ptr = c->pb_buffer;
2957     c->buffer_end = c->pb_buffer + len;
2958     c->state = RTSPSTATE_SEND_REPLY;
2959     return 0;
2960 }
2961
2962 static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
2963                                    struct in_addr my_ip)
2964 {
2965     AVFormatContext *avc;
2966     AVStream *avs = NULL;
2967     int i;
2968
2969     avc =  avformat_alloc_context();
2970     if (avc == NULL) {
2971         return -1;
2972     }
2973     av_dict_set(&avc->metadata, "title",
2974                stream->title[0] ? stream->title : "No Title", 0);
2975     avc->nb_streams = stream->nb_streams;
2976     if (stream->is_multicast) {
2977         snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
2978                  inet_ntoa(stream->multicast_ip),
2979                  stream->multicast_port, stream->multicast_ttl);
2980     } else {
2981         snprintf(avc->filename, 1024, "rtp://0.0.0.0");
2982     }
2983
2984     if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) ||
2985         !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams))))
2986         goto sdp_done;
2987     if (avc->nb_streams >= INT_MAX/sizeof(*avs) ||
2988         !(avs = av_malloc(avc->nb_streams * sizeof(*avs))))
2989         goto sdp_done;
2990
2991     for(i = 0; i < stream->nb_streams; i++) {
2992         avc->streams[i] = &avs[i];
2993         avc->streams[i]->codec = stream->streams[i]->codec;
2994     }
2995     *pbuffer = av_mallocz(2048);
2996     av_sdp_create(&avc, 1, *pbuffer, 2048);
2997
2998  sdp_done:
2999     av_free(avc->streams);
3000     av_dict_free(&avc->metadata);
3001     av_free(avc);
3002     av_free(avs);
3003
3004     return strlen(*pbuffer);
3005 }
3006
3007 static void rtsp_cmd_options(HTTPContext *c, const char *url)
3008 {
3009 //    rtsp_reply_header(c, RTSP_STATUS_OK);
3010     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
3011     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
3012     avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
3013     avio_printf(c->pb, "\r\n");
3014 }
3015
3016 static void rtsp_cmd_describe(HTTPContext *c, const char *url)
3017 {
3018     FFStream *stream;
3019     char path1[1024];
3020     const char *path;
3021     uint8_t *content;
3022     int content_length, len;
3023     struct sockaddr_in my_addr;
3024
3025     /* find which url is asked */
3026     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3027     path = path1;
3028     if (*path == '/')
3029         path++;
3030
3031     for(stream = first_stream; stream != NULL; stream = stream->next) {
3032         if (!stream->is_feed &&
3033             stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
3034             !strcmp(path, stream->filename)) {
3035             goto found;
3036         }
3037     }
3038     /* no stream found */
3039     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
3040     return;
3041
3042  found:
3043     /* prepare the media description in sdp format */
3044
3045     /* get the host IP */
3046     len = sizeof(my_addr);
3047     getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
3048     content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);
3049     if (content_length < 0) {
3050         rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
3051         return;
3052     }
3053     rtsp_reply_header(c, RTSP_STATUS_OK);
3054     avio_printf(c->pb, "Content-Base: %s/\r\n", url);
3055     avio_printf(c->pb, "Content-Type: application/sdp\r\n");
3056     avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
3057     avio_printf(c->pb, "\r\n");
3058     avio_write(c->pb, content, content_length);
3059     av_free(content);
3060 }
3061
3062 static HTTPContext *find_rtp_session(const char *session_id)
3063 {
3064     HTTPContext *c;
3065
3066     if (session_id[0] == '\0')
3067         return NULL;
3068
3069     for(c = first_http_ctx; c != NULL; c = c->next) {
3070         if (!strcmp(c->session_id, session_id))
3071             return c;
3072     }
3073     return NULL;
3074 }
3075
3076 static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
3077 {
3078     RTSPTransportField *th;
3079     int i;
3080
3081     for(i=0;i<h->nb_transports;i++) {
3082         th = &h->transports[i];
3083         if (th->lower_transport == lower_transport)
3084             return th;
3085     }
3086     return NULL;
3087 }
3088
3089 static void rtsp_cmd_setup(HTTPContext *c, const char *url,
3090                            RTSPMessageHeader *h)
3091 {
3092     FFStream *stream;
3093     int stream_index, rtp_port, rtcp_port;
3094     char buf[1024];
3095     char path1[1024];
3096     const char *path;
3097     HTTPContext *rtp_c;
3098     RTSPTransportField *th;
3099     struct sockaddr_in dest_addr;
3100     RTSPActionServerSetup setup;
3101
3102     /* find which url is asked */
3103     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3104     path = path1;
3105     if (*path == '/')
3106         path++;
3107
3108     /* now check each stream */
3109     for(stream = first_stream; stream != NULL; stream = stream->next) {
3110         if (!stream->is_feed &&
3111             stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
3112             /* accept aggregate filenames only if single stream */
3113             if (!strcmp(path, stream->filename)) {
3114                 if (stream->nb_streams != 1) {
3115                     rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);
3116                     return;
3117                 }
3118                 stream_index = 0;
3119                 goto found;
3120             }
3121
3122             for(stream_index = 0; stream_index < stream->nb_streams;
3123                 stream_index++) {
3124                 snprintf(buf, sizeof(buf), "%s/streamid=%d",
3125                          stream->filename, stream_index);
3126                 if (!strcmp(path, buf))
3127                     goto found;
3128             }
3129         }
3130     }
3131     /* no stream found */
3132     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
3133     return;
3134  found:
3135
3136     /* generate session id if needed */
3137     if (h->session_id[0] == '\0') {
3138         unsigned random0 = av_lfg_get(&random_state);
3139         unsigned random1 = av_lfg_get(&random_state);
3140         snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
3141                  random0, random1);
3142     }
3143
3144     /* find rtp session, and create it if none found */
3145     rtp_c = find_rtp_session(h->session_id);
3146     if (!rtp_c) {
3147         /* always prefer UDP */
3148         th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
3149         if (!th) {
3150             th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
3151             if (!th) {
3152                 rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3153                 return;
3154             }
3155         }
3156
3157         rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
3158                                    th->lower_transport);
3159         if (!rtp_c) {
3160             rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
3161             return;
3162         }
3163
3164         /* open input stream */
3165         if (open_input_stream(rtp_c, "") < 0) {
3166             rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
3167             return;
3168         }
3169     }
3170
3171     /* test if stream is OK (test needed because several SETUP needs
3172        to be done for a given file) */
3173     if (rtp_c->stream != stream) {
3174         rtsp_reply_error(c, RTSP_STATUS_SERVICE);
3175         return;
3176     }
3177
3178     /* test if stream is already set up */
3179     if (rtp_c->rtp_ctx[stream_index]) {
3180         rtsp_reply_error(c, RTSP_STATUS_STATE);
3181         return;
3182     }
3183
3184     /* check transport */
3185     th = find_transport(h, rtp_c->rtp_protocol);
3186     if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
3187                 th->client_port_min <= 0)) {
3188         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3189         return;
3190     }
3191
3192     /* setup default options */
3193     setup.transport_option[0] = '\0';
3194     dest_addr = rtp_c->from_addr;
3195     dest_addr.sin_port = htons(th->client_port_min);
3196
3197     /* setup stream */
3198     if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
3199         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3200         return;
3201     }
3202
3203     /* now everything is OK, so we can send the connection parameters */
3204     rtsp_reply_header(c, RTSP_STATUS_OK);
3205     /* session ID */
3206     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3207
3208     switch(rtp_c->rtp_protocol) {
3209     case RTSP_LOWER_TRANSPORT_UDP:
3210         rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
3211         rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
3212         avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
3213                     "client_port=%d-%d;server_port=%d-%d",
3214                     th->client_port_min, th->client_port_max,
3215                     rtp_port, rtcp_port);
3216         break;
3217     case RTSP_LOWER_TRANSPORT_TCP:
3218         avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
3219                     stream_index * 2, stream_index * 2 + 1);
3220         break;
3221     default:
3222         break;
3223     }
3224     if (setup.transport_option[0] != '\0')
3225         avio_printf(c->pb, ";%s", setup.transport_option);
3226     avio_printf(c->pb, "\r\n");
3227
3228
3229     avio_printf(c->pb, "\r\n");
3230 }
3231
3232
3233 /* find an rtp connection by using the session ID. Check consistency
3234    with filename */
3235 static HTTPContext *find_rtp_session_with_url(const char *url,
3236                                               const char *session_id)
3237 {
3238     HTTPContext *rtp_c;
3239     char path1[1024];
3240     const char *path;
3241     char buf[1024];
3242     int s, len;
3243
3244     rtp_c = find_rtp_session(session_id);
3245     if (!rtp_c)
3246         return NULL;
3247
3248     /* find which url is asked */
3249     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3250     path = path1;
3251     if (*path == '/')
3252         path++;
3253     if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
3254     for(s=0; s<rtp_c->stream->nb_streams; ++s) {
3255       snprintf(buf, sizeof(buf), "%s/streamid=%d",
3256         rtp_c->stream->filename, s);
3257       if(!strncmp(path, buf, sizeof(buf))) {
3258     // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
3259         return rtp_c;
3260       }
3261     }
3262     len = strlen(path);
3263     if (len > 0 && path[len - 1] == '/' &&
3264         !strncmp(path, rtp_c->stream->filename, len - 1))
3265         return rtp_c;
3266     return NULL;
3267 }
3268
3269 static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3270 {
3271     HTTPContext *rtp_c;
3272
3273     rtp_c = find_rtp_session_with_url(url, h->session_id);
3274     if (!rtp_c) {
3275         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3276         return;
3277     }
3278
3279     if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3280         rtp_c->state != HTTPSTATE_WAIT_FEED &&
3281         rtp_c->state != HTTPSTATE_READY) {
3282         rtsp_reply_error(c, RTSP_STATUS_STATE);
3283         return;
3284     }
3285
3286     rtp_c->state = HTTPSTATE_SEND_DATA;
3287
3288     /* now everything is OK, so we can send the connection parameters */
3289     rtsp_reply_header(c, RTSP_STATUS_OK);
3290     /* session ID */
3291     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3292     avio_printf(c->pb, "\r\n");
3293 }
3294
3295 static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3296 {
3297     HTTPContext *rtp_c;
3298
3299     rtp_c = find_rtp_session_with_url(url, h->session_id);
3300     if (!rtp_c) {
3301         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3302         return;
3303     }
3304
3305     if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3306         rtp_c->state != HTTPSTATE_WAIT_FEED) {
3307         rtsp_reply_error(c, RTSP_STATUS_STATE);
3308         return;
3309     }
3310
3311     rtp_c->state = HTTPSTATE_READY;
3312     rtp_c->first_pts = AV_NOPTS_VALUE;
3313     /* now everything is OK, so we can send the connection parameters */
3314     rtsp_reply_header(c, RTSP_STATUS_OK);
3315     /* session ID */
3316     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3317     avio_printf(c->pb, "\r\n");
3318 }
3319
3320 static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3321 {
3322     HTTPContext *rtp_c;
3323
3324     rtp_c = find_rtp_session_with_url(url, h->session_id);
3325     if (!rtp_c) {
3326         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3327         return;
3328     }
3329
3330     /* now everything is OK, so we can send the connection parameters */
3331     rtsp_reply_header(c, RTSP_STATUS_OK);
3332     /* session ID */
3333     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3334     avio_printf(c->pb, "\r\n");
3335
3336     /* abort the session */
3337     close_connection(rtp_c);
3338 }
3339
3340
3341 /********************************************************************/
3342 /* RTP handling */
3343
3344 static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
3345                                        FFStream *stream, const char *session_id,
3346                                        enum RTSPLowerTransport rtp_protocol)
3347 {
3348     HTTPContext *c = NULL;
3349     const char *proto_str;
3350
3351     /* XXX: should output a warning page when coming
3352        close to the connection limit */
3353     if (nb_connections >= nb_max_connections)
3354         goto fail;
3355
3356     /* add a new connection */
3357     c = av_mallocz(sizeof(HTTPContext));
3358     if (!c)
3359         goto fail;
3360
3361     c->fd = -1;
3362     c->poll_entry = NULL;
3363     c->from_addr = *from_addr;
3364     c->buffer_size = IOBUFFER_INIT_SIZE;
3365     c->buffer = av_malloc(c->buffer_size);
3366     if (!c->buffer)
3367         goto fail;
3368     nb_connections++;
3369     c->stream = stream;
3370     av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
3371     c->state = HTTPSTATE_READY;
3372     c->is_packetized = 1;
3373     c->rtp_protocol = rtp_protocol;
3374
3375     /* protocol is shown in statistics */
3376     switch(c->rtp_protocol) {
3377     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3378         proto_str = "MCAST";
3379         break;
3380     case RTSP_LOWER_TRANSPORT_UDP:
3381         proto_str = "UDP";
3382         break;
3383     case RTSP_LOWER_TRANSPORT_TCP:
3384         proto_str = "TCP";
3385         break;
3386     default:
3387         proto_str = "???";
3388         break;
3389     }
3390     av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
3391     av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
3392
3393     current_bandwidth += stream->bandwidth;
3394
3395     c->next = first_http_ctx;
3396     first_http_ctx = c;
3397     return c;
3398
3399  fail:
3400     if (c) {
3401         av_free(c->buffer);
3402         av_free(c);
3403     }
3404     return NULL;
3405 }
3406
3407 /* add a new RTP stream in an RTP connection (used in RTSP SETUP
3408    command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
3409    used. */
3410 static int rtp_new_av_stream(HTTPContext *c,
3411                              int stream_index, struct sockaddr_in *dest_addr,
3412                              HTTPContext *rtsp_c)
3413 {
3414     AVFormatContext *ctx;
3415     AVStream *st;
3416     char *ipaddr;
3417     URLContext *h = NULL;
3418     uint8_t *dummy_buf;
3419     int max_packet_size;
3420
3421     /* now we can open the relevant output stream */
3422     ctx = avformat_alloc_context();
3423     if (!ctx)
3424         return -1;
3425     ctx->oformat = av_guess_format("rtp", NULL, NULL);
3426
3427     st = av_mallocz(sizeof(AVStream));
3428     if (!st)
3429         goto fail;
3430     ctx->nb_streams = 1;
3431     ctx->streams = av_mallocz(sizeof(AVStream *) * ctx->nb_streams);
3432     if (!ctx->streams)
3433       goto fail;
3434     ctx->streams[0] = st;
3435
3436     if (!c->stream->feed ||
3437         c->stream->feed == c->stream)
3438         memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
3439     else
3440         memcpy(st,
3441                c->stream->feed->streams[c->stream->feed_streams[stream_index]],
3442                sizeof(AVStream));
3443     st->priv_data = NULL;
3444
3445     /* build destination RTP address */
3446     ipaddr = inet_ntoa(dest_addr->sin_addr);
3447
3448     switch(c->rtp_protocol) {
3449     case RTSP_LOWER_TRANSPORT_UDP:
3450     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3451         /* RTP/UDP case */
3452
3453         /* XXX: also pass as parameter to function ? */
3454         if (c->stream->is_multicast) {
3455             int ttl;
3456             ttl = c->stream->multicast_ttl;
3457             if (!ttl)
3458                 ttl = 16;
3459             snprintf(ctx->filename, sizeof(ctx->filename),
3460                      "rtp://%s:%d?multicast=1&ttl=%d",
3461                      ipaddr, ntohs(dest_addr->sin_port), ttl);
3462         } else {
3463             snprintf(ctx->filename, sizeof(ctx->filename),
3464                      "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
3465         }
3466
3467         if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
3468             goto fail;
3469         c->rtp_handles[stream_index] = h;
3470         max_packet_size = h->max_packet_size;
3471         break;
3472     case RTSP_LOWER_TRANSPORT_TCP:
3473         /* RTP/TCP case */
3474         c->rtsp_c = rtsp_c;
3475         max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
3476         break;
3477     default:
3478         goto fail;
3479     }
3480
3481     http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
3482              ipaddr, ntohs(dest_addr->sin_port),
3483              c->stream->filename, stream_index, c->protocol);
3484
3485     /* normally, no packets should be output here, but the packet size may be checked */
3486     if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
3487         /* XXX: close stream */
3488         goto fail;
3489     }
3490     if (avformat_write_header(ctx, NULL) < 0) {
3491     fail:
3492         if (h)
3493             ffurl_close(h);
3494         av_free(ctx);
3495         return -1;
3496     }
3497     avio_close_dyn_buf(ctx->pb, &dummy_buf);
3498     av_free(dummy_buf);
3499
3500     c->rtp_ctx[stream_index] = ctx;
3501     return 0;
3502 }
3503
3504 /********************************************************************/
3505 /* ffserver initialization */
3506
3507 static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
3508 {
3509     AVStream *fst;
3510
3511     if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
3512         return NULL;
3513
3514     fst = av_mallocz(sizeof(AVStream));
3515     if (!fst)
3516         return NULL;
3517     if (copy) {
3518         fst->codec = avcodec_alloc_context3(NULL);
3519         memcpy(fst->codec, codec, sizeof(AVCodecContext));
3520         if (codec->extradata_size) {
3521             fst->codec->extradata = av_malloc(codec->extradata_size);
3522             memcpy(fst->codec->extradata, codec->extradata,
3523                 codec->extradata_size);
3524         }
3525     } else {
3526         /* live streams must use the actual feed's codec since it may be
3527          * updated later to carry extradata needed by the streams.
3528          */
3529         fst->codec = codec;
3530     }
3531     fst->priv_data = av_mallocz(sizeof(FeedData));
3532     fst->index = stream->nb_streams;
3533     avpriv_set_pts_info(fst, 33, 1, 90000);
3534     fst->sample_aspect_ratio = codec->sample_aspect_ratio;
3535     stream->streams[stream->nb_streams++] = fst;
3536     return fst;
3537 }
3538
3539 /* return the stream number in the feed */
3540 static int add_av_stream(FFStream *feed, AVStream *st)
3541 {
3542     AVStream *fst;
3543     AVCodecContext *av, *av1;
3544     int i;
3545
3546     av = st->codec;
3547     for(i=0;i<feed->nb_streams;i++) {
3548         st = feed->streams[i];
3549         av1 = st->codec;
3550         if (av1->codec_id == av->codec_id &&
3551             av1->codec_type == av->codec_type &&
3552             av1->bit_rate == av->bit_rate) {
3553
3554             switch(av->codec_type) {
3555             case AVMEDIA_TYPE_AUDIO:
3556                 if (av1->channels == av->channels &&
3557                     av1->sample_rate == av->sample_rate)
3558                     return i;
3559                 break;
3560             case AVMEDIA_TYPE_VIDEO:
3561                 if (av1->width == av->width &&
3562                     av1->height == av->height &&
3563                     av1->time_base.den == av->time_base.den &&
3564                     av1->time_base.num == av->time_base.num &&
3565                     av1->gop_size == av->gop_size)
3566                     return i;
3567                 break;
3568             default:
3569                 abort();
3570             }
3571         }
3572     }
3573
3574     fst = add_av_stream1(feed, av, 0);
3575     if (!fst)
3576         return -1;
3577     return feed->nb_streams - 1;
3578 }
3579
3580 static void remove_stream(FFStream *stream)
3581 {
3582     FFStream **ps;
3583     ps = &first_stream;
3584     while (*ps != NULL) {
3585         if (*ps == stream)
3586             *ps = (*ps)->next;
3587         else
3588             ps = &(*ps)->next;
3589     }
3590 }
3591
3592 /* specific mpeg4 handling : we extract the raw parameters */
3593 static void extract_mpeg4_header(AVFormatContext *infile)
3594 {
3595     int mpeg4_count, i, size;
3596     AVPacket pkt;
3597     AVStream *st;
3598     const uint8_t *p;
3599
3600     mpeg4_count = 0;
3601     for(i=0;i<infile->nb_streams;i++) {
3602         st = infile->streams[i];
3603         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3604             st->codec->extradata_size == 0) {
3605             mpeg4_count++;
3606         }
3607     }
3608     if (!mpeg4_count)
3609         return;
3610
3611     printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
3612     while (mpeg4_count > 0) {
3613         if (av_read_packet(infile, &pkt) < 0)
3614             break;
3615         st = infile->streams[pkt.stream_index];
3616         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3617             st->codec->extradata_size == 0) {
3618             av_freep(&st->codec->extradata);
3619             /* fill extradata with the header */
3620             /* XXX: we make hard suppositions here ! */
3621             p = pkt.data;
3622             while (p < pkt.data + pkt.size - 4) {
3623                 /* stop when vop header is found */
3624                 if (p[0] == 0x00 && p[1] == 0x00 &&
3625                     p[2] == 0x01 && p[3] == 0xb6) {
3626                     size = p - pkt.data;
3627                     //                    av_hex_dump_log(infile, AV_LOG_DEBUG, pkt.data, size);
3628                     st->codec->extradata = av_malloc(size);
3629                     st->codec->extradata_size = size;
3630                     memcpy(st->codec->extradata, pkt.data, size);
3631                     break;
3632                 }
3633                 p++;
3634             }
3635             mpeg4_count--;
3636         }
3637         av_free_packet(&pkt);
3638     }
3639 }
3640
3641 /* compute the needed AVStream for each file */
3642 static void build_file_streams(void)
3643 {
3644     FFStream *stream, *stream_next;
3645     int i, ret;
3646
3647     /* gather all streams */
3648     for(stream = first_stream; stream != NULL; stream = stream_next) {
3649         AVFormatContext *infile = NULL;
3650         stream_next = stream->next;
3651         if (stream->stream_type == STREAM_TYPE_LIVE &&
3652             !stream->feed) {
3653             /* the stream comes from a file */
3654             /* try to open the file */
3655             /* open stream */
3656             if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
3657                 /* specific case : if transport stream output to RTP,
3658                    we use a raw transport stream reader */
3659                 av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
3660             }
3661
3662             http_log("Opening file '%s'\n", stream->feed_filename);
3663             if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
3664                 http_log("Could not open '%s': %d\n", stream->feed_filename, ret);
3665                 /* remove stream (no need to spend more time on it) */
3666             fail:
3667                 remove_stream(stream);
3668             } else {
3669                 /* find all the AVStreams inside and reference them in
3670                    'stream' */
3671                 if (avformat_find_stream_info(infile, NULL) < 0) {
3672                     http_log("Could not find codec parameters from '%s'\n",
3673                              stream->feed_filename);
3674                     avformat_close_input(&infile);
3675                     goto fail;
3676                 }
3677                 extract_mpeg4_header(infile);
3678
3679                 for(i=0;i<infile->nb_streams;i++)
3680                     add_av_stream1(stream, infile->streams[i]->codec, 1);
3681
3682                 avformat_close_input(&infile);
3683             }
3684         }
3685     }
3686 }
3687
3688 /* compute the needed AVStream for each feed */
3689 static void build_feed_streams(void)
3690 {
3691     FFStream *stream, *feed;
3692     int i;
3693
3694     /* gather all streams */
3695     for(stream = first_stream; stream != NULL; stream = stream->next) {
3696         feed = stream->feed;
3697         if (feed) {
3698             if (stream->is_feed) {
3699                 for(i=0;i<stream->nb_streams;i++)
3700                     stream->feed_streams[i] = i;
3701             } else {
3702                 /* we handle a stream coming from a feed */
3703                 for(i=0;i<stream->nb_streams;i++)
3704                     stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]);
3705             }
3706         }
3707     }
3708
3709     /* create feed files if needed */
3710     for(feed = first_feed; feed != NULL; feed = feed->next_feed) {
3711         int fd;
3712
3713         if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
3714             /* See if it matches */
3715             AVFormatContext *s = NULL;
3716             int matches = 0;
3717
3718             if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
3719                 /* set buffer size */
3720                 ffio_set_buf_size(s->pb, FFM_PACKET_SIZE);
3721                 /* Now see if it matches */
3722                 if (s->nb_streams == feed->nb_streams) {
3723                     matches = 1;
3724                     for(i=0;i<s->nb_streams;i++) {
3725                         AVStream *sf, *ss;
3726                         sf = feed->streams[i];
3727                         ss = s->streams[i];
3728
3729                         if (sf->index != ss->index ||
3730                             sf->id != ss->id) {
3731                             http_log("Index & Id do not match for stream %d (%s)\n",
3732                                    i, feed->feed_filename);
3733                             matches = 0;
3734                         } else {
3735                             AVCodecContext *ccf, *ccs;
3736
3737                             ccf = sf->codec;
3738                             ccs = ss->codec;
3739 #define CHECK_CODEC(x)  (ccf->x != ccs->x)
3740
3741                             if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
3742                                 http_log("Codecs do not match for stream %d\n", i);
3743                                 matches = 0;
3744                             } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
3745                                 http_log("Codec bitrates do not match for stream %d\n", i);
3746                                 matches = 0;
3747                             } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {
3748                                 if (CHECK_CODEC(time_base.den) ||
3749                                     CHECK_CODEC(time_base.num) ||
3750                                     CHECK_CODEC(width) ||
3751                                     CHECK_CODEC(height)) {
3752                                     http_log("Codec width, height and framerate do not match for stream %d\n", i);
3753                                     matches = 0;
3754                                 }
3755                             } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {
3756                                 if (CHECK_CODEC(sample_rate) ||
3757                                     CHECK_CODEC(channels) ||
3758                                     CHECK_CODEC(frame_size)) {
3759                                     http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);
3760                                     matches = 0;
3761                                 }
3762                             } else {
3763                                 http_log("Unknown codec type\n");
3764                                 matches = 0;
3765                             }
3766                         }
3767                         if (!matches)
3768                             break;
3769                     }
3770                 } else
3771                     http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",
3772                         feed->feed_filename, s->nb_streams, feed->nb_streams);
3773
3774                 avformat_close_input(&s);
3775             } else
3776                 http_log("Deleting feed file '%s' as it appears to be corrupt\n",
3777                         feed->feed_filename);
3778
3779             if (!matches) {
3780                 if (feed->readonly) {
3781                     http_log("Unable to delete feed file '%s' as it is marked readonly\n",
3782                         feed->feed_filename);
3783                     exit(1);
3784                 }
3785                 unlink(feed->feed_filename);
3786             }
3787         }
3788         if (avio_check(feed->feed_filename, AVIO_FLAG_WRITE) <= 0) {
3789             AVFormatContext s1 = {0}, *s = &s1;
3790
3791             if (feed->readonly) {
3792                 http_log("Unable to create feed file '%s' as it is marked readonly\n",
3793                     feed->feed_filename);
3794                 exit(1);
3795             }
3796
3797             /* only write the header of the ffm file */
3798             if (avio_open(&s->pb, feed->feed_filename, AVIO_FLAG_WRITE) < 0) {
3799                 http_log("Could not open output feed file '%s'\n",
3800                          feed->feed_filename);
3801                 exit(1);
3802             }
3803             s->oformat = feed->fmt;
3804             s->nb_streams = feed->nb_streams;
3805             s->streams = feed->streams;
3806             if (avformat_write_header(s, NULL) < 0) {
3807                 http_log("Container doesn't support the required parameters\n");
3808                 exit(1);
3809             }
3810             /* XXX: need better api */
3811             av_freep(&s->priv_data);
3812             avio_close(s->pb);
3813         }
3814         /* get feed size and write index */
3815         fd = open(feed->feed_filename, O_RDONLY);
3816         if (fd < 0) {
3817             http_log("Could not open output feed file '%s'\n",
3818                     feed->feed_filename);
3819             exit(1);
3820         }
3821
3822         feed->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
3823         feed->feed_size = lseek(fd, 0, SEEK_END);
3824         /* ensure that we do not wrap before the end of file */
3825         if (feed->feed_max_size && feed->feed_max_size < feed->feed_size)
3826             feed->feed_max_size = feed->feed_size;
3827
3828         close(fd);
3829     }
3830 }
3831
3832 /* compute the bandwidth used by each stream */
3833 static void compute_bandwidth(void)
3834 {
3835     unsigned bandwidth;
3836     int i;
3837     FFStream *stream;
3838
3839     for(stream = first_stream; stream != NULL; stream = stream->next) {
3840         bandwidth = 0;
3841         for(i=0;i<stream->nb_streams;i++) {
3842             AVStream *st = stream->streams[i];
3843             switch(st->codec->codec_type) {
3844             case AVMEDIA_TYPE_AUDIO:
3845             case AVMEDIA_TYPE_VIDEO:
3846                 bandwidth += st->codec->bit_rate;
3847                 break;
3848             default:
3849                 break;
3850             }
3851         }
3852         stream->bandwidth = (bandwidth + 999) / 1000;
3853     }
3854 }
3855
3856 /* add a codec and set the default parameters */
3857 static void add_codec(FFStream *stream, AVCodecContext *av)
3858 {
3859     AVStream *st;
3860
3861     if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
3862         return;
3863
3864     /* compute default parameters */
3865     switch(av->codec_type) {
3866     case AVMEDIA_TYPE_AUDIO:
3867         if (av->bit_rate == 0)
3868             av->bit_rate = 64000;
3869         if (av->sample_rate == 0)
3870             av->sample_rate = 22050;
3871         if (av->channels == 0)
3872             av->channels = 1;
3873         break;
3874     case AVMEDIA_TYPE_VIDEO:
3875         if (av->bit_rate == 0)
3876             av->bit_rate = 64000;
3877         if (av->time_base.num == 0){
3878             av->time_base.den = 5;
3879             av->time_base.num = 1;
3880         }
3881         if (av->width == 0 || av->height == 0) {
3882             av->width = 160;
3883             av->height = 128;
3884         }
3885         /* Bitrate tolerance is less for streaming */
3886         if (av->bit_rate_tolerance == 0)
3887             av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
3888                       (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
3889         if (av->qmin == 0)
3890             av->qmin = 3;
3891         if (av->qmax == 0)
3892             av->qmax = 31;
3893         if (av->max_qdiff == 0)
3894             av->max_qdiff = 3;
3895         av->qcompress = 0.5;
3896         av->qblur = 0.5;
3897
3898         if (!av->nsse_weight)
3899             av->nsse_weight = 8;
3900
3901         av->frame_skip_cmp = FF_CMP_DCTMAX;
3902         if (!av->me_method)
3903             av->me_method = ME_EPZS;
3904         av->rc_buffer_aggressivity = 1.0;
3905
3906         if (!av->rc_eq)
3907             av->rc_eq = "tex^qComp";
3908         if (!av->i_quant_factor)
3909             av->i_quant_factor = -0.8;
3910         if (!av->b_quant_factor)
3911             av->b_quant_factor = 1.25;
3912         if (!av->b_quant_offset)
3913             av->b_quant_offset = 1.25;
3914         if (!av->rc_max_rate)
3915             av->rc_max_rate = av->bit_rate * 2;
3916
3917         if (av->rc_max_rate && !av->rc_buffer_size) {
3918             av->rc_buffer_size = av->rc_max_rate;
3919         }
3920
3921
3922         break;
3923     default:
3924         abort();
3925     }
3926
3927     st = av_mallocz(sizeof(AVStream));
3928     if (!st)
3929         return;
3930     st->codec = avcodec_alloc_context3(NULL);
3931     stream->streams[stream->nb_streams++] = st;
3932     memcpy(st->codec, av, sizeof(AVCodecContext));
3933 }
3934
3935 static enum AVCodecID opt_audio_codec(const char *arg)
3936 {
3937     AVCodec *p= avcodec_find_encoder_by_name(arg);
3938
3939     if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO)
3940         return AV_CODEC_ID_NONE;
3941
3942     return p->id;
3943 }
3944
3945 static enum AVCodecID opt_video_codec(const char *arg)
3946 {
3947     AVCodec *p= avcodec_find_encoder_by_name(arg);
3948
3949     if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO)
3950         return AV_CODEC_ID_NONE;
3951
3952     return p->id;
3953 }
3954
3955 /* simplistic plugin support */
3956
3957 #if HAVE_DLOPEN
3958 static void load_module(const char *filename)
3959 {
3960     void *dll;
3961     void (*init_func)(void);
3962     dll = dlopen(filename, RTLD_NOW);
3963     if (!dll) {
3964         fprintf(stderr, "Could not load module '%s' - %s\n",
3965                 filename, dlerror());
3966         return;
3967     }
3968
3969     init_func = dlsym(dll, "ffserver_module_init");
3970     if (!init_func) {
3971         fprintf(stderr,
3972                 "%s: init function 'ffserver_module_init()' not found\n",
3973                 filename);
3974         dlclose(dll);
3975     }
3976
3977     init_func();
3978 }
3979 #endif
3980
3981 static int ffserver_opt_default(const char *opt, const char *arg,
3982                        AVCodecContext *avctx, int type)
3983 {
3984     int ret = 0;
3985     const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0);
3986     if(o)
3987         ret = av_opt_set(avctx, opt, arg, 0);
3988     return ret;
3989 }
3990
3991 static int ffserver_opt_preset(const char *arg,
3992                        AVCodecContext *avctx, int type,
3993                        enum AVCodecID *audio_id, enum AVCodecID *video_id)
3994 {
3995     FILE *f=NULL;
3996     char filename[1000], tmp[1000], tmp2[1000], line[1000];
3997     int ret = 0;
3998     AVCodec *codec = avcodec_find_encoder(avctx->codec_id);
3999
4000     if (!(f = get_preset_file(filename, sizeof(filename), arg, 0,
4001                               codec ? codec->name : NULL))) {
4002         fprintf(stderr, "File for preset '%s' not found\n", arg);
4003         return 1;
4004     }
4005
4006     while(!feof(f)){
4007         int e= fscanf(f, "%999[^\n]\n", line) - 1;
4008         if(line[0] == '#' && !e)
4009             continue;
4010         e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
4011         if(e){
4012             fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line);
4013             ret = 1;
4014             break;
4015         }
4016         if(!strcmp(tmp, "acodec")){
4017             *audio_id = opt_audio_codec(tmp2);
4018         }else if(!strcmp(tmp, "vcodec")){
4019             *video_id = opt_video_codec(tmp2);
4020         }else if(!strcmp(tmp, "scodec")){
4021             /* opt_subtitle_codec(tmp2); */
4022         }else if(ffserver_opt_default(tmp, tmp2, avctx, type) < 0){
4023             fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
4024             ret = 1;
4025             break;
4026         }
4027     }
4028
4029     fclose(f);
4030
4031     return ret;
4032 }
4033
4034 static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename,
4035                                              const char *mime_type)
4036 {
4037     AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
4038
4039     if (fmt) {
4040         AVOutputFormat *stream_fmt;
4041         char stream_format_name[64];
4042
4043         snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
4044         stream_fmt = av_guess_format(stream_format_name, NULL, NULL);
4045
4046         if (stream_fmt)
4047             fmt = stream_fmt;
4048     }
4049
4050     return fmt;
4051 }
4052
4053 static void report_config_error(const char *filename, int line_num, int *errors, const char *fmt, ...)
4054 {
4055     va_list vl;
4056     va_start(vl, fmt);
4057     fprintf(stderr, "%s:%d: ", filename, line_num);
4058     vfprintf(stderr, fmt, vl);
4059     va_end(vl);
4060
4061     (*errors)++;
4062 }
4063
4064 static int parse_ffconfig(const char *filename)
4065 {
4066     FILE *f;
4067     char line[1024];
4068     char cmd[64];
4069     char arg[1024];
4070     const char *p;
4071     int val, errors, line_num;
4072     FFStream **last_stream, *stream, *redirect;
4073     FFStream **last_feed, *feed, *s;
4074     AVCodecContext audio_enc, video_enc;
4075     enum AVCodecID audio_id, video_id;
4076
4077     f = fopen(filename, "r");
4078     if (!f) {
4079         perror(filename);
4080         return -1;
4081     }
4082
4083     errors = 0;
4084     line_num = 0;
4085     first_stream = NULL;
4086     last_stream = &first_stream;
4087     first_feed = NULL;
4088     last_feed = &first_feed;
4089     stream = NULL;
4090     feed = NULL;
4091     redirect = NULL;
4092     audio_id = AV_CODEC_ID_NONE;
4093     video_id = AV_CODEC_ID_NONE;
4094
4095 #define ERROR(...) report_config_error(filename, line_num, &errors, __VA_ARGS__)
4096     for(;;) {
4097         if (fgets(line, sizeof(line), f) == NULL)
4098             break;
4099         line_num++;
4100         p = line;
4101         while (isspace(*p))
4102             p++;
4103         if (*p == '\0' || *p == '#')
4104             continue;
4105
4106         get_arg(cmd, sizeof(cmd), &p);
4107
4108         if (!av_strcasecmp(cmd, "Port")) {
4109             get_arg(arg, sizeof(arg), &p);
4110             val = atoi(arg);
4111             if (val < 1 || val > 65536) {
4112                 ERROR("Invalid_port: %s\n", arg);
4113             }
4114             my_http_addr.sin_port = htons(val);
4115         } else if (!av_strcasecmp(cmd, "BindAddress")) {
4116             get_arg(arg, sizeof(arg), &p);
4117             if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
4118                 ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
4119             }
4120         } else if (!av_strcasecmp(cmd, "NoDaemon")) {
4121             ffserver_daemon = 0;
4122         } else if (!av_strcasecmp(cmd, "RTSPPort")) {
4123             get_arg(arg, sizeof(arg), &p);
4124             val = atoi(arg);
4125             if (val < 1 || val > 65536) {
4126                 ERROR("%s:%d: Invalid port: %s\n", arg);
4127             }
4128             my_rtsp_addr.sin_port = htons(atoi(arg));
4129         } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) {
4130             get_arg(arg, sizeof(arg), &p);
4131             if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
4132                 ERROR("Invalid host/IP address: %s\n", arg);
4133             }
4134         } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) {
4135             get_arg(arg, sizeof(arg), &p);
4136             val = atoi(arg);
4137             if (val < 1 || val > 65536) {
4138                 ERROR("Invalid MaxHTTPConnections: %s\n", arg);
4139             }
4140             nb_max_http_connections = val;
4141         } else if (!av_strcasecmp(cmd, "MaxClients")) {
4142             get_arg(arg, sizeof(arg), &p);
4143             val = atoi(arg);
4144             if (val < 1 || val > nb_max_http_connections) {
4145                 ERROR("Invalid MaxClients: %s\n", arg);
4146             } else {
4147                 nb_max_connections = val;
4148             }
4149         } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
4150             int64_t llval;
4151             get_arg(arg, sizeof(arg), &p);
4152             llval = atoll(arg);
4153             if (llval < 10 || llval > 10000000) {
4154                 ERROR("Invalid MaxBandwidth: %s\n", arg);
4155             } else
4156                 max_bandwidth = llval;
4157         } else if (!av_strcasecmp(cmd, "CustomLog")) {
4158             if (!ffserver_debug)
4159                 get_arg(logfilename, sizeof(logfilename), &p);
4160         } else if (!av_strcasecmp(cmd, "<Feed")) {
4161             /*********************************************/
4162             /* Feed related options */
4163             char *q;
4164             if (stream || feed) {
4165                 ERROR("Already in a tag\n");
4166             } else {
4167                 feed = av_mallocz(sizeof(FFStream));
4168                 get_arg(feed->filename, sizeof(feed->filename), &p);
4169                 q = strrchr(feed->filename, '>');
4170                 if (*q)
4171                     *q = '\0';
4172
4173                 for (s = first_feed; s; s = s->next) {
4174                     if (!strcmp(feed->filename, s->filename)) {
4175                         ERROR("Feed '%s' already registered\n", s->filename);
4176                     }
4177                 }
4178
4179                 feed->fmt = av_guess_format("ffm", NULL, NULL);
4180                 /* defaut feed file */
4181                 snprintf(feed->feed_filename, sizeof(feed->feed_filename),
4182                          "/tmp/%s.ffm", feed->filename);
4183                 feed->feed_max_size = 5 * 1024 * 1024;
4184                 feed->is_feed = 1;
4185                 feed->feed = feed; /* self feeding :-) */
4186
4187                 /* add in stream list */
4188                 *last_stream = feed;
4189                 last_stream = &feed->next;
4190                 /* add in feed list */
4191                 *last_feed = feed;
4192                 last_feed = &feed->next_feed;
4193             }
4194         } else if (!av_strcasecmp(cmd, "Launch")) {
4195             if (feed) {
4196                 int i;
4197
4198                 feed->child_argv = av_mallocz(64 * sizeof(char *));
4199
4200                 for (i = 0; i < 62; i++) {
4201                     get_arg(arg, sizeof(arg), &p);
4202                     if (!arg[0])
4203                         break;
4204
4205                     feed->child_argv[i] = av_strdup(arg);
4206                 }
4207
4208                 feed->child_argv[i] = av_malloc(30 + strlen(feed->filename));
4209
4210                 snprintf(feed->child_argv[i], 30+strlen(feed->filename),
4211                     "http://%s:%d/%s",
4212                         (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" :
4213                     inet_ntoa(my_http_addr.sin_addr),
4214                     ntohs(my_http_addr.sin_port), feed->filename);
4215             }
4216         } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) {
4217             if (feed) {
4218                 get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
4219                 feed->readonly = 1;
4220             } else if (stream) {
4221                 get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
4222             }
4223         } else if (!av_strcasecmp(cmd, "File")) {
4224             if (feed) {
4225                 get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
4226             } else if (stream)
4227                 get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
4228         } else if (!av_strcasecmp(cmd, "Truncate")) {
4229             if (feed) {
4230                 get_arg(arg, sizeof(arg), &p);
4231                 feed->truncate = strtod(arg, NULL);
4232             }
4233         } else if (!av_strcasecmp(cmd, "FileMaxSize")) {
4234             if (feed) {
4235                 char *p1;
4236                 double fsize;
4237
4238                 get_arg(arg, sizeof(arg), &p);
4239                 p1 = arg;
4240                 fsize = strtod(p1, &p1);
4241                 switch(toupper(*p1)) {
4242                 case 'K':
4243                     fsize *= 1024;
4244                     break;
4245                 case 'M':
4246                     fsize *= 1024 * 1024;
4247                     break;
4248                 case 'G':
4249                     fsize *= 1024 * 1024 * 1024;
4250                     break;
4251                 }
4252                 feed->feed_max_size = (int64_t)fsize;
4253                 if (feed->feed_max_size < FFM_PACKET_SIZE*4) {
4254                     ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4);
4255                 }
4256             }
4257         } else if (!av_strcasecmp(cmd, "</Feed>")) {
4258             if (!feed) {
4259                 ERROR("No corresponding <Feed> for </Feed>\n");
4260             }
4261             feed = NULL;
4262         } else if (!av_strcasecmp(cmd, "<Stream")) {
4263             /*********************************************/
4264             /* Stream related options */
4265             char *q;
4266             if (stream || feed) {
4267                 ERROR("Already in a tag\n");
4268             } else {
4269                 FFStream *s;
4270                 stream = av_mallocz(sizeof(FFStream));
4271                 get_arg(stream->filename, sizeof(stream->filename), &p);
4272                 q = strrchr(stream->filename, '>');
4273                 if (*q)
4274                     *q = '\0';
4275
4276                 for (s = first_stream; s; s = s->next) {
4277                     if (!strcmp(stream->filename, s->filename)) {
4278                         ERROR("Stream '%s' already registered\n", s->filename);
4279                     }
4280                 }
4281
4282                 stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL);
4283                 avcodec_get_context_defaults3(&video_enc, NULL);
4284                 avcodec_get_context_defaults3(&audio_enc, NULL);
4285
4286                 audio_id = AV_CODEC_ID_NONE;
4287                 video_id = AV_CODEC_ID_NONE;
4288                 if (stream->fmt) {
4289                     audio_id = stream->fmt->audio_codec;
4290                     video_id = stream->fmt->video_codec;
4291                 }
4292
4293                 *last_stream = stream;
4294                 last_stream = &stream->next;
4295             }
4296         } else if (!av_strcasecmp(cmd, "Feed")) {
4297             get_arg(arg, sizeof(arg), &p);
4298             if (stream) {
4299                 FFStream *sfeed;
4300
4301                 sfeed = first_feed;
4302                 while (sfeed != NULL) {
4303                     if (!strcmp(sfeed->filename, arg))
4304                         break;
4305                     sfeed = sfeed->next_feed;
4306                 }
4307                 if (!sfeed)
4308                     ERROR("feed '%s' not defined\n", arg);
4309                 else
4310                     stream->feed = sfeed;
4311             }
4312         } else if (!av_strcasecmp(cmd, "Format")) {
4313             get_arg(arg, sizeof(arg), &p);
4314             if (stream) {
4315                 if (!strcmp(arg, "status")) {
4316                     stream->stream_type = STREAM_TYPE_STATUS;
4317                     stream->fmt = NULL;
4318                 } else {
4319                     stream->stream_type = STREAM_TYPE_LIVE;
4320                     /* jpeg cannot be used here, so use single frame jpeg */
4321                     if (!strcmp(arg, "jpeg"))
4322                         strcpy(arg, "mjpeg");
4323                     stream->fmt = ffserver_guess_format(arg, NULL, NULL);
4324                     if (!stream->fmt) {
4325                         ERROR("Unknown Format: %s\n", arg);
4326                     }
4327                 }
4328                 if (stream->fmt) {
4329                     audio_id = stream->fmt->audio_codec;
4330                     video_id = stream->fmt->video_codec;
4331                 }
4332             }
4333         } else if (!av_strcasecmp(cmd, "InputFormat")) {
4334             get_arg(arg, sizeof(arg), &p);
4335             if (stream) {
4336                 stream->ifmt = av_find_input_format(arg);
4337                 if (!stream->ifmt) {
4338                     ERROR("Unknown input format: %s\n", arg);
4339                 }
4340             }
4341         } else if (!av_strcasecmp(cmd, "FaviconURL")) {
4342             if (stream && stream->stream_type == STREAM_TYPE_STATUS) {
4343                 get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
4344             } else {
4345                 ERROR("FaviconURL only permitted for status streams\n");
4346             }
4347         } else if (!av_strcasecmp(cmd, "Author")) {
4348             if (stream)
4349                 get_arg(stream->author, sizeof(stream->author), &p);
4350         } else if (!av_strcasecmp(cmd, "Comment")) {
4351             if (stream)
4352                 get_arg(stream->comment, sizeof(stream->comment), &p);
4353         } else if (!av_strcasecmp(cmd, "Copyright")) {
4354             if (stream)
4355                 get_arg(stream->copyright, sizeof(stream->copyright), &p);
4356         } else if (!av_strcasecmp(cmd, "Title")) {
4357             if (stream)
4358                 get_arg(stream->title, sizeof(stream->title), &p);
4359         } else if (!av_strcasecmp(cmd, "Preroll")) {
4360             get_arg(arg, sizeof(arg), &p);
4361             if (stream)
4362                 stream->prebuffer = atof(arg) * 1000;
4363         } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
4364             if (stream)
4365                 stream->send_on_key = 1;
4366         } else if (!av_strcasecmp(cmd, "AudioCodec")) {
4367             get_arg(arg, sizeof(arg), &p);
4368             audio_id = opt_audio_codec(arg);
4369             if (audio_id == AV_CODEC_ID_NONE) {
4370                 ERROR("Unknown AudioCodec: %s\n", arg);
4371             }
4372         } else if (!av_strcasecmp(cmd, "VideoCodec")) {
4373             get_arg(arg, sizeof(arg), &p);
4374             video_id = opt_video_codec(arg);
4375             if (video_id == AV_CODEC_ID_NONE) {
4376                 ERROR("Unknown VideoCodec: %s\n", arg);
4377             }
4378         } else if (!av_strcasecmp(cmd, "MaxTime")) {
4379             get_arg(arg, sizeof(arg), &p);
4380             if (stream)
4381                 stream->max_time = atof(arg) * 1000;
4382         } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
4383             get_arg(arg, sizeof(arg), &p);
4384             if (stream)
4385                 audio_enc.bit_rate = lrintf(atof(arg) * 1000);
4386         } else if (!av_strcasecmp(cmd, "AudioChannels")) {
4387             get_arg(arg, sizeof(arg), &p);
4388             if (stream)
4389                 audio_enc.channels = atoi(arg);
4390         } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
4391             get_arg(arg, sizeof(arg), &p);
4392             if (stream)
4393                 audio_enc.sample_rate = atoi(arg);
4394         } else if (!av_strcasecmp(cmd, "AudioQuality")) {
4395             get_arg(arg, sizeof(arg), &p);
4396             if (stream) {
4397 //                audio_enc.quality = atof(arg) * 1000;
4398             }
4399         } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
4400             if (stream) {
4401                 int minrate, maxrate;
4402
4403                 get_arg(arg, sizeof(arg), &p);
4404
4405                 if (sscanf(arg, "%d-%d", &minrate, &maxrate) == 2) {
4406                     video_enc.rc_min_rate = minrate * 1000;
4407                     video_enc.rc_max_rate = maxrate * 1000;
4408                 } else {
4409                     ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg);
4410                 }
4411             }
4412         } else if (!av_strcasecmp(cmd, "Debug")) {
4413             if (stream) {
4414                 get_arg(arg, sizeof(arg), &p);
4415                 video_enc.debug = strtol(arg,0,0);
4416             }
4417         } else if (!av_strcasecmp(cmd, "Strict")) {
4418             if (stream) {
4419                 get_arg(arg, sizeof(arg), &p);
4420                 video_enc.strict_std_compliance = atoi(arg);
4421             }
4422         } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
4423             if (stream) {
4424                 get_arg(arg, sizeof(arg), &p);
4425                 video_enc.rc_buffer_size = atoi(arg) * 8*1024;
4426             }
4427         } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
4428             if (stream) {
4429                 get_arg(arg, sizeof(arg), &p);
4430                 video_enc.bit_rate_tolerance = atoi(arg) * 1000;
4431             }
4432         } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
4433             get_arg(arg, sizeof(arg), &p);
4434             if (stream) {
4435                 video_enc.bit_rate = atoi(arg) * 1000;
4436             }
4437         } else if (!av_strcasecmp(cmd, "VideoSize")) {
4438             get_arg(arg, sizeof(arg), &p);
4439             if (stream) {
4440                 av_parse_video_size(&video_enc.width, &video_enc.height, arg);
4441                 if ((video_enc.width % 16) != 0 ||
4442                     (video_enc.height % 16) != 0) {
4443                     ERROR("Image size must be a multiple of 16\n");
4444                 }
4445             }
4446         } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
4447             get_arg(arg, sizeof(arg), &p);
4448             if (stream) {
4449                 AVRational frame_rate;
4450                 if (av_parse_video_rate(&frame_rate, arg) < 0) {
4451                     ERROR("Incorrect frame rate: %s\n", arg);
4452                 } else {
4453                     video_enc.time_base.num = frame_rate.den;
4454                     video_enc.time_base.den = frame_rate.num;
4455                 }
4456             }
4457         } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
4458             get_arg(arg, sizeof(arg), &p);
4459             if (stream)
4460                 video_enc.gop_size = atoi(arg);
4461         } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
4462             if (stream)
4463                 video_enc.gop_size = 1;
4464         } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
4465             if (stream)
4466                 video_enc.mb_decision = FF_MB_DECISION_BITS;
4467         } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
4468             if (stream) {
4469                 video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove
4470                 video_enc.flags |= CODEC_FLAG_4MV;
4471             }
4472         } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
4473                    !av_strcasecmp(cmd, "AVOptionAudio")) {
4474             char arg2[1024];
4475             AVCodecContext *avctx;
4476             int type;
4477             get_arg(arg, sizeof(arg), &p);
4478             get_arg(arg2, sizeof(arg2), &p);
4479             if (!av_strcasecmp(cmd, "AVOptionVideo")) {
4480                 avctx = &video_enc;
4481                 type = AV_OPT_FLAG_VIDEO_PARAM;
4482             } else {
4483                 avctx = &audio_enc;
4484                 type = AV_OPT_FLAG_AUDIO_PARAM;
4485             }
4486             if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
4487                 ERROR("AVOption error: %s %s\n", arg, arg2);
4488             }
4489         } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
4490                    !av_strcasecmp(cmd, "AVPresetAudio")) {
4491             AVCodecContext *avctx;
4492             int type;
4493             get_arg(arg, sizeof(arg), &p);
4494             if (!av_strcasecmp(cmd, "AVPresetVideo")) {
4495                 avctx = &video_enc;
4496                 video_enc.codec_id = video_id;
4497                 type = AV_OPT_FLAG_VIDEO_PARAM;
4498             } else {
4499                 avctx = &audio_enc;
4500                 audio_enc.codec_id = audio_id;
4501                 type = AV_OPT_FLAG_AUDIO_PARAM;
4502             }
4503             if (ffserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
4504                 ERROR("AVPreset error: %s\n", arg);
4505             }
4506         } else if (!av_strcasecmp(cmd, "VideoTag")) {
4507             get_arg(arg, sizeof(arg), &p);
4508             if ((strlen(arg) == 4) && stream)
4509                 video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
4510         } else if (!av_strcasecmp(cmd, "BitExact")) {
4511             if (stream)
4512                 video_enc.flags |= CODEC_FLAG_BITEXACT;
4513         } else if (!av_strcasecmp(cmd, "DctFastint")) {
4514             if (stream)
4515                 video_enc.dct_algo  = FF_DCT_FASTINT;
4516         } else if (!av_strcasecmp(cmd, "IdctSimple")) {
4517             if (stream)
4518                 video_enc.idct_algo = FF_IDCT_SIMPLE;
4519         } else if (!av_strcasecmp(cmd, "Qscale")) {
4520             get_arg(arg, sizeof(arg), &p);
4521             if (stream) {
4522                 video_enc.flags |= CODEC_FLAG_QSCALE;
4523                 video_enc.global_quality = FF_QP2LAMBDA * atoi(arg);
4524             }
4525         } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
4526             get_arg(arg, sizeof(arg), &p);
4527             if (stream) {
4528                 video_enc.max_qdiff = atoi(arg);
4529                 if (video_enc.max_qdiff < 1 || video_enc.max_qdiff > 31) {
4530                     ERROR("VideoQDiff out of range\n");
4531                 }
4532             }
4533         } else if (!av_strcasecmp(cmd, "VideoQMax")) {
4534             get_arg(arg, sizeof(arg), &p);
4535             if (stream) {
4536                 video_enc.qmax = atoi(arg);
4537                 if (video_enc.qmax < 1 || video_enc.qmax > 31) {
4538                     ERROR("VideoQMax out of range\n");
4539                 }
4540             }
4541         } else if (!av_strcasecmp(cmd, "VideoQMin")) {
4542             get_arg(arg, sizeof(arg), &p);
4543             if (stream) {
4544                 video_enc.qmin = atoi(arg);
4545                 if (video_enc.qmin < 1 || video_enc.qmin > 31) {
4546                     ERROR("VideoQMin out of range\n");
4547                 }
4548             }
4549         } else if (!av_strcasecmp(cmd, "LumaElim")) {
4550             get_arg(arg, sizeof(arg), &p);
4551             if (stream)
4552                 video_enc.luma_elim_threshold = atoi(arg);
4553         } else if (!av_strcasecmp(cmd, "ChromaElim")) {
4554             get_arg(arg, sizeof(arg), &p);
4555             if (stream)
4556                 video_enc.chroma_elim_threshold = atoi(arg);
4557         } else if (!av_strcasecmp(cmd, "LumiMask")) {
4558             get_arg(arg, sizeof(arg), &p);
4559             if (stream)
4560                 video_enc.lumi_masking = atof(arg);
4561         } else if (!av_strcasecmp(cmd, "DarkMask")) {
4562             get_arg(arg, sizeof(arg), &p);
4563             if (stream)
4564                 video_enc.dark_masking = atof(arg);
4565         } else if (!av_strcasecmp(cmd, "NoVideo")) {
4566             video_id = AV_CODEC_ID_NONE;
4567         } else if (!av_strcasecmp(cmd, "NoAudio")) {
4568             audio_id = AV_CODEC_ID_NONE;
4569         } else if (!av_strcasecmp(cmd, "ACL")) {
4570             parse_acl_row(stream, feed, NULL, p, filename, line_num);
4571         } else if (!av_strcasecmp(cmd, "DynamicACL")) {
4572             if (stream) {
4573                 get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p);
4574             }
4575         } else if (!av_strcasecmp(cmd, "RTSPOption")) {
4576             get_arg(arg, sizeof(arg), &p);
4577             if (stream) {
4578                 av_freep(&stream->rtsp_option);
4579                 stream->rtsp_option = av_strdup(arg);
4580             }
4581         } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
4582             get_arg(arg, sizeof(arg), &p);
4583             if (stream) {
4584                 if (resolve_host(&stream->multicast_ip, arg) != 0) {
4585                     ERROR("Invalid host/IP address: %s\n", arg);
4586                 }
4587                 stream->is_multicast = 1;
4588                 stream->loop = 1; /* default is looping */
4589             }
4590         } else if (!av_strcasecmp(cmd, "MulticastPort")) {
4591             get_arg(arg, sizeof(arg), &p);
4592             if (stream)
4593                 stream->multicast_port = atoi(arg);
4594         } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
4595             get_arg(arg, sizeof(arg), &p);
4596             if (stream)
4597                 stream->multicast_ttl = atoi(arg);
4598         } else if (!av_strcasecmp(cmd, "NoLoop")) {
4599             if (stream)
4600                 stream->loop = 0;
4601         } else if (!av_strcasecmp(cmd, "</Stream>")) {
4602             if (!stream) {
4603                 ERROR("No corresponding <Stream> for </Stream>\n");
4604             } else {
4605                 if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) {
4606                     if (audio_id != AV_CODEC_ID_NONE) {
4607                         audio_enc.codec_type = AVMEDIA_TYPE_AUDIO;
4608                         audio_enc.codec_id = audio_id;
4609                         add_codec(stream, &audio_enc);
4610                     }
4611                     if (video_id != AV_CODEC_ID_NONE) {
4612                         video_enc.codec_type = AVMEDIA_TYPE_VIDEO;
4613                         video_enc.codec_id = video_id;
4614                         add_codec(stream, &video_enc);
4615                     }
4616                 }
4617                 stream = NULL;
4618             }
4619         } else if (!av_strcasecmp(cmd, "<Redirect")) {
4620             /*********************************************/
4621             char *q;
4622             if (stream || feed || redirect) {
4623                 ERROR("Already in a tag\n");
4624             } else {
4625                 redirect = av_mallocz(sizeof(FFStream));
4626                 *last_stream = redirect;
4627                 last_stream = &redirect->next;
4628
4629                 get_arg(redirect->filename, sizeof(redirect->filename), &p);
4630                 q = strrchr(redirect->filename, '>');
4631                 if (*q)
4632                     *q = '\0';
4633                 redirect->stream_type = STREAM_TYPE_REDIRECT;
4634             }
4635         } else if (!av_strcasecmp(cmd, "URL")) {
4636             if (redirect)
4637                 get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p);
4638         } else if (!av_strcasecmp(cmd, "</Redirect>")) {
4639             if (!redirect) {
4640                 ERROR("No corresponding <Redirect> for </Redirect>\n");
4641             } else {
4642                 if (!redirect->feed_filename[0]) {
4643                     ERROR("No URL found for <Redirect>\n");
4644                 }
4645                 redirect = NULL;
4646             }
4647         } else if (!av_strcasecmp(cmd, "LoadModule")) {
4648             get_arg(arg, sizeof(arg), &p);
4649 #if HAVE_DLOPEN
4650             load_module(arg);
4651 #else
4652             ERROR("Module support not compiled into this version: '%s'\n", arg);
4653 #endif
4654         } else {
4655             ERROR("Incorrect keyword: '%s'\n", cmd);
4656         }
4657     }
4658 #undef ERROR
4659
4660     fclose(f);
4661     if (errors)
4662         return -1;
4663     else
4664         return 0;
4665 }
4666
4667 static void handle_child_exit(int sig)
4668 {
4669     pid_t pid;
4670     int status;
4671
4672     while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
4673         FFStream *feed;
4674
4675         for (feed = first_feed; feed; feed = feed->next) {
4676             if (feed->pid == pid) {
4677                 int uptime = time(0) - feed->pid_start;
4678
4679                 feed->pid = 0;
4680                 fprintf(stderr, "%s: Pid %d exited with status %d after %d seconds\n", feed->filename, pid, status, uptime);
4681
4682                 if (uptime < 30)
4683                     /* Turn off any more restarts */
4684                     feed->child_argv = 0;
4685             }
4686         }
4687     }
4688
4689     need_to_start_children = 1;
4690 }
4691
4692 static void opt_debug(void)
4693 {
4694     ffserver_debug = 1;
4695     ffserver_daemon = 0;
4696     logfilename[0] = '-';
4697 }
4698
4699 void show_help_default(const char *opt, const char *arg)
4700 {
4701     printf("usage: ffserver [options]\n"
4702            "Hyper fast multi format Audio/Video streaming server\n");
4703     printf("\n");
4704     show_help_options(options, "Main options:", 0, 0, 0);
4705 }
4706
4707 static const OptionDef options[] = {
4708 #include "cmdutils_common_opts.h"
4709     { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" },
4710     { "d", 0, {(void*)opt_debug}, "enable debug mode" },
4711     { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/ffserver.conf", "configfile" },
4712     { NULL },
4713 };
4714
4715 int main(int argc, char **argv)
4716 {
4717     struct sigaction sigact = { { 0 } };
4718
4719     parse_loglevel(argc, argv, options);
4720     av_register_all();
4721     avformat_network_init();
4722
4723     show_banner(argc, argv, options);
4724
4725     my_program_name = argv[0];
4726     my_program_dir = getcwd(0, 0);
4727     ffserver_daemon = 1;
4728
4729     parse_options(NULL, argc, argv, options, NULL);
4730
4731     unsetenv("http_proxy");             /* Kill the http_proxy */
4732
4733     av_lfg_init(&random_state, av_get_random_seed());
4734
4735     sigact.sa_handler = handle_child_exit;
4736     sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
4737     sigaction(SIGCHLD, &sigact, 0);
4738
4739     if (parse_ffconfig(config_filename) < 0) {
4740         fprintf(stderr, "Incorrect config file - exiting.\n");
4741         exit(1);
4742     }
4743
4744     /* open log file if needed */
4745     if (logfilename[0] != '\0') {
4746         if (!strcmp(logfilename, "-"))
4747             logfile = stdout;
4748         else
4749             logfile = fopen(logfilename, "a");
4750         av_log_set_callback(http_av_log);
4751     }
4752
4753     build_file_streams();
4754
4755     build_feed_streams();
4756
4757     compute_bandwidth();
4758
4759     /* put the process in background and detach it from its TTY */
4760     if (ffserver_daemon) {
4761         int pid;
4762
4763         pid = fork();
4764         if (pid < 0) {
4765             perror("fork");
4766             exit(1);
4767         } else if (pid > 0) {
4768             /* parent : exit */
4769             exit(0);
4770         } else {
4771             /* child */
4772             setsid();
4773             close(0);
4774             open("/dev/null", O_RDWR);
4775             if (strcmp(logfilename, "-") != 0) {
4776                 close(1);
4777                 dup(0);
4778             }
4779             close(2);
4780             dup(0);
4781         }
4782     }
4783
4784     /* signal init */
4785     signal(SIGPIPE, SIG_IGN);
4786
4787     if (ffserver_daemon)
4788         chdir("/");
4789
4790     if (http_server() < 0) {
4791         http_log("Could not start server\n");
4792         exit(1);
4793     }
4794
4795     return 0;
4796 }