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