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