]> git.sesse.net Git - ffmpeg/blob - ffserver.c
lavc/adpcm_data: fix const misplacement
[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         ctx = avformat_alloc_context();
2279         c->fmt_ctx = *ctx;
2280         av_freep(&ctx);
2281         av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0);
2282         c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
2283
2284         for(i=0;i<c->stream->nb_streams;i++) {
2285             AVStream *src;
2286             c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
2287             /* if file or feed, then just take streams from FFStream struct */
2288             if (!c->stream->feed ||
2289                 c->stream->feed == c->stream)
2290                 src = c->stream->streams[i];
2291             else
2292                 src = c->stream->feed->streams[c->stream->feed_streams[i]];
2293
2294             *(c->fmt_ctx.streams[i]) = *src;
2295             c->fmt_ctx.streams[i]->priv_data = 0;
2296             c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in
2297                                            AVStream, not in codec */
2298         }
2299         /* set output format parameters */
2300         c->fmt_ctx.oformat = c->stream->fmt;
2301         c->fmt_ctx.nb_streams = c->stream->nb_streams;
2302
2303         c->got_key_frame = 0;
2304
2305         /* prepare header and save header data in a stream */
2306         if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
2307             /* XXX: potential leak */
2308             return -1;
2309         }
2310         c->fmt_ctx.pb->seekable = 0;
2311
2312         /*
2313          * HACK to avoid mpeg ps muxer to spit many underflow errors
2314          * Default value from FFmpeg
2315          * Try to set it use configuration option
2316          */
2317         c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
2318
2319         if ((ret = avformat_write_header(&c->fmt_ctx, NULL)) < 0) {
2320             http_log("Error writing output header for stream '%s': %s\n",
2321                      c->stream->filename, av_err2str(ret));
2322             return ret;
2323         }
2324         av_dict_free(&c->fmt_ctx.metadata);
2325
2326         len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
2327         c->buffer_ptr = c->pb_buffer;
2328         c->buffer_end = c->pb_buffer + len;
2329
2330         c->state = HTTPSTATE_SEND_DATA;
2331         c->last_packet_sent = 0;
2332         break;
2333     case HTTPSTATE_SEND_DATA:
2334         /* find a new packet */
2335         /* read a packet from the input stream */
2336         if (c->stream->feed)
2337             ffm_set_write_index(c->fmt_in,
2338                                 c->stream->feed->feed_write_index,
2339                                 c->stream->feed->feed_size);
2340
2341         if (c->stream->max_time &&
2342             c->stream->max_time + c->start_time - cur_time < 0)
2343             /* We have timed out */
2344             c->state = HTTPSTATE_SEND_DATA_TRAILER;
2345         else {
2346             AVPacket pkt;
2347         redo:
2348             ret = av_read_frame(c->fmt_in, &pkt);
2349             if (ret < 0) {
2350                 if (c->stream->feed) {
2351                     /* if coming from feed, it means we reached the end of the
2352                        ffm file, so must wait for more data */
2353                     c->state = HTTPSTATE_WAIT_FEED;
2354                     return 1; /* state changed */
2355                 } else if (ret == AVERROR(EAGAIN)) {
2356                     /* input not ready, come back later */
2357                     return 0;
2358                 } else {
2359                     if (c->stream->loop) {
2360                         avformat_close_input(&c->fmt_in);
2361                         if (open_input_stream(c, "") < 0)
2362                             goto no_loop;
2363                         goto redo;
2364                     } else {
2365                     no_loop:
2366                         /* must send trailer now because eof or error */
2367                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2368                     }
2369                 }
2370             } else {
2371                 int source_index = pkt.stream_index;
2372                 /* update first pts if needed */
2373                 if (c->first_pts == AV_NOPTS_VALUE) {
2374                     c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
2375                     c->start_time = cur_time;
2376                 }
2377                 /* send it to the appropriate stream */
2378                 if (c->stream->feed) {
2379                     /* if coming from a feed, select the right stream */
2380                     if (c->switch_pending) {
2381                         c->switch_pending = 0;
2382                         for(i=0;i<c->stream->nb_streams;i++) {
2383                             if (c->switch_feed_streams[i] == pkt.stream_index)
2384                                 if (pkt.flags & AV_PKT_FLAG_KEY)
2385                                     c->switch_feed_streams[i] = -1;
2386                             if (c->switch_feed_streams[i] >= 0)
2387                                 c->switch_pending = 1;
2388                         }
2389                     }
2390                     for(i=0;i<c->stream->nb_streams;i++) {
2391                         if (c->stream->feed_streams[i] == pkt.stream_index) {
2392                             AVStream *st = c->fmt_in->streams[source_index];
2393                             pkt.stream_index = i;
2394                             if (pkt.flags & AV_PKT_FLAG_KEY &&
2395                                 (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
2396                                  c->stream->nb_streams == 1))
2397                                 c->got_key_frame = 1;
2398                             if (!c->stream->send_on_key || c->got_key_frame)
2399                                 goto send_it;
2400                         }
2401                     }
2402                 } else {
2403                     AVCodecContext *codec;
2404                     AVStream *ist, *ost;
2405                 send_it:
2406                     ist = c->fmt_in->streams[source_index];
2407                     /* specific handling for RTP: we use several
2408                        output stream (one for each RTP
2409                        connection). XXX: need more abstract handling */
2410                     if (c->is_packetized) {
2411                         /* compute send time and duration */
2412                         c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
2413                         c->cur_pts -= c->first_pts;
2414                         c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
2415                         /* find RTP context */
2416                         c->packet_stream_index = pkt.stream_index;
2417                         ctx = c->rtp_ctx[c->packet_stream_index];
2418                         if(!ctx) {
2419                             av_free_packet(&pkt);
2420                             break;
2421                         }
2422                         codec = ctx->streams[0]->codec;
2423                         /* only one stream per RTP connection */
2424                         pkt.stream_index = 0;
2425                     } else {
2426                         ctx = &c->fmt_ctx;
2427                         /* Fudge here */
2428                         codec = ctx->streams[pkt.stream_index]->codec;
2429                     }
2430
2431                     if (c->is_packetized) {
2432                         int max_packet_size;
2433                         if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
2434                             max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
2435                         else
2436                             max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
2437                         ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size);
2438                     } else {
2439                         ret = avio_open_dyn_buf(&ctx->pb);
2440                     }
2441                     if (ret < 0) {
2442                         /* XXX: potential leak */
2443                         return -1;
2444                     }
2445                     ost = ctx->streams[pkt.stream_index];
2446
2447                     ctx->pb->seekable = 0;
2448                     if (pkt.dts != AV_NOPTS_VALUE)
2449                         pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base);
2450                     if (pkt.pts != AV_NOPTS_VALUE)
2451                         pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base);
2452                     pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base);
2453                     if ((ret = av_write_frame(ctx, &pkt)) < 0) {
2454                         http_log("Error writing frame to output for stream '%s': %s\n",
2455                                  c->stream->filename, av_err2str(ret));
2456                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2457                     }
2458
2459                     len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2460                     c->cur_frame_bytes = len;
2461                     c->buffer_ptr = c->pb_buffer;
2462                     c->buffer_end = c->pb_buffer + len;
2463
2464                     codec->frame_number++;
2465                     if (len == 0) {
2466                         av_free_packet(&pkt);
2467                         goto redo;
2468                     }
2469                 }
2470                 av_free_packet(&pkt);
2471             }
2472         }
2473         break;
2474     default:
2475     case HTTPSTATE_SEND_DATA_TRAILER:
2476         /* last packet test ? */
2477         if (c->last_packet_sent || c->is_packetized)
2478             return -1;
2479         ctx = &c->fmt_ctx;
2480         /* prepare header */
2481         if (avio_open_dyn_buf(&ctx->pb) < 0) {
2482             /* XXX: potential leak */
2483             return -1;
2484         }
2485         c->fmt_ctx.pb->seekable = 0;
2486         av_write_trailer(ctx);
2487         len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2488         c->buffer_ptr = c->pb_buffer;
2489         c->buffer_end = c->pb_buffer + len;
2490
2491         c->last_packet_sent = 1;
2492         break;
2493     }
2494     return 0;
2495 }
2496
2497 /* should convert the format at the same time */
2498 /* send data starting at c->buffer_ptr to the output connection
2499    (either UDP or TCP connection) */
2500 static int http_send_data(HTTPContext *c)
2501 {
2502     int len, ret;
2503
2504     for(;;) {
2505         if (c->buffer_ptr >= c->buffer_end) {
2506             ret = http_prepare_data(c);
2507             if (ret < 0)
2508                 return -1;
2509             else if (ret != 0)
2510                 /* state change requested */
2511                 break;
2512         } else {
2513             if (c->is_packetized) {
2514                 /* RTP data output */
2515                 len = c->buffer_end - c->buffer_ptr;
2516                 if (len < 4) {
2517                     /* fail safe - should never happen */
2518                 fail1:
2519                     c->buffer_ptr = c->buffer_end;
2520                     return 0;
2521                 }
2522                 len = (c->buffer_ptr[0] << 24) |
2523                     (c->buffer_ptr[1] << 16) |
2524                     (c->buffer_ptr[2] << 8) |
2525                     (c->buffer_ptr[3]);
2526                 if (len > (c->buffer_end - c->buffer_ptr))
2527                     goto fail1;
2528                 if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
2529                     /* nothing to send yet: we can wait */
2530                     return 0;
2531                 }
2532
2533                 c->data_count += len;
2534                 update_datarate(&c->datarate, c->data_count);
2535                 if (c->stream)
2536                     c->stream->bytes_served += len;
2537
2538                 if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
2539                     /* RTP packets are sent inside the RTSP TCP connection */
2540                     AVIOContext *pb;
2541                     int interleaved_index, size;
2542                     uint8_t header[4];
2543                     HTTPContext *rtsp_c;
2544
2545                     rtsp_c = c->rtsp_c;
2546                     /* if no RTSP connection left, error */
2547                     if (!rtsp_c)
2548                         return -1;
2549                     /* if already sending something, then wait. */
2550                     if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
2551                         break;
2552                     if (avio_open_dyn_buf(&pb) < 0)
2553                         goto fail1;
2554                     interleaved_index = c->packet_stream_index * 2;
2555                     /* RTCP packets are sent at odd indexes */
2556                     if (c->buffer_ptr[1] == 200)
2557                         interleaved_index++;
2558                     /* write RTSP TCP header */
2559                     header[0] = '$';
2560                     header[1] = interleaved_index;
2561                     header[2] = len >> 8;
2562                     header[3] = len;
2563                     avio_write(pb, header, 4);
2564                     /* write RTP packet data */
2565                     c->buffer_ptr += 4;
2566                     avio_write(pb, c->buffer_ptr, len);
2567                     size = avio_close_dyn_buf(pb, &c->packet_buffer);
2568                     /* prepare asynchronous TCP sending */
2569                     rtsp_c->packet_buffer_ptr = c->packet_buffer;
2570                     rtsp_c->packet_buffer_end = c->packet_buffer + size;
2571                     c->buffer_ptr += len;
2572
2573                     /* send everything we can NOW */
2574                     len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
2575                                 rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
2576                     if (len > 0)
2577                         rtsp_c->packet_buffer_ptr += len;
2578                     if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
2579                         /* if we could not send all the data, we will
2580                            send it later, so a new state is needed to
2581                            "lock" the RTSP TCP connection */
2582                         rtsp_c->state = RTSPSTATE_SEND_PACKET;
2583                         break;
2584                     } else
2585                         /* all data has been sent */
2586                         av_freep(&c->packet_buffer);
2587                 } else {
2588                     /* send RTP packet directly in UDP */
2589                     c->buffer_ptr += 4;
2590                     ffurl_write(c->rtp_handles[c->packet_stream_index],
2591                                 c->buffer_ptr, len);
2592                     c->buffer_ptr += len;
2593                     /* here we continue as we can send several packets per 10 ms slot */
2594                 }
2595             } else {
2596                 /* TCP data output */
2597                 len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
2598                 if (len < 0) {
2599                     if (ff_neterrno() != AVERROR(EAGAIN) &&
2600                         ff_neterrno() != AVERROR(EINTR))
2601                         /* error : close connection */
2602                         return -1;
2603                     else
2604                         return 0;
2605                 } else
2606                     c->buffer_ptr += len;
2607
2608                 c->data_count += len;
2609                 update_datarate(&c->datarate, c->data_count);
2610                 if (c->stream)
2611                     c->stream->bytes_served += len;
2612                 break;
2613             }
2614         }
2615     } /* for(;;) */
2616     return 0;
2617 }
2618
2619 static int http_start_receive_data(HTTPContext *c)
2620 {
2621     int fd;
2622     int ret;
2623
2624     if (c->stream->feed_opened) {
2625         http_log("Stream feed '%s' was not opened\n", c->stream->feed_filename);
2626         return AVERROR(EINVAL);
2627     }
2628
2629     /* Don't permit writing to this one */
2630     if (c->stream->readonly) {
2631         http_log("Cannot write to read-only file '%s'\n", c->stream->feed_filename);
2632         return AVERROR(EINVAL);
2633     }
2634
2635     /* open feed */
2636     fd = open(c->stream->feed_filename, O_RDWR);
2637     if (fd < 0) {
2638         ret = AVERROR(errno);
2639         http_log("Could not open feed file '%s': %s\n",
2640                  c->stream->feed_filename, strerror(errno));
2641         return ret;
2642     }
2643     c->feed_fd = fd;
2644
2645     if (c->stream->truncate) {
2646         /* truncate feed file */
2647         ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
2648         http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
2649         if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
2650             ret = AVERROR(errno);
2651             http_log("Error truncating feed file '%s': %s\n",
2652                      c->stream->feed_filename, strerror(errno));
2653             return ret;
2654         }
2655     } else {
2656         ret = ffm_read_write_index(fd);
2657         if (ret < 0) {
2658             http_log("Error reading write index from feed file '%s': %s\n",
2659                      c->stream->feed_filename, strerror(errno));
2660             return ret;
2661         } else {
2662             c->stream->feed_write_index = ret;
2663         }
2664     }
2665
2666     c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
2667     c->stream->feed_size = lseek(fd, 0, SEEK_END);
2668     lseek(fd, 0, SEEK_SET);
2669
2670     /* init buffer input */
2671     c->buffer_ptr = c->buffer;
2672     c->buffer_end = c->buffer + FFM_PACKET_SIZE;
2673     c->stream->feed_opened = 1;
2674     c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
2675     return 0;
2676 }
2677
2678 static int http_receive_data(HTTPContext *c)
2679 {
2680     HTTPContext *c1;
2681     int len, loop_run = 0;
2682
2683     while (c->chunked_encoding && !c->chunk_size &&
2684            c->buffer_end > c->buffer_ptr) {
2685         /* read chunk header, if present */
2686         len = recv(c->fd, c->buffer_ptr, 1, 0);
2687
2688         if (len < 0) {
2689             if (ff_neterrno() != AVERROR(EAGAIN) &&
2690                 ff_neterrno() != AVERROR(EINTR))
2691                 /* error : close connection */
2692                 goto fail;
2693             return 0;
2694         } else if (len == 0) {
2695             /* end of connection : close it */
2696             goto fail;
2697         } else if (c->buffer_ptr - c->buffer >= 2 &&
2698                    !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
2699             c->chunk_size = strtol(c->buffer, 0, 16);
2700             if (c->chunk_size == 0) // end of stream
2701                 goto fail;
2702             c->buffer_ptr = c->buffer;
2703             break;
2704         } else if (++loop_run > 10) {
2705             /* no chunk header, abort */
2706             goto fail;
2707         } else {
2708             c->buffer_ptr++;
2709         }
2710     }
2711
2712     if (c->buffer_end > c->buffer_ptr) {
2713         len = recv(c->fd, c->buffer_ptr,
2714                    FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
2715         if (len < 0) {
2716             if (ff_neterrno() != AVERROR(EAGAIN) &&
2717                 ff_neterrno() != AVERROR(EINTR))
2718                 /* error : close connection */
2719                 goto fail;
2720         } else if (len == 0)
2721             /* end of connection : close it */
2722             goto fail;
2723         else {
2724             c->chunk_size -= len;
2725             c->buffer_ptr += len;
2726             c->data_count += len;
2727             update_datarate(&c->datarate, c->data_count);
2728         }
2729     }
2730
2731     if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
2732         if (c->buffer[0] != 'f' ||
2733             c->buffer[1] != 'm') {
2734             http_log("Feed stream has become desynchronized -- disconnecting\n");
2735             goto fail;
2736         }
2737     }
2738
2739     if (c->buffer_ptr >= c->buffer_end) {
2740         FFStream *feed = c->stream;
2741         /* a packet has been received : write it in the store, except
2742            if header */
2743         if (c->data_count > FFM_PACKET_SIZE) {
2744             /* XXX: use llseek or url_seek */
2745             lseek(c->feed_fd, feed->feed_write_index, SEEK_SET);
2746             if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
2747                 http_log("Error writing to feed file: %s\n", strerror(errno));
2748                 goto fail;
2749             }
2750
2751             feed->feed_write_index += FFM_PACKET_SIZE;
2752             /* update file size */
2753             if (feed->feed_write_index > c->stream->feed_size)
2754                 feed->feed_size = feed->feed_write_index;
2755
2756             /* handle wrap around if max file size reached */
2757             if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size)
2758                 feed->feed_write_index = FFM_PACKET_SIZE;
2759
2760             /* write index */
2761             if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
2762                 http_log("Error writing index to feed file: %s\n", strerror(errno));
2763                 goto fail;
2764             }
2765
2766             /* wake up any waiting connections */
2767             for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2768                 if (c1->state == HTTPSTATE_WAIT_FEED &&
2769                     c1->stream->feed == c->stream->feed)
2770                     c1->state = HTTPSTATE_SEND_DATA;
2771             }
2772         } else {
2773             /* We have a header in our hands that contains useful data */
2774             AVFormatContext *s = avformat_alloc_context();
2775             AVIOContext *pb;
2776             AVInputFormat *fmt_in;
2777             int i;
2778
2779             if (!s)
2780                 goto fail;
2781
2782             /* use feed output format name to find corresponding input format */
2783             fmt_in = av_find_input_format(feed->fmt->name);
2784             if (!fmt_in)
2785                 goto fail;
2786
2787             pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
2788                                     0, NULL, NULL, NULL, NULL);
2789             pb->seekable = 0;
2790
2791             s->pb = pb;
2792             if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) {
2793                 av_free(pb);
2794                 goto fail;
2795             }
2796
2797             /* Now we have the actual streams */
2798             if (s->nb_streams != feed->nb_streams) {
2799                 avformat_close_input(&s);
2800                 av_free(pb);
2801                 http_log("Feed '%s' stream number does not match registered feed\n",
2802                          c->stream->feed_filename);
2803                 goto fail;
2804             }
2805
2806             for (i = 0; i < s->nb_streams; i++) {
2807                 AVStream *fst = feed->streams[i];
2808                 AVStream *st = s->streams[i];
2809                 avcodec_copy_context(fst->codec, st->codec);
2810             }
2811
2812             avformat_close_input(&s);
2813             av_free(pb);
2814         }
2815         c->buffer_ptr = c->buffer;
2816     }
2817
2818     return 0;
2819  fail:
2820     c->stream->feed_opened = 0;
2821     close(c->feed_fd);
2822     /* wake up any waiting connections to stop waiting for feed */
2823     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2824         if (c1->state == HTTPSTATE_WAIT_FEED &&
2825             c1->stream->feed == c->stream->feed)
2826             c1->state = HTTPSTATE_SEND_DATA_TRAILER;
2827     }
2828     return -1;
2829 }
2830
2831 /********************************************************************/
2832 /* RTSP handling */
2833
2834 static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
2835 {
2836     const char *str;
2837     time_t ti;
2838     struct tm *tm;
2839     char buf2[32];
2840
2841     switch(error_number) {
2842     case RTSP_STATUS_OK:
2843         str = "OK";
2844         break;
2845     case RTSP_STATUS_METHOD:
2846         str = "Method Not Allowed";
2847         break;
2848     case RTSP_STATUS_BANDWIDTH:
2849         str = "Not Enough Bandwidth";
2850         break;
2851     case RTSP_STATUS_SESSION:
2852         str = "Session Not Found";
2853         break;
2854     case RTSP_STATUS_STATE:
2855         str = "Method Not Valid in This State";
2856         break;
2857     case RTSP_STATUS_AGGREGATE:
2858         str = "Aggregate operation not allowed";
2859         break;
2860     case RTSP_STATUS_ONLY_AGGREGATE:
2861         str = "Only aggregate operation allowed";
2862         break;
2863     case RTSP_STATUS_TRANSPORT:
2864         str = "Unsupported transport";
2865         break;
2866     case RTSP_STATUS_INTERNAL:
2867         str = "Internal Server Error";
2868         break;
2869     case RTSP_STATUS_SERVICE:
2870         str = "Service Unavailable";
2871         break;
2872     case RTSP_STATUS_VERSION:
2873         str = "RTSP Version not supported";
2874         break;
2875     default:
2876         str = "Unknown Error";
2877         break;
2878     }
2879
2880     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
2881     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
2882
2883     /* output GMT time */
2884     ti = time(NULL);
2885     tm = gmtime(&ti);
2886     strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
2887     avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
2888 }
2889
2890 static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
2891 {
2892     rtsp_reply_header(c, error_number);
2893     avio_printf(c->pb, "\r\n");
2894 }
2895
2896 static int rtsp_parse_request(HTTPContext *c)
2897 {
2898     const char *p, *p1, *p2;
2899     char cmd[32];
2900     char url[1024];
2901     char protocol[32];
2902     char line[1024];
2903     int len;
2904     RTSPMessageHeader header1 = { 0 }, *header = &header1;
2905
2906     c->buffer_ptr[0] = '\0';
2907     p = c->buffer;
2908
2909     get_word(cmd, sizeof(cmd), &p);
2910     get_word(url, sizeof(url), &p);
2911     get_word(protocol, sizeof(protocol), &p);
2912
2913     av_strlcpy(c->method, cmd, sizeof(c->method));
2914     av_strlcpy(c->url, url, sizeof(c->url));
2915     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
2916
2917     if (avio_open_dyn_buf(&c->pb) < 0) {
2918         /* XXX: cannot do more */
2919         c->pb = NULL; /* safety */
2920         return -1;
2921     }
2922
2923     /* check version name */
2924     if (strcmp(protocol, "RTSP/1.0") != 0) {
2925         rtsp_reply_error(c, RTSP_STATUS_VERSION);
2926         goto the_end;
2927     }
2928
2929     /* parse each header line */
2930     /* skip to next line */
2931     while (*p != '\n' && *p != '\0')
2932         p++;
2933     if (*p == '\n')
2934         p++;
2935     while (*p != '\0') {
2936         p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
2937         if (!p1)
2938             break;
2939         p2 = p1;
2940         if (p2 > p && p2[-1] == '\r')
2941             p2--;
2942         /* skip empty line */
2943         if (p2 == p)
2944             break;
2945         len = p2 - p;
2946         if (len > sizeof(line) - 1)
2947             len = sizeof(line) - 1;
2948         memcpy(line, p, len);
2949         line[len] = '\0';
2950         ff_rtsp_parse_line(header, line, NULL, NULL);
2951         p = p1 + 1;
2952     }
2953
2954     /* handle sequence number */
2955     c->seq = header->seq;
2956
2957     if (!strcmp(cmd, "DESCRIBE"))
2958         rtsp_cmd_describe(c, url);
2959     else if (!strcmp(cmd, "OPTIONS"))
2960         rtsp_cmd_options(c, url);
2961     else if (!strcmp(cmd, "SETUP"))
2962         rtsp_cmd_setup(c, url, header);
2963     else if (!strcmp(cmd, "PLAY"))
2964         rtsp_cmd_play(c, url, header);
2965     else if (!strcmp(cmd, "PAUSE"))
2966         rtsp_cmd_pause(c, url, header);
2967     else if (!strcmp(cmd, "TEARDOWN"))
2968         rtsp_cmd_teardown(c, url, header);
2969     else
2970         rtsp_reply_error(c, RTSP_STATUS_METHOD);
2971
2972  the_end:
2973     len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
2974     c->pb = NULL; /* safety */
2975     if (len < 0) {
2976         /* XXX: cannot do more */
2977         return -1;
2978     }
2979     c->buffer_ptr = c->pb_buffer;
2980     c->buffer_end = c->pb_buffer + len;
2981     c->state = RTSPSTATE_SEND_REPLY;
2982     return 0;
2983 }
2984
2985 static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
2986                                    struct in_addr my_ip)
2987 {
2988     AVFormatContext *avc;
2989     AVStream *avs = NULL;
2990     AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
2991     AVDictionaryEntry *entry = av_dict_get(stream->metadata, "title", NULL, 0);
2992     int i;
2993
2994     avc =  avformat_alloc_context();
2995     if (avc == NULL || !rtp_format) {
2996         return -1;
2997     }
2998     avc->oformat = rtp_format;
2999     av_dict_set(&avc->metadata, "title",
3000                 entry ? entry->value : "No Title", 0);
3001     avc->nb_streams = stream->nb_streams;
3002     if (stream->is_multicast) {
3003         snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
3004                  inet_ntoa(stream->multicast_ip),
3005                  stream->multicast_port, stream->multicast_ttl);
3006     } else {
3007         snprintf(avc->filename, 1024, "rtp://0.0.0.0");
3008     }
3009
3010     if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) ||
3011         !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams))))
3012         goto sdp_done;
3013     if (avc->nb_streams >= INT_MAX/sizeof(*avs) ||
3014         !(avs = av_malloc(avc->nb_streams * sizeof(*avs))))
3015         goto sdp_done;
3016
3017     for(i = 0; i < stream->nb_streams; i++) {
3018         avc->streams[i] = &avs[i];
3019         avc->streams[i]->codec = stream->streams[i]->codec;
3020     }
3021     *pbuffer = av_mallocz(2048);
3022     av_sdp_create(&avc, 1, *pbuffer, 2048);
3023
3024  sdp_done:
3025     av_free(avc->streams);
3026     av_dict_free(&avc->metadata);
3027     av_free(avc);
3028     av_free(avs);
3029
3030     return strlen(*pbuffer);
3031 }
3032
3033 static void rtsp_cmd_options(HTTPContext *c, const char *url)
3034 {
3035 //    rtsp_reply_header(c, RTSP_STATUS_OK);
3036     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
3037     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
3038     avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
3039     avio_printf(c->pb, "\r\n");
3040 }
3041
3042 static void rtsp_cmd_describe(HTTPContext *c, const char *url)
3043 {
3044     FFStream *stream;
3045     char path1[1024];
3046     const char *path;
3047     uint8_t *content;
3048     int content_length;
3049     socklen_t len;
3050     struct sockaddr_in my_addr;
3051
3052     /* find which url is asked */
3053     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3054     path = path1;
3055     if (*path == '/')
3056         path++;
3057
3058     for(stream = first_stream; stream != NULL; stream = stream->next) {
3059         if (!stream->is_feed &&
3060             stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
3061             !strcmp(path, stream->filename)) {
3062             goto found;
3063         }
3064     }
3065     /* no stream found */
3066     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
3067     return;
3068
3069  found:
3070     /* prepare the media description in sdp format */
3071
3072     /* get the host IP */
3073     len = sizeof(my_addr);
3074     getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
3075     content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);
3076     if (content_length < 0) {
3077         rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
3078         return;
3079     }
3080     rtsp_reply_header(c, RTSP_STATUS_OK);
3081     avio_printf(c->pb, "Content-Base: %s/\r\n", url);
3082     avio_printf(c->pb, "Content-Type: application/sdp\r\n");
3083     avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
3084     avio_printf(c->pb, "\r\n");
3085     avio_write(c->pb, content, content_length);
3086     av_free(content);
3087 }
3088
3089 static HTTPContext *find_rtp_session(const char *session_id)
3090 {
3091     HTTPContext *c;
3092
3093     if (session_id[0] == '\0')
3094         return NULL;
3095
3096     for(c = first_http_ctx; c != NULL; c = c->next) {
3097         if (!strcmp(c->session_id, session_id))
3098             return c;
3099     }
3100     return NULL;
3101 }
3102
3103 static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
3104 {
3105     RTSPTransportField *th;
3106     int i;
3107
3108     for(i=0;i<h->nb_transports;i++) {
3109         th = &h->transports[i];
3110         if (th->lower_transport == lower_transport)
3111             return th;
3112     }
3113     return NULL;
3114 }
3115
3116 static void rtsp_cmd_setup(HTTPContext *c, const char *url,
3117                            RTSPMessageHeader *h)
3118 {
3119     FFStream *stream;
3120     int stream_index, rtp_port, rtcp_port;
3121     char buf[1024];
3122     char path1[1024];
3123     const char *path;
3124     HTTPContext *rtp_c;
3125     RTSPTransportField *th;
3126     struct sockaddr_in dest_addr;
3127     RTSPActionServerSetup setup;
3128
3129     /* find which url is asked */
3130     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3131     path = path1;
3132     if (*path == '/')
3133         path++;
3134
3135     /* now check each stream */
3136     for(stream = first_stream; stream != NULL; stream = stream->next) {
3137         if (!stream->is_feed &&
3138             stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
3139             /* accept aggregate filenames only if single stream */
3140             if (!strcmp(path, stream->filename)) {
3141                 if (stream->nb_streams != 1) {
3142                     rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);
3143                     return;
3144                 }
3145                 stream_index = 0;
3146                 goto found;
3147             }
3148
3149             for(stream_index = 0; stream_index < stream->nb_streams;
3150                 stream_index++) {
3151                 snprintf(buf, sizeof(buf), "%s/streamid=%d",
3152                          stream->filename, stream_index);
3153                 if (!strcmp(path, buf))
3154                     goto found;
3155             }
3156         }
3157     }
3158     /* no stream found */
3159     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
3160     return;
3161  found:
3162
3163     /* generate session id if needed */
3164     if (h->session_id[0] == '\0') {
3165         unsigned random0 = av_lfg_get(&random_state);
3166         unsigned random1 = av_lfg_get(&random_state);
3167         snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
3168                  random0, random1);
3169     }
3170
3171     /* find rtp session, and create it if none found */
3172     rtp_c = find_rtp_session(h->session_id);
3173     if (!rtp_c) {
3174         /* always prefer UDP */
3175         th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
3176         if (!th) {
3177             th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
3178             if (!th) {
3179                 rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3180                 return;
3181             }
3182         }
3183
3184         rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
3185                                    th->lower_transport);
3186         if (!rtp_c) {
3187             rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
3188             return;
3189         }
3190
3191         /* open input stream */
3192         if (open_input_stream(rtp_c, "") < 0) {
3193             rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
3194             return;
3195         }
3196     }
3197
3198     /* test if stream is OK (test needed because several SETUP needs
3199        to be done for a given file) */
3200     if (rtp_c->stream != stream) {
3201         rtsp_reply_error(c, RTSP_STATUS_SERVICE);
3202         return;
3203     }
3204
3205     /* test if stream is already set up */
3206     if (rtp_c->rtp_ctx[stream_index]) {
3207         rtsp_reply_error(c, RTSP_STATUS_STATE);
3208         return;
3209     }
3210
3211     /* check transport */
3212     th = find_transport(h, rtp_c->rtp_protocol);
3213     if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
3214                 th->client_port_min <= 0)) {
3215         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3216         return;
3217     }
3218
3219     /* setup default options */
3220     setup.transport_option[0] = '\0';
3221     dest_addr = rtp_c->from_addr;
3222     dest_addr.sin_port = htons(th->client_port_min);
3223
3224     /* setup stream */
3225     if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
3226         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3227         return;
3228     }
3229
3230     /* now everything is OK, so we can send the connection parameters */
3231     rtsp_reply_header(c, RTSP_STATUS_OK);
3232     /* session ID */
3233     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3234
3235     switch(rtp_c->rtp_protocol) {
3236     case RTSP_LOWER_TRANSPORT_UDP:
3237         rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
3238         rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
3239         avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
3240                     "client_port=%d-%d;server_port=%d-%d",
3241                     th->client_port_min, th->client_port_max,
3242                     rtp_port, rtcp_port);
3243         break;
3244     case RTSP_LOWER_TRANSPORT_TCP:
3245         avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
3246                     stream_index * 2, stream_index * 2 + 1);
3247         break;
3248     default:
3249         break;
3250     }
3251     if (setup.transport_option[0] != '\0')
3252         avio_printf(c->pb, ";%s", setup.transport_option);
3253     avio_printf(c->pb, "\r\n");
3254
3255
3256     avio_printf(c->pb, "\r\n");
3257 }
3258
3259
3260 /* find an rtp connection by using the session ID. Check consistency
3261    with filename */
3262 static HTTPContext *find_rtp_session_with_url(const char *url,
3263                                               const char *session_id)
3264 {
3265     HTTPContext *rtp_c;
3266     char path1[1024];
3267     const char *path;
3268     char buf[1024];
3269     int s, len;
3270
3271     rtp_c = find_rtp_session(session_id);
3272     if (!rtp_c)
3273         return NULL;
3274
3275     /* find which url is asked */
3276     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3277     path = path1;
3278     if (*path == '/')
3279         path++;
3280     if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
3281     for(s=0; s<rtp_c->stream->nb_streams; ++s) {
3282       snprintf(buf, sizeof(buf), "%s/streamid=%d",
3283         rtp_c->stream->filename, s);
3284       if(!strncmp(path, buf, sizeof(buf))) {
3285     // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
3286         return rtp_c;
3287       }
3288     }
3289     len = strlen(path);
3290     if (len > 0 && path[len - 1] == '/' &&
3291         !strncmp(path, rtp_c->stream->filename, len - 1))
3292         return rtp_c;
3293     return NULL;
3294 }
3295
3296 static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3297 {
3298     HTTPContext *rtp_c;
3299
3300     rtp_c = find_rtp_session_with_url(url, h->session_id);
3301     if (!rtp_c) {
3302         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3303         return;
3304     }
3305
3306     if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3307         rtp_c->state != HTTPSTATE_WAIT_FEED &&
3308         rtp_c->state != HTTPSTATE_READY) {
3309         rtsp_reply_error(c, RTSP_STATUS_STATE);
3310         return;
3311     }
3312
3313     rtp_c->state = HTTPSTATE_SEND_DATA;
3314
3315     /* now everything is OK, so we can send the connection parameters */
3316     rtsp_reply_header(c, RTSP_STATUS_OK);
3317     /* session ID */
3318     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3319     avio_printf(c->pb, "\r\n");
3320 }
3321
3322 static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3323 {
3324     HTTPContext *rtp_c;
3325
3326     rtp_c = find_rtp_session_with_url(url, h->session_id);
3327     if (!rtp_c) {
3328         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3329         return;
3330     }
3331
3332     if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3333         rtp_c->state != HTTPSTATE_WAIT_FEED) {
3334         rtsp_reply_error(c, RTSP_STATUS_STATE);
3335         return;
3336     }
3337
3338     rtp_c->state = HTTPSTATE_READY;
3339     rtp_c->first_pts = AV_NOPTS_VALUE;
3340     /* now everything is OK, so we can send the connection parameters */
3341     rtsp_reply_header(c, RTSP_STATUS_OK);
3342     /* session ID */
3343     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3344     avio_printf(c->pb, "\r\n");
3345 }
3346
3347 static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3348 {
3349     HTTPContext *rtp_c;
3350
3351     rtp_c = find_rtp_session_with_url(url, h->session_id);
3352     if (!rtp_c) {
3353         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3354         return;
3355     }
3356
3357     /* now everything is OK, so we can send the connection parameters */
3358     rtsp_reply_header(c, RTSP_STATUS_OK);
3359     /* session ID */
3360     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3361     avio_printf(c->pb, "\r\n");
3362
3363     /* abort the session */
3364     close_connection(rtp_c);
3365 }
3366
3367
3368 /********************************************************************/
3369 /* RTP handling */
3370
3371 static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
3372                                        FFStream *stream, const char *session_id,
3373                                        enum RTSPLowerTransport rtp_protocol)
3374 {
3375     HTTPContext *c = NULL;
3376     const char *proto_str;
3377
3378     /* XXX: should output a warning page when coming
3379        close to the connection limit */
3380     if (nb_connections >= nb_max_connections)
3381         goto fail;
3382
3383     /* add a new connection */
3384     c = av_mallocz(sizeof(HTTPContext));
3385     if (!c)
3386         goto fail;
3387
3388     c->fd = -1;
3389     c->poll_entry = NULL;
3390     c->from_addr = *from_addr;
3391     c->buffer_size = IOBUFFER_INIT_SIZE;
3392     c->buffer = av_malloc(c->buffer_size);
3393     if (!c->buffer)
3394         goto fail;
3395     nb_connections++;
3396     c->stream = stream;
3397     av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
3398     c->state = HTTPSTATE_READY;
3399     c->is_packetized = 1;
3400     c->rtp_protocol = rtp_protocol;
3401
3402     /* protocol is shown in statistics */
3403     switch(c->rtp_protocol) {
3404     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3405         proto_str = "MCAST";
3406         break;
3407     case RTSP_LOWER_TRANSPORT_UDP:
3408         proto_str = "UDP";
3409         break;
3410     case RTSP_LOWER_TRANSPORT_TCP:
3411         proto_str = "TCP";
3412         break;
3413     default:
3414         proto_str = "???";
3415         break;
3416     }
3417     av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
3418     av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
3419
3420     current_bandwidth += stream->bandwidth;
3421
3422     c->next = first_http_ctx;
3423     first_http_ctx = c;
3424     return c;
3425
3426  fail:
3427     if (c) {
3428         av_free(c->buffer);
3429         av_free(c);
3430     }
3431     return NULL;
3432 }
3433
3434 /* add a new RTP stream in an RTP connection (used in RTSP SETUP
3435    command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
3436    used. */
3437 static int rtp_new_av_stream(HTTPContext *c,
3438                              int stream_index, struct sockaddr_in *dest_addr,
3439                              HTTPContext *rtsp_c)
3440 {
3441     AVFormatContext *ctx;
3442     AVStream *st;
3443     char *ipaddr;
3444     URLContext *h = NULL;
3445     uint8_t *dummy_buf;
3446     int max_packet_size;
3447
3448     /* now we can open the relevant output stream */
3449     ctx = avformat_alloc_context();
3450     if (!ctx)
3451         return -1;
3452     ctx->oformat = av_guess_format("rtp", NULL, NULL);
3453
3454     st = av_mallocz(sizeof(AVStream));
3455     if (!st)
3456         goto fail;
3457     ctx->nb_streams = 1;
3458     ctx->streams = av_mallocz(sizeof(AVStream *) * ctx->nb_streams);
3459     if (!ctx->streams)
3460       goto fail;
3461     ctx->streams[0] = st;
3462
3463     if (!c->stream->feed ||
3464         c->stream->feed == c->stream)
3465         memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
3466     else
3467         memcpy(st,
3468                c->stream->feed->streams[c->stream->feed_streams[stream_index]],
3469                sizeof(AVStream));
3470     st->priv_data = NULL;
3471
3472     /* build destination RTP address */
3473     ipaddr = inet_ntoa(dest_addr->sin_addr);
3474
3475     switch(c->rtp_protocol) {
3476     case RTSP_LOWER_TRANSPORT_UDP:
3477     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3478         /* RTP/UDP case */
3479
3480         /* XXX: also pass as parameter to function ? */
3481         if (c->stream->is_multicast) {
3482             int ttl;
3483             ttl = c->stream->multicast_ttl;
3484             if (!ttl)
3485                 ttl = 16;
3486             snprintf(ctx->filename, sizeof(ctx->filename),
3487                      "rtp://%s:%d?multicast=1&ttl=%d",
3488                      ipaddr, ntohs(dest_addr->sin_port), ttl);
3489         } else {
3490             snprintf(ctx->filename, sizeof(ctx->filename),
3491                      "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
3492         }
3493
3494         if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
3495             goto fail;
3496         c->rtp_handles[stream_index] = h;
3497         max_packet_size = h->max_packet_size;
3498         break;
3499     case RTSP_LOWER_TRANSPORT_TCP:
3500         /* RTP/TCP case */
3501         c->rtsp_c = rtsp_c;
3502         max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
3503         break;
3504     default:
3505         goto fail;
3506     }
3507
3508     http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
3509              ipaddr, ntohs(dest_addr->sin_port),
3510              c->stream->filename, stream_index, c->protocol);
3511
3512     /* normally, no packets should be output here, but the packet size may be checked */
3513     if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
3514         /* XXX: close stream */
3515         goto fail;
3516     }
3517     if (avformat_write_header(ctx, NULL) < 0) {
3518     fail:
3519         if (h)
3520             ffurl_close(h);
3521         av_free(ctx);
3522         return -1;
3523     }
3524     avio_close_dyn_buf(ctx->pb, &dummy_buf);
3525     av_free(dummy_buf);
3526
3527     c->rtp_ctx[stream_index] = ctx;
3528     return 0;
3529 }
3530
3531 /********************************************************************/
3532 /* ffserver initialization */
3533
3534 static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
3535 {
3536     AVStream *fst;
3537
3538     if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
3539         return NULL;
3540
3541     fst = av_mallocz(sizeof(AVStream));
3542     if (!fst)
3543         return NULL;
3544     if (copy) {
3545         fst->codec = avcodec_alloc_context3(NULL);
3546         memcpy(fst->codec, codec, sizeof(AVCodecContext));
3547         if (codec->extradata_size) {
3548             fst->codec->extradata = av_mallocz(codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
3549             memcpy(fst->codec->extradata, codec->extradata,
3550                 codec->extradata_size);
3551         }
3552     } else {
3553         /* live streams must use the actual feed's codec since it may be
3554          * updated later to carry extradata needed by the streams.
3555          */
3556         fst->codec = codec;
3557     }
3558     fst->priv_data = av_mallocz(sizeof(FeedData));
3559     fst->index = stream->nb_streams;
3560     avpriv_set_pts_info(fst, 33, 1, 90000);
3561     fst->sample_aspect_ratio = codec->sample_aspect_ratio;
3562     stream->streams[stream->nb_streams++] = fst;
3563     return fst;
3564 }
3565
3566 /* return the stream number in the feed */
3567 static int add_av_stream(FFStream *feed, AVStream *st)
3568 {
3569     AVStream *fst;
3570     AVCodecContext *av, *av1;
3571     int i;
3572
3573     av = st->codec;
3574     for(i=0;i<feed->nb_streams;i++) {
3575         st = feed->streams[i];
3576         av1 = st->codec;
3577         if (av1->codec_id == av->codec_id &&
3578             av1->codec_type == av->codec_type &&
3579             av1->bit_rate == av->bit_rate) {
3580
3581             switch(av->codec_type) {
3582             case AVMEDIA_TYPE_AUDIO:
3583                 if (av1->channels == av->channels &&
3584                     av1->sample_rate == av->sample_rate)
3585                     return i;
3586                 break;
3587             case AVMEDIA_TYPE_VIDEO:
3588                 if (av1->width == av->width &&
3589                     av1->height == av->height &&
3590                     av1->time_base.den == av->time_base.den &&
3591                     av1->time_base.num == av->time_base.num &&
3592                     av1->gop_size == av->gop_size)
3593                     return i;
3594                 break;
3595             default:
3596                 abort();
3597             }
3598         }
3599     }
3600
3601     fst = add_av_stream1(feed, av, 0);
3602     if (!fst)
3603         return -1;
3604     return feed->nb_streams - 1;
3605 }
3606
3607 static void remove_stream(FFStream *stream)
3608 {
3609     FFStream **ps;
3610     ps = &first_stream;
3611     while (*ps != NULL) {
3612         if (*ps == stream)
3613             *ps = (*ps)->next;
3614         else
3615             ps = &(*ps)->next;
3616     }
3617 }
3618
3619 /* specific mpeg4 handling : we extract the raw parameters */
3620 static void extract_mpeg4_header(AVFormatContext *infile)
3621 {
3622     int mpeg4_count, i, size;
3623     AVPacket pkt;
3624     AVStream *st;
3625     const uint8_t *p;
3626
3627     infile->flags |= AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE;
3628
3629     mpeg4_count = 0;
3630     for(i=0;i<infile->nb_streams;i++) {
3631         st = infile->streams[i];
3632         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3633             st->codec->extradata_size == 0) {
3634             mpeg4_count++;
3635         }
3636     }
3637     if (!mpeg4_count)
3638         return;
3639
3640     printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
3641     while (mpeg4_count > 0) {
3642         if (av_read_frame(infile, &pkt) < 0)
3643             break;
3644         st = infile->streams[pkt.stream_index];
3645         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3646             st->codec->extradata_size == 0) {
3647             av_freep(&st->codec->extradata);
3648             /* fill extradata with the header */
3649             /* XXX: we make hard suppositions here ! */
3650             p = pkt.data;
3651             while (p < pkt.data + pkt.size - 4) {
3652                 /* stop when vop header is found */
3653                 if (p[0] == 0x00 && p[1] == 0x00 &&
3654                     p[2] == 0x01 && p[3] == 0xb6) {
3655                     size = p - pkt.data;
3656                     //                    av_hex_dump_log(infile, AV_LOG_DEBUG, pkt.data, size);
3657                     st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
3658                     st->codec->extradata_size = size;
3659                     memcpy(st->codec->extradata, pkt.data, size);
3660                     break;
3661                 }
3662                 p++;
3663             }
3664             mpeg4_count--;
3665         }
3666         av_free_packet(&pkt);
3667     }
3668 }
3669
3670 /* compute the needed AVStream for each file */
3671 static void build_file_streams(void)
3672 {
3673     FFStream *stream, *stream_next;
3674     int i, ret;
3675
3676     /* gather all streams */
3677     for(stream = first_stream; stream != NULL; stream = stream_next) {
3678         AVFormatContext *infile = NULL;
3679         stream_next = stream->next;
3680         if (stream->stream_type == STREAM_TYPE_LIVE &&
3681             !stream->feed) {
3682             /* the stream comes from a file */
3683             /* try to open the file */
3684             /* open stream */
3685             if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
3686                 /* specific case : if transport stream output to RTP,
3687                    we use a raw transport stream reader */
3688                 av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
3689             }
3690
3691             if (!stream->feed_filename[0]) {
3692                 http_log("Unspecified feed file for stream '%s'\n", stream->filename);
3693                 goto fail;
3694             }
3695
3696             http_log("Opening feed file '%s' for stream '%s'\n", stream->feed_filename, stream->filename);
3697             if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
3698                 http_log("Could not open '%s': %s\n", stream->feed_filename, av_err2str(ret));
3699                 /* remove stream (no need to spend more time on it) */
3700             fail:
3701                 remove_stream(stream);
3702             } else {
3703                 /* find all the AVStreams inside and reference them in
3704                    'stream' */
3705                 if (avformat_find_stream_info(infile, NULL) < 0) {
3706                     http_log("Could not find codec parameters from '%s'\n",
3707                              stream->feed_filename);
3708                     avformat_close_input(&infile);
3709                     goto fail;
3710                 }
3711                 extract_mpeg4_header(infile);
3712
3713                 for(i=0;i<infile->nb_streams;i++)
3714                     add_av_stream1(stream, infile->streams[i]->codec, 1);
3715
3716                 avformat_close_input(&infile);
3717             }
3718         }
3719     }
3720 }
3721
3722 /* compute the needed AVStream for each feed */
3723 static void build_feed_streams(void)
3724 {
3725     FFStream *stream, *feed;
3726     int i;
3727
3728     /* gather all streams */
3729     for(stream = first_stream; stream != NULL; stream = stream->next) {
3730         feed = stream->feed;
3731         if (feed) {
3732             if (stream->is_feed) {
3733                 for(i=0;i<stream->nb_streams;i++)
3734                     stream->feed_streams[i] = i;
3735             } else {
3736                 /* we handle a stream coming from a feed */
3737                 for(i=0;i<stream->nb_streams;i++)
3738                     stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]);
3739             }
3740         }
3741     }
3742
3743     /* create feed files if needed */
3744     for(feed = first_feed; feed != NULL; feed = feed->next_feed) {
3745         int fd;
3746
3747         if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
3748             /* See if it matches */
3749             AVFormatContext *s = NULL;
3750             int matches = 0;
3751
3752             if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
3753                 /* set buffer size */
3754                 ffio_set_buf_size(s->pb, FFM_PACKET_SIZE);
3755                 /* Now see if it matches */
3756                 if (s->nb_streams == feed->nb_streams) {
3757                     matches = 1;
3758                     for(i=0;i<s->nb_streams;i++) {
3759                         AVStream *sf, *ss;
3760                         sf = feed->streams[i];
3761                         ss = s->streams[i];
3762
3763                         if (sf->index != ss->index ||
3764                             sf->id != ss->id) {
3765                             http_log("Index & Id do not match for stream %d (%s)\n",
3766                                    i, feed->feed_filename);
3767                             matches = 0;
3768                         } else {
3769                             AVCodecContext *ccf, *ccs;
3770
3771                             ccf = sf->codec;
3772                             ccs = ss->codec;
3773 #define CHECK_CODEC(x)  (ccf->x != ccs->x)
3774
3775                             if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
3776                                 http_log("Codecs do not match for stream %d\n", i);
3777                                 matches = 0;
3778                             } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
3779                                 http_log("Codec bitrates do not match for stream %d\n", i);
3780                                 matches = 0;
3781                             } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {
3782                                 if (CHECK_CODEC(time_base.den) ||
3783                                     CHECK_CODEC(time_base.num) ||
3784                                     CHECK_CODEC(width) ||
3785                                     CHECK_CODEC(height)) {
3786                                     http_log("Codec width, height and framerate do not match for stream %d\n", i);
3787                                     matches = 0;
3788                                 }
3789                             } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {
3790                                 if (CHECK_CODEC(sample_rate) ||
3791                                     CHECK_CODEC(channels) ||
3792                                     CHECK_CODEC(frame_size)) {
3793                                     http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);
3794                                     matches = 0;
3795                                 }
3796                             } else {
3797                                 http_log("Unknown codec type\n");
3798                                 matches = 0;
3799                             }
3800                         }
3801                         if (!matches)
3802                             break;
3803                     }
3804                 } else
3805                     http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",
3806                         feed->feed_filename, s->nb_streams, feed->nb_streams);
3807
3808                 avformat_close_input(&s);
3809             } else
3810                 http_log("Deleting feed file '%s' as it appears to be corrupt\n",
3811                         feed->feed_filename);
3812
3813             if (!matches) {
3814                 if (feed->readonly) {
3815                     http_log("Unable to delete feed file '%s' as it is marked readonly\n",
3816                         feed->feed_filename);
3817                     exit(1);
3818                 }
3819                 unlink(feed->feed_filename);
3820             }
3821         }
3822         if (avio_check(feed->feed_filename, AVIO_FLAG_WRITE) <= 0) {
3823             AVFormatContext *s = avformat_alloc_context();
3824
3825             if (feed->readonly) {
3826                 http_log("Unable to create feed file '%s' as it is marked readonly\n",
3827                     feed->feed_filename);
3828                 exit(1);
3829             }
3830
3831             /* only write the header of the ffm file */
3832             if (avio_open(&s->pb, feed->feed_filename, AVIO_FLAG_WRITE) < 0) {
3833                 http_log("Could not open output feed file '%s'\n",
3834                          feed->feed_filename);
3835                 exit(1);
3836             }
3837             s->oformat = feed->fmt;
3838             s->nb_streams = feed->nb_streams;
3839             s->streams = feed->streams;
3840             if (avformat_write_header(s, NULL) < 0) {
3841                 http_log("Container doesn't support the required parameters\n");
3842                 exit(1);
3843             }
3844             /* XXX: need better api */
3845             av_freep(&s->priv_data);
3846             avio_close(s->pb);
3847             s->streams = NULL;
3848             s->nb_streams = 0;
3849             avformat_free_context(s);
3850         }
3851         /* get feed size and write index */
3852         fd = open(feed->feed_filename, O_RDONLY);
3853         if (fd < 0) {
3854             http_log("Could not open output feed file '%s'\n",
3855                     feed->feed_filename);
3856             exit(1);
3857         }
3858
3859         feed->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
3860         feed->feed_size = lseek(fd, 0, SEEK_END);
3861         /* ensure that we do not wrap before the end of file */
3862         if (feed->feed_max_size && feed->feed_max_size < feed->feed_size)
3863             feed->feed_max_size = feed->feed_size;
3864
3865         close(fd);
3866     }
3867 }
3868
3869 /* compute the bandwidth used by each stream */
3870 static void compute_bandwidth(void)
3871 {
3872     unsigned bandwidth;
3873     int i;
3874     FFStream *stream;
3875
3876     for(stream = first_stream; stream != NULL; stream = stream->next) {
3877         bandwidth = 0;
3878         for(i=0;i<stream->nb_streams;i++) {
3879             AVStream *st = stream->streams[i];
3880             switch(st->codec->codec_type) {
3881             case AVMEDIA_TYPE_AUDIO:
3882             case AVMEDIA_TYPE_VIDEO:
3883                 bandwidth += st->codec->bit_rate;
3884                 break;
3885             default:
3886                 break;
3887             }
3888         }
3889         stream->bandwidth = (bandwidth + 999) / 1000;
3890     }
3891 }
3892
3893 /* add a codec and set the default parameters */
3894 static void add_codec(FFStream *stream, AVCodecContext *av)
3895 {
3896     AVStream *st;
3897
3898     if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
3899         return;
3900
3901     /* compute default parameters */
3902     switch(av->codec_type) {
3903     case AVMEDIA_TYPE_AUDIO:
3904         if (av->bit_rate == 0)
3905             av->bit_rate = 64000;
3906         if (av->sample_rate == 0)
3907             av->sample_rate = 22050;
3908         if (av->channels == 0)
3909             av->channels = 1;
3910         break;
3911     case AVMEDIA_TYPE_VIDEO:
3912         if (av->bit_rate == 0)
3913             av->bit_rate = 64000;
3914         if (av->time_base.num == 0){
3915             av->time_base.den = 5;
3916             av->time_base.num = 1;
3917         }
3918         if (av->width == 0 || av->height == 0) {
3919             av->width = 160;
3920             av->height = 128;
3921         }
3922         /* Bitrate tolerance is less for streaming */
3923         if (av->bit_rate_tolerance == 0)
3924             av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
3925                       (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
3926         if (av->qmin == 0)
3927             av->qmin = 3;
3928         if (av->qmax == 0)
3929             av->qmax = 31;
3930         if (av->max_qdiff == 0)
3931             av->max_qdiff = 3;
3932         av->qcompress = 0.5;
3933         av->qblur = 0.5;
3934
3935         if (!av->nsse_weight)
3936             av->nsse_weight = 8;
3937
3938         av->frame_skip_cmp = FF_CMP_DCTMAX;
3939         if (!av->me_method)
3940             av->me_method = ME_EPZS;
3941         av->rc_buffer_aggressivity = 1.0;
3942
3943         if (!av->rc_eq)
3944             av->rc_eq = av_strdup("tex^qComp");
3945         if (!av->i_quant_factor)
3946             av->i_quant_factor = -0.8;
3947         if (!av->b_quant_factor)
3948             av->b_quant_factor = 1.25;
3949         if (!av->b_quant_offset)
3950             av->b_quant_offset = 1.25;
3951         if (!av->rc_max_rate)
3952             av->rc_max_rate = av->bit_rate * 2;
3953
3954         if (av->rc_max_rate && !av->rc_buffer_size) {
3955             av->rc_buffer_size = av->rc_max_rate;
3956         }
3957
3958
3959         break;
3960     default:
3961         abort();
3962     }
3963
3964     st = av_mallocz(sizeof(AVStream));
3965     if (!st)
3966         return;
3967     st->codec = avcodec_alloc_context3(NULL);
3968     stream->streams[stream->nb_streams++] = st;
3969     memcpy(st->codec, av, sizeof(AVCodecContext));
3970 }
3971
3972 static enum AVCodecID opt_codec(const char *name, enum AVMediaType type)
3973 {
3974     AVCodec *codec = avcodec_find_encoder_by_name(name);
3975
3976     if (!codec || codec->type != type)
3977         return AV_CODEC_ID_NONE;
3978     return codec->id;
3979 }
3980
3981 static int ffserver_opt_default(const char *opt, const char *arg,
3982                        AVCodecContext *avctx, int type)
3983 {
3984     int ret = 0;
3985     const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0);
3986     if(o)
3987         ret = av_opt_set(avctx, opt, arg, 0);
3988     return ret;
3989 }
3990
3991 static int ffserver_opt_preset(const char *arg,
3992                        AVCodecContext *avctx, int type,
3993                        enum AVCodecID *audio_id, enum AVCodecID *video_id)
3994 {
3995     FILE *f=NULL;
3996     char filename[1000], tmp[1000], tmp2[1000], line[1000];
3997     int ret = 0;
3998     AVCodec *codec = avcodec_find_encoder(avctx->codec_id);
3999
4000     if (!(f = get_preset_file(filename, sizeof(filename), arg, 0,
4001                               codec ? codec->name : NULL))) {
4002         fprintf(stderr, "File for preset '%s' not found\n", arg);
4003         return 1;
4004     }
4005
4006     while(!feof(f)){
4007         int e= fscanf(f, "%999[^\n]\n", line) - 1;
4008         if(line[0] == '#' && !e)
4009             continue;
4010         e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
4011         if(e){
4012             fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line);
4013             ret = 1;
4014             break;
4015         }
4016         if(!strcmp(tmp, "acodec")){
4017             *audio_id = opt_codec(tmp2, AVMEDIA_TYPE_AUDIO);
4018         }else if(!strcmp(tmp, "vcodec")){
4019             *video_id = opt_codec(tmp2, AVMEDIA_TYPE_VIDEO);
4020         }else if(!strcmp(tmp, "scodec")){
4021             /* opt_subtitle_codec(tmp2); */
4022         }else if(ffserver_opt_default(tmp, tmp2, avctx, type) < 0){
4023             fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
4024             ret = 1;
4025             break;
4026         }
4027     }
4028
4029     fclose(f);
4030
4031     return ret;
4032 }
4033
4034 static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename,
4035                                              const char *mime_type)
4036 {
4037     AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
4038
4039     if (fmt) {
4040         AVOutputFormat *stream_fmt;
4041         char stream_format_name[64];
4042
4043         snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name);
4044         stream_fmt = av_guess_format(stream_format_name, NULL, NULL);
4045
4046         if (stream_fmt)
4047             fmt = stream_fmt;
4048     }
4049
4050     return fmt;
4051 }
4052
4053 static void report_config_error(const char *filename, int line_num, int log_level, int *errors, const char *fmt, ...)
4054 {
4055     va_list vl;
4056     va_start(vl, fmt);
4057     av_log(NULL, log_level, "%s:%d: ", filename, line_num);
4058     av_vlog(NULL, log_level, fmt, vl);
4059     va_end(vl);
4060
4061     (*errors)++;
4062 }
4063
4064 static int parse_ffconfig(const char *filename)
4065 {
4066     FILE *f;
4067     char line[1024];
4068     char cmd[64];
4069     char arg[1024], arg2[1024];
4070     const char *p;
4071     int val, errors, warnings, line_num;
4072     FFStream **last_stream, *stream, *redirect;
4073     FFStream **last_feed, *feed, *s;
4074     AVCodecContext audio_enc, video_enc;
4075     enum AVCodecID audio_id, video_id;
4076     int ret = 0;
4077
4078     f = fopen(filename, "r");
4079     if (!f) {
4080         ret = AVERROR(errno);
4081         av_log(NULL, AV_LOG_ERROR, "Could not open the configuration file '%s'\n", filename);
4082         return ret;
4083     }
4084
4085     errors = warnings = 0;
4086     line_num = 0;
4087     first_stream = NULL;
4088     last_stream = &first_stream;
4089     first_feed = NULL;
4090     last_feed = &first_feed;
4091     stream = NULL;
4092     feed = NULL;
4093     redirect = NULL;
4094     audio_id = AV_CODEC_ID_NONE;
4095     video_id = AV_CODEC_ID_NONE;
4096 #define ERROR(...)   report_config_error(filename, line_num, AV_LOG_ERROR,   &errors,   __VA_ARGS__)
4097 #define WARNING(...) report_config_error(filename, line_num, AV_LOG_WARNING, &warnings, __VA_ARGS__)
4098
4099     for(;;) {
4100         if (fgets(line, sizeof(line), f) == NULL)
4101             break;
4102         line_num++;
4103         p = line;
4104         while (av_isspace(*p))
4105             p++;
4106         if (*p == '\0' || *p == '#')
4107             continue;
4108
4109         get_arg(cmd, sizeof(cmd), &p);
4110
4111         if (!av_strcasecmp(cmd, "Port")) {
4112             get_arg(arg, sizeof(arg), &p);
4113             val = atoi(arg);
4114             if (val < 1 || val > 65536) {
4115                 ERROR("Invalid_port: %s\n", arg);
4116             }
4117             my_http_addr.sin_port = htons(val);
4118         } else if (!av_strcasecmp(cmd, "BindAddress")) {
4119             get_arg(arg, sizeof(arg), &p);
4120             if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
4121                 ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
4122             }
4123         } else if (!av_strcasecmp(cmd, "NoDaemon")) {
4124             WARNING("NoDaemon option has no effect, you should remove it\n");
4125         } else if (!av_strcasecmp(cmd, "RTSPPort")) {
4126             get_arg(arg, sizeof(arg), &p);
4127             val = atoi(arg);
4128             if (val < 1 || val > 65536) {
4129                 ERROR("%s:%d: Invalid port: %s\n", arg);
4130             }
4131             my_rtsp_addr.sin_port = htons(atoi(arg));
4132         } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) {
4133             get_arg(arg, sizeof(arg), &p);
4134             if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
4135                 ERROR("Invalid host/IP address: %s\n", arg);
4136             }
4137         } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) {
4138             get_arg(arg, sizeof(arg), &p);
4139             val = atoi(arg);
4140             if (val < 1 || val > 65536) {
4141                 ERROR("Invalid MaxHTTPConnections: %s\n", arg);
4142             }
4143             nb_max_http_connections = val;
4144         } else if (!av_strcasecmp(cmd, "MaxClients")) {
4145             get_arg(arg, sizeof(arg), &p);
4146             val = atoi(arg);
4147             if (val < 1 || val > nb_max_http_connections) {
4148                 ERROR("Invalid MaxClients: %s\n", arg);
4149             } else {
4150                 nb_max_connections = val;
4151             }
4152         } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
4153             int64_t llval;
4154             get_arg(arg, sizeof(arg), &p);
4155             llval = strtoll(arg, NULL, 10);
4156             if (llval < 10 || llval > 10000000) {
4157                 ERROR("Invalid MaxBandwidth: %s\n", arg);
4158             } else
4159                 max_bandwidth = llval;
4160         } else if (!av_strcasecmp(cmd, "CustomLog")) {
4161             if (!ffserver_debug)
4162                 get_arg(logfilename, sizeof(logfilename), &p);
4163         } else if (!av_strcasecmp(cmd, "<Feed")) {
4164             /*********************************************/
4165             /* Feed related options */
4166             char *q;
4167             if (stream || feed) {
4168                 ERROR("Already in a tag\n");
4169             } else {
4170                 feed = av_mallocz(sizeof(FFStream));
4171                 if (!feed) {
4172                     ret = AVERROR(ENOMEM);
4173                     goto end;
4174                 }
4175                 get_arg(feed->filename, sizeof(feed->filename), &p);
4176                 q = strrchr(feed->filename, '>');
4177                 if (*q)
4178                     *q = '\0';
4179
4180                 for (s = first_feed; s; s = s->next) {
4181                     if (!strcmp(feed->filename, s->filename)) {
4182                         ERROR("Feed '%s' already registered\n", s->filename);
4183                     }
4184                 }
4185
4186                 feed->fmt = av_guess_format("ffm", NULL, NULL);
4187                 /* default feed file */
4188                 snprintf(feed->feed_filename, sizeof(feed->feed_filename),
4189                          "/tmp/%s.ffm", feed->filename);
4190                 feed->feed_max_size = 5 * 1024 * 1024;
4191                 feed->is_feed = 1;
4192                 feed->feed = feed; /* self feeding :-) */
4193
4194                 /* add in stream list */
4195                 *last_stream = feed;
4196                 last_stream = &feed->next;
4197                 /* add in feed list */
4198                 *last_feed = feed;
4199                 last_feed = &feed->next_feed;
4200             }
4201         } else if (!av_strcasecmp(cmd, "Launch")) {
4202             if (feed) {
4203                 int i;
4204
4205                 feed->child_argv = av_mallocz(64 * sizeof(char *));
4206                 if (!feed->child_argv) {
4207                     ret = AVERROR(ENOMEM);
4208                     goto end;
4209                 }
4210                 for (i = 0; i < 62; i++) {
4211                     get_arg(arg, sizeof(arg), &p);
4212                     if (!arg[0])
4213                         break;
4214
4215                     feed->child_argv[i] = av_strdup(arg);
4216                     if (!feed->child_argv[i]) {
4217                         ret = AVERROR(ENOMEM);
4218                         goto end;
4219                     }
4220                 }
4221
4222                 feed->child_argv[i] =
4223                     av_asprintf("http://%s:%d/%s",
4224                                 (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" :
4225                                 inet_ntoa(my_http_addr.sin_addr), ntohs(my_http_addr.sin_port),
4226                                 feed->filename);
4227                 if (!feed->child_argv[i]) {
4228                     ret = AVERROR(ENOMEM);
4229                     goto end;
4230                 }
4231             }
4232         } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) {
4233             if (feed) {
4234                 get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
4235                 feed->readonly = !av_strcasecmp(cmd, "ReadOnlyFile");
4236             } else if (stream) {
4237                 get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
4238             }
4239         } else if (!av_strcasecmp(cmd, "Truncate")) {
4240             if (feed) {
4241                 get_arg(arg, sizeof(arg), &p);
4242                 /* assume Truncate is true in case no argument is specified */
4243                 if (!arg[0]) {
4244                     feed->truncate = 1;
4245                 } else {
4246                     WARNING("Truncate N syntax in configuration file is deprecated, "
4247                             "use Truncate alone with no arguments\n");
4248                     feed->truncate = strtod(arg, NULL);
4249                 }
4250             }
4251         } else if (!av_strcasecmp(cmd, "FileMaxSize")) {
4252             if (feed) {
4253                 char *p1;
4254                 double fsize;
4255
4256                 get_arg(arg, sizeof(arg), &p);
4257                 p1 = arg;
4258                 fsize = strtod(p1, &p1);
4259                 switch(av_toupper(*p1)) {
4260                 case 'K':
4261                     fsize *= 1024;
4262                     break;
4263                 case 'M':
4264                     fsize *= 1024 * 1024;
4265                     break;
4266                 case 'G':
4267                     fsize *= 1024 * 1024 * 1024;
4268                     break;
4269                 }
4270                 feed->feed_max_size = (int64_t)fsize;
4271                 if (feed->feed_max_size < FFM_PACKET_SIZE*4) {
4272                     ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4);
4273                 }
4274             }
4275         } else if (!av_strcasecmp(cmd, "</Feed>")) {
4276             if (!feed) {
4277                 ERROR("No corresponding <Feed> for </Feed>\n");
4278             }
4279             feed = NULL;
4280         } else if (!av_strcasecmp(cmd, "<Stream")) {
4281             /*********************************************/
4282             /* Stream related options */
4283             char *q;
4284             if (stream || feed) {
4285                 ERROR("Already in a tag\n");
4286             } else {
4287                 FFStream *s;
4288                 stream = av_mallocz(sizeof(FFStream));
4289                 if (!stream) {
4290                     ret = AVERROR(ENOMEM);
4291                     goto end;
4292                 }
4293                 get_arg(stream->filename, sizeof(stream->filename), &p);
4294                 q = strrchr(stream->filename, '>');
4295                 if (q)
4296                     *q = '\0';
4297
4298                 for (s = first_stream; s; s = s->next) {
4299                     if (!strcmp(stream->filename, s->filename)) {
4300                         ERROR("Stream '%s' already registered\n", s->filename);
4301                     }
4302                 }
4303
4304                 stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL);
4305                 avcodec_get_context_defaults3(&video_enc, NULL);
4306                 avcodec_get_context_defaults3(&audio_enc, NULL);
4307
4308                 audio_id = AV_CODEC_ID_NONE;
4309                 video_id = AV_CODEC_ID_NONE;
4310                 if (stream->fmt) {
4311                     audio_id = stream->fmt->audio_codec;
4312                     video_id = stream->fmt->video_codec;
4313                 }
4314
4315                 *last_stream = stream;
4316                 last_stream = &stream->next;
4317             }
4318         } else if (!av_strcasecmp(cmd, "Feed")) {
4319             get_arg(arg, sizeof(arg), &p);
4320             if (stream) {
4321                 FFStream *sfeed;
4322
4323                 sfeed = first_feed;
4324                 while (sfeed != NULL) {
4325                     if (!strcmp(sfeed->filename, arg))
4326                         break;
4327                     sfeed = sfeed->next_feed;
4328                 }
4329                 if (!sfeed)
4330                     ERROR("Feed with name '%s' for stream '%s' is not defined\n", arg, stream->filename);
4331                 else
4332                     stream->feed = sfeed;
4333             }
4334         } else if (!av_strcasecmp(cmd, "Format")) {
4335             get_arg(arg, sizeof(arg), &p);
4336             if (stream) {
4337                 if (!strcmp(arg, "status")) {
4338                     stream->stream_type = STREAM_TYPE_STATUS;
4339                     stream->fmt = NULL;
4340                 } else {
4341                     stream->stream_type = STREAM_TYPE_LIVE;
4342                     /* jpeg cannot be used here, so use single frame jpeg */
4343                     if (!strcmp(arg, "jpeg"))
4344                         strcpy(arg, "mjpeg");
4345                     stream->fmt = ffserver_guess_format(arg, NULL, NULL);
4346                     if (!stream->fmt) {
4347                         ERROR("Unknown Format: %s\n", arg);
4348                     }
4349                 }
4350                 if (stream->fmt) {
4351                     audio_id = stream->fmt->audio_codec;
4352                     video_id = stream->fmt->video_codec;
4353                 }
4354             }
4355         } else if (!av_strcasecmp(cmd, "InputFormat")) {
4356             get_arg(arg, sizeof(arg), &p);
4357             if (stream) {
4358                 stream->ifmt = av_find_input_format(arg);
4359                 if (!stream->ifmt) {
4360                     ERROR("Unknown input format: %s\n", arg);
4361                 }
4362             }
4363         } else if (!av_strcasecmp(cmd, "FaviconURL")) {
4364             if (stream && stream->stream_type == STREAM_TYPE_STATUS) {
4365                 get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
4366             } else {
4367                 ERROR("FaviconURL only permitted for status streams\n");
4368             }
4369         } else if (!av_strcasecmp(cmd, "Author")    ||
4370                    !av_strcasecmp(cmd, "Comment")   ||
4371                    !av_strcasecmp(cmd, "Copyright") ||
4372                    !av_strcasecmp(cmd, "Title")) {
4373             get_arg(arg, sizeof(arg), &p);
4374
4375             if (stream) {
4376                 char key[32];
4377                 int i, ret;
4378
4379                 for (i = 0; i < strlen(cmd); i++)
4380                     key[i] = av_tolower(cmd[i]);
4381                 key[i] = 0;
4382                 WARNING("'%s' option in configuration file is deprecated, "
4383                         "use 'Metadata %s VALUE' instead\n", cmd, key);
4384                 if ((ret = av_dict_set(&stream->metadata, key, arg, 0)) < 0) {
4385                     ERROR("Could not set metadata '%s' to value '%s': %s\n",
4386                           key, arg, av_err2str(ret));
4387                 }
4388             }
4389         } else if (!av_strcasecmp(cmd, "Metadata")) {
4390             get_arg(arg, sizeof(arg), &p);
4391             get_arg(arg2, sizeof(arg2), &p);
4392             if (stream) {
4393                 int ret;
4394                 if ((ret = av_dict_set(&stream->metadata, arg, arg2, 0)) < 0) {
4395                     ERROR("Could not set metadata '%s' to value '%s': %s\n",
4396                           arg, arg2, av_err2str(ret));
4397                 }
4398             }
4399         } else if (!av_strcasecmp(cmd, "Preroll")) {
4400             get_arg(arg, sizeof(arg), &p);
4401             if (stream)
4402                 stream->prebuffer = atof(arg) * 1000;
4403         } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
4404             if (stream)
4405                 stream->send_on_key = 1;
4406         } else if (!av_strcasecmp(cmd, "AudioCodec")) {
4407             get_arg(arg, sizeof(arg), &p);
4408             audio_id = opt_codec(arg, AVMEDIA_TYPE_AUDIO);
4409             if (audio_id == AV_CODEC_ID_NONE) {
4410                 ERROR("Unknown AudioCodec: %s\n", arg);
4411             }
4412         } else if (!av_strcasecmp(cmd, "VideoCodec")) {
4413             get_arg(arg, sizeof(arg), &p);
4414             video_id = opt_codec(arg, AVMEDIA_TYPE_VIDEO);
4415             if (video_id == AV_CODEC_ID_NONE) {
4416                 ERROR("Unknown VideoCodec: %s\n", arg);
4417             }
4418         } else if (!av_strcasecmp(cmd, "MaxTime")) {
4419             get_arg(arg, sizeof(arg), &p);
4420             if (stream)
4421                 stream->max_time = atof(arg) * 1000;
4422         } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
4423             get_arg(arg, sizeof(arg), &p);
4424             if (stream)
4425                 audio_enc.bit_rate = lrintf(atof(arg) * 1000);
4426         } else if (!av_strcasecmp(cmd, "AudioChannels")) {
4427             get_arg(arg, sizeof(arg), &p);
4428             if (stream)
4429                 audio_enc.channels = atoi(arg);
4430         } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
4431             get_arg(arg, sizeof(arg), &p);
4432             if (stream)
4433                 audio_enc.sample_rate = atoi(arg);
4434         } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
4435             if (stream) {
4436                 int minrate, maxrate;
4437
4438                 get_arg(arg, sizeof(arg), &p);
4439
4440                 if (sscanf(arg, "%d-%d", &minrate, &maxrate) == 2) {
4441                     video_enc.rc_min_rate = minrate * 1000;
4442                     video_enc.rc_max_rate = maxrate * 1000;
4443                 } else {
4444                     ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg);
4445                 }
4446             }
4447         } else if (!av_strcasecmp(cmd, "Debug")) {
4448             if (stream) {
4449                 get_arg(arg, sizeof(arg), &p);
4450                 video_enc.debug = strtol(arg,0,0);
4451             }
4452         } else if (!av_strcasecmp(cmd, "Strict")) {
4453             if (stream) {
4454                 get_arg(arg, sizeof(arg), &p);
4455                 video_enc.strict_std_compliance = atoi(arg);
4456             }
4457         } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
4458             if (stream) {
4459                 get_arg(arg, sizeof(arg), &p);
4460                 video_enc.rc_buffer_size = atoi(arg) * 8*1024;
4461             }
4462         } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
4463             if (stream) {
4464                 get_arg(arg, sizeof(arg), &p);
4465                 video_enc.bit_rate_tolerance = atoi(arg) * 1000;
4466             }
4467         } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
4468             get_arg(arg, sizeof(arg), &p);
4469             if (stream) {
4470                 video_enc.bit_rate = atoi(arg) * 1000;
4471             }
4472         } else if (!av_strcasecmp(cmd, "VideoSize")) {
4473             get_arg(arg, sizeof(arg), &p);
4474             if (stream) {
4475                 ret = av_parse_video_size(&video_enc.width, &video_enc.height, arg);
4476                 if (ret < 0) {
4477                     ERROR("Invalid video size '%s'\n", arg);
4478                 } else {
4479                     if ((video_enc.width % 16) != 0 ||
4480                         (video_enc.height % 16) != 0) {
4481                         ERROR("Image size must be a multiple of 16\n");
4482                     }
4483                 }
4484             }
4485         } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
4486             get_arg(arg, sizeof(arg), &p);
4487             if (stream) {
4488                 AVRational frame_rate;
4489                 if (av_parse_video_rate(&frame_rate, arg) < 0) {
4490                     ERROR("Incorrect frame rate: %s\n", arg);
4491                 } else {
4492                     video_enc.time_base.num = frame_rate.den;
4493                     video_enc.time_base.den = frame_rate.num;
4494                 }
4495             }
4496         } else if (!av_strcasecmp(cmd, "PixelFormat")) {
4497             get_arg(arg, sizeof(arg), &p);
4498             if (stream) {
4499                 video_enc.pix_fmt = av_get_pix_fmt(arg);
4500                 if (video_enc.pix_fmt == AV_PIX_FMT_NONE) {
4501                     ERROR("Unknown pixel format: %s\n", arg);
4502                 }
4503             }
4504         } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
4505             get_arg(arg, sizeof(arg), &p);
4506             if (stream)
4507                 video_enc.gop_size = atoi(arg);
4508         } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
4509             if (stream)
4510                 video_enc.gop_size = 1;
4511         } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
4512             if (stream)
4513                 video_enc.mb_decision = FF_MB_DECISION_BITS;
4514         } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
4515             if (stream) {
4516                 video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove
4517                 video_enc.flags |= CODEC_FLAG_4MV;
4518             }
4519         } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
4520                    !av_strcasecmp(cmd, "AVOptionAudio")) {
4521             AVCodecContext *avctx;
4522             int type;
4523             get_arg(arg, sizeof(arg), &p);
4524             get_arg(arg2, sizeof(arg2), &p);
4525             if (!av_strcasecmp(cmd, "AVOptionVideo")) {
4526                 avctx = &video_enc;
4527                 type = AV_OPT_FLAG_VIDEO_PARAM;
4528             } else {
4529                 avctx = &audio_enc;
4530                 type = AV_OPT_FLAG_AUDIO_PARAM;
4531             }
4532             if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
4533                 ERROR("Error setting %s option to %s %s\n", cmd, arg, arg2);
4534             }
4535         } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
4536                    !av_strcasecmp(cmd, "AVPresetAudio")) {
4537             AVCodecContext *avctx;
4538             int type;
4539             get_arg(arg, sizeof(arg), &p);
4540             if (!av_strcasecmp(cmd, "AVPresetVideo")) {
4541                 avctx = &video_enc;
4542                 video_enc.codec_id = video_id;
4543                 type = AV_OPT_FLAG_VIDEO_PARAM;
4544             } else {
4545                 avctx = &audio_enc;
4546                 audio_enc.codec_id = audio_id;
4547                 type = AV_OPT_FLAG_AUDIO_PARAM;
4548             }
4549             if (ffserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
4550                 ERROR("AVPreset error: %s\n", arg);
4551             }
4552         } else if (!av_strcasecmp(cmd, "VideoTag")) {
4553             get_arg(arg, sizeof(arg), &p);
4554             if ((strlen(arg) == 4) && stream)
4555                 video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
4556         } else if (!av_strcasecmp(cmd, "BitExact")) {
4557             if (stream)
4558                 video_enc.flags |= CODEC_FLAG_BITEXACT;
4559         } else if (!av_strcasecmp(cmd, "DctFastint")) {
4560             if (stream)
4561                 video_enc.dct_algo  = FF_DCT_FASTINT;
4562         } else if (!av_strcasecmp(cmd, "IdctSimple")) {
4563             if (stream)
4564                 video_enc.idct_algo = FF_IDCT_SIMPLE;
4565         } else if (!av_strcasecmp(cmd, "Qscale")) {
4566             get_arg(arg, sizeof(arg), &p);
4567             if (stream) {
4568                 video_enc.flags |= CODEC_FLAG_QSCALE;
4569                 video_enc.global_quality = FF_QP2LAMBDA * atoi(arg);
4570             }
4571         } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
4572             get_arg(arg, sizeof(arg), &p);
4573             if (stream) {
4574                 video_enc.max_qdiff = atoi(arg);
4575                 if (video_enc.max_qdiff < 1 || video_enc.max_qdiff > 31) {
4576                     ERROR("VideoQDiff out of range\n");
4577                 }
4578             }
4579         } else if (!av_strcasecmp(cmd, "VideoQMax")) {
4580             get_arg(arg, sizeof(arg), &p);
4581             if (stream) {
4582                 video_enc.qmax = atoi(arg);
4583                 if (video_enc.qmax < 1 || video_enc.qmax > 31) {
4584                     ERROR("VideoQMax out of range\n");
4585                 }
4586             }
4587         } else if (!av_strcasecmp(cmd, "VideoQMin")) {
4588             get_arg(arg, sizeof(arg), &p);
4589             if (stream) {
4590                 video_enc.qmin = atoi(arg);
4591                 if (video_enc.qmin < 1 || video_enc.qmin > 31) {
4592                     ERROR("VideoQMin out of range\n");
4593                 }
4594             }
4595         } else if (!av_strcasecmp(cmd, "LumiMask")) {
4596             get_arg(arg, sizeof(arg), &p);
4597             if (stream)
4598                 video_enc.lumi_masking = atof(arg);
4599         } else if (!av_strcasecmp(cmd, "DarkMask")) {
4600             get_arg(arg, sizeof(arg), &p);
4601             if (stream)
4602                 video_enc.dark_masking = atof(arg);
4603         } else if (!av_strcasecmp(cmd, "NoVideo")) {
4604             video_id = AV_CODEC_ID_NONE;
4605         } else if (!av_strcasecmp(cmd, "NoAudio")) {
4606             audio_id = AV_CODEC_ID_NONE;
4607         } else if (!av_strcasecmp(cmd, "ACL")) {
4608             parse_acl_row(stream, feed, NULL, p, filename, line_num);
4609         } else if (!av_strcasecmp(cmd, "DynamicACL")) {
4610             if (stream) {
4611                 get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p);
4612             }
4613         } else if (!av_strcasecmp(cmd, "RTSPOption")) {
4614             get_arg(arg, sizeof(arg), &p);
4615             if (stream) {
4616                 av_freep(&stream->rtsp_option);
4617                 stream->rtsp_option = av_strdup(arg);
4618             }
4619         } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
4620             get_arg(arg, sizeof(arg), &p);
4621             if (stream) {
4622                 if (resolve_host(&stream->multicast_ip, arg) != 0) {
4623                     ERROR("Invalid host/IP address: %s\n", arg);
4624                 }
4625                 stream->is_multicast = 1;
4626                 stream->loop = 1; /* default is looping */
4627             }
4628         } else if (!av_strcasecmp(cmd, "MulticastPort")) {
4629             get_arg(arg, sizeof(arg), &p);
4630             if (stream)
4631                 stream->multicast_port = atoi(arg);
4632         } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
4633             get_arg(arg, sizeof(arg), &p);
4634             if (stream)
4635                 stream->multicast_ttl = atoi(arg);
4636         } else if (!av_strcasecmp(cmd, "NoLoop")) {
4637             if (stream)
4638                 stream->loop = 0;
4639         } else if (!av_strcasecmp(cmd, "</Stream>")) {
4640             if (!stream) {
4641                 ERROR("No corresponding <Stream> for </Stream>\n");
4642             } else {
4643                 if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) {
4644                     if (audio_id != AV_CODEC_ID_NONE) {
4645                         audio_enc.codec_type = AVMEDIA_TYPE_AUDIO;
4646                         audio_enc.codec_id = audio_id;
4647                         add_codec(stream, &audio_enc);
4648                     }
4649                     if (video_id != AV_CODEC_ID_NONE) {
4650                         video_enc.codec_type = AVMEDIA_TYPE_VIDEO;
4651                         video_enc.codec_id = video_id;
4652                         add_codec(stream, &video_enc);
4653                     }
4654                 }
4655                 stream = NULL;
4656             }
4657         } else if (!av_strcasecmp(cmd, "<Redirect")) {
4658             /*********************************************/
4659             char *q;
4660             if (stream || feed || redirect) {
4661                 ERROR("Already in a tag\n");
4662             } else {
4663                 redirect = av_mallocz(sizeof(FFStream));
4664                 if (!redirect) {
4665                     ret = AVERROR(ENOMEM);
4666                     goto end;
4667                 }
4668                 *last_stream = redirect;
4669                 last_stream = &redirect->next;
4670
4671                 get_arg(redirect->filename, sizeof(redirect->filename), &p);
4672                 q = strrchr(redirect->filename, '>');
4673                 if (*q)
4674                     *q = '\0';
4675                 redirect->stream_type = STREAM_TYPE_REDIRECT;
4676             }
4677         } else if (!av_strcasecmp(cmd, "URL")) {
4678             if (redirect)
4679                 get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p);
4680         } else if (!av_strcasecmp(cmd, "</Redirect>")) {
4681             if (!redirect) {
4682                 ERROR("No corresponding <Redirect> for </Redirect>\n");
4683             } else {
4684                 if (!redirect->feed_filename[0]) {
4685                     ERROR("No URL found for <Redirect>\n");
4686                 }
4687                 redirect = NULL;
4688             }
4689         } else if (!av_strcasecmp(cmd, "LoadModule")) {
4690             ERROR("Loadable modules no longer supported\n");
4691         } else {
4692             ERROR("Incorrect keyword: '%s'\n", cmd);
4693         }
4694     }
4695 #undef ERROR
4696
4697 end:
4698     fclose(f);
4699     if (ret < 0)
4700         return ret;
4701     if (errors)
4702         return AVERROR(EINVAL);
4703     else
4704         return 0;
4705 }
4706
4707 static void handle_child_exit(int sig)
4708 {
4709     pid_t pid;
4710     int status;
4711
4712     while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
4713         FFStream *feed;
4714
4715         for (feed = first_feed; feed; feed = feed->next) {
4716             if (feed->pid == pid) {
4717                 int uptime = time(0) - feed->pid_start;
4718
4719                 feed->pid = 0;
4720                 fprintf(stderr, "%s: Pid %d exited with status %d after %d seconds\n", feed->filename, pid, status, uptime);
4721
4722                 if (uptime < 30)
4723                     /* Turn off any more restarts */
4724                     feed->child_argv = 0;
4725             }
4726         }
4727     }
4728
4729     need_to_start_children = 1;
4730 }
4731
4732 static void opt_debug(void)
4733 {
4734     ffserver_debug = 1;
4735     logfilename[0] = '-';
4736 }
4737
4738 void show_help_default(const char *opt, const char *arg)
4739 {
4740     printf("usage: ffserver [options]\n"
4741            "Hyper fast multi format Audio/Video streaming server\n");
4742     printf("\n");
4743     show_help_options(options, "Main options:", 0, 0, 0);
4744 }
4745
4746 static const OptionDef options[] = {
4747 #include "cmdutils_common_opts.h"
4748     { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" },
4749     { "d", 0, {(void*)opt_debug}, "enable debug mode" },
4750     { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/ffserver.conf", "configfile" },
4751     { NULL },
4752 };
4753
4754 int main(int argc, char **argv)
4755 {
4756     struct sigaction sigact = { { 0 } };
4757     int ret = 0;
4758
4759     config_filename = av_strdup("/etc/ffserver.conf");
4760
4761     parse_loglevel(argc, argv, options);
4762     av_register_all();
4763     avformat_network_init();
4764
4765     show_banner(argc, argv, options);
4766
4767     my_program_name = argv[0];
4768
4769     parse_options(NULL, argc, argv, options, NULL);
4770
4771     unsetenv("http_proxy");             /* Kill the http_proxy */
4772
4773     av_lfg_init(&random_state, av_get_random_seed());
4774
4775     sigact.sa_handler = handle_child_exit;
4776     sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
4777     sigaction(SIGCHLD, &sigact, 0);
4778
4779     if ((ret = parse_ffconfig(config_filename)) < 0) {
4780         fprintf(stderr, "Error reading configuration file '%s': %s\n",
4781                 config_filename, av_err2str(ret));
4782         exit(1);
4783     }
4784     av_freep(&config_filename);
4785
4786     /* open log file if needed */
4787     if (logfilename[0] != '\0') {
4788         if (!strcmp(logfilename, "-"))
4789             logfile = stdout;
4790         else
4791             logfile = fopen(logfilename, "a");
4792         av_log_set_callback(http_av_log);
4793     }
4794
4795     build_file_streams();
4796
4797     build_feed_streams();
4798
4799     compute_bandwidth();
4800
4801     /* signal init */
4802     signal(SIGPIPE, SIG_IGN);
4803
4804     if (http_server() < 0) {
4805         http_log("Could not start server\n");
4806         exit(1);
4807     }
4808
4809     return 0;
4810 }