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