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