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