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