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