ffserver: cosmetics and grammar
[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             /* change state to send data */
632             rtp_c->state = HTTPSTATE_SEND_DATA;
633         }
634     }
635 }
636
637 /* main loop of the HTTP server */
638 static int http_server(void)
639 {
640     int server_fd = 0, rtsp_server_fd = 0;
641     int ret, delay, delay1;
642     struct pollfd *poll_table, *poll_entry;
643     HTTPContext *c, *c_next;
644
645     if(!(poll_table = av_mallocz((nb_max_http_connections + 2)*sizeof(*poll_table)))) {
646         http_log("Impossible to allocate a poll table handling %d connections.\n", nb_max_http_connections);
647         return -1;
648     }
649
650     if (my_http_addr.sin_port) {
651         server_fd = socket_open_listen(&my_http_addr);
652         if (server_fd < 0)
653             return -1;
654     }
655
656     if (my_rtsp_addr.sin_port) {
657         rtsp_server_fd = socket_open_listen(&my_rtsp_addr);
658         if (rtsp_server_fd < 0)
659             return -1;
660     }
661
662     if (!rtsp_server_fd && !server_fd) {
663         http_log("HTTP and RTSP disabled.\n");
664         return -1;
665     }
666
667     http_log("FFserver started.\n");
668
669     start_children(first_feed);
670
671     start_multicast();
672
673     for(;;) {
674         poll_entry = poll_table;
675         if (server_fd) {
676             poll_entry->fd = server_fd;
677             poll_entry->events = POLLIN;
678             poll_entry++;
679         }
680         if (rtsp_server_fd) {
681             poll_entry->fd = rtsp_server_fd;
682             poll_entry->events = POLLIN;
683             poll_entry++;
684         }
685
686         /* wait for events on each HTTP handle */
687         c = first_http_ctx;
688         delay = 1000;
689         while (c != NULL) {
690             int fd;
691             fd = c->fd;
692             switch(c->state) {
693             case HTTPSTATE_SEND_HEADER:
694             case RTSPSTATE_SEND_REPLY:
695             case RTSPSTATE_SEND_PACKET:
696                 c->poll_entry = poll_entry;
697                 poll_entry->fd = fd;
698                 poll_entry->events = POLLOUT;
699                 poll_entry++;
700                 break;
701             case HTTPSTATE_SEND_DATA_HEADER:
702             case HTTPSTATE_SEND_DATA:
703             case HTTPSTATE_SEND_DATA_TRAILER:
704                 if (!c->is_packetized) {
705                     /* for TCP, we output as much as we can
706                      * (may need to put a limit) */
707                     c->poll_entry = poll_entry;
708                     poll_entry->fd = fd;
709                     poll_entry->events = POLLOUT;
710                     poll_entry++;
711                 } else {
712                     /* when ffserver is doing the timing, we work by
713                        looking at which packet needs to be sent every
714                        10 ms */
715                     delay1 = 10; /* one tick wait XXX: 10 ms assumed */
716                     if (delay1 < delay)
717                         delay = delay1;
718                 }
719                 break;
720             case HTTPSTATE_WAIT_REQUEST:
721             case HTTPSTATE_RECEIVE_DATA:
722             case HTTPSTATE_WAIT_FEED:
723             case RTSPSTATE_WAIT_REQUEST:
724                 /* need to catch errors */
725                 c->poll_entry = poll_entry;
726                 poll_entry->fd = fd;
727                 poll_entry->events = POLLIN;/* Maybe this will work */
728                 poll_entry++;
729                 break;
730             default:
731                 c->poll_entry = NULL;
732                 break;
733             }
734             c = c->next;
735         }
736
737         /* wait for an event on one connection. We poll at least every
738            second to handle timeouts */
739         do {
740             ret = poll(poll_table, poll_entry - poll_table, delay);
741             if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
742                 ff_neterrno() != AVERROR(EINTR))
743                 return -1;
744         } while (ret < 0);
745
746         cur_time = av_gettime() / 1000;
747
748         if (need_to_start_children) {
749             need_to_start_children = 0;
750             start_children(first_feed);
751         }
752
753         /* now handle the events */
754         for(c = first_http_ctx; c != NULL; c = c_next) {
755             c_next = c->next;
756             if (handle_connection(c) < 0) {
757                 /* close and free the connection */
758                 log_connection(c);
759                 close_connection(c);
760             }
761         }
762
763         poll_entry = poll_table;
764         if (server_fd) {
765             /* new HTTP connection request ? */
766             if (poll_entry->revents & POLLIN)
767                 new_connection(server_fd, 0);
768             poll_entry++;
769         }
770         if (rtsp_server_fd) {
771             /* new RTSP connection request ? */
772             if (poll_entry->revents & POLLIN)
773                 new_connection(rtsp_server_fd, 1);
774         }
775     }
776 }
777
778 /* start waiting for a new HTTP/RTSP request */
779 static void start_wait_request(HTTPContext *c, int is_rtsp)
780 {
781     c->buffer_ptr = c->buffer;
782     c->buffer_end = c->buffer + c->buffer_size - 1; /* leave room for '\0' */
783
784     if (is_rtsp) {
785         c->timeout = cur_time + RTSP_REQUEST_TIMEOUT;
786         c->state = RTSPSTATE_WAIT_REQUEST;
787     } else {
788         c->timeout = cur_time + HTTP_REQUEST_TIMEOUT;
789         c->state = HTTPSTATE_WAIT_REQUEST;
790     }
791 }
792
793 static void http_send_too_busy_reply(int fd)
794 {
795     char buffer[400];
796     int len = snprintf(buffer, sizeof(buffer),
797                        "HTTP/1.0 503 Server too busy\r\n"
798                        "Content-type: text/html\r\n"
799                        "\r\n"
800                        "<html><head><title>Too busy</title></head><body>\r\n"
801                        "<p>The server is too busy to serve your request at this time.</p>\r\n"
802                        "<p>The number of current connections is %u, and this exceeds the limit of %u.</p>\r\n"
803                        "</body></html>\r\n",
804                        nb_connections, nb_max_connections);
805     av_assert0(len < sizeof(buffer));
806     send(fd, buffer, len, 0);
807 }
808
809
810 static void new_connection(int server_fd, int is_rtsp)
811 {
812     struct sockaddr_in from_addr;
813     socklen_t len;
814     int fd;
815     HTTPContext *c = NULL;
816
817     len = sizeof(from_addr);
818     fd = accept(server_fd, (struct sockaddr *)&from_addr,
819                 &len);
820     if (fd < 0) {
821         http_log("error during accept %s\n", strerror(errno));
822         return;
823     }
824     ff_socket_nonblock(fd, 1);
825
826     if (nb_connections >= nb_max_connections) {
827         http_send_too_busy_reply(fd);
828         goto fail;
829     }
830
831     /* add a new connection */
832     c = av_mallocz(sizeof(HTTPContext));
833     if (!c)
834         goto fail;
835
836     c->fd = fd;
837     c->poll_entry = NULL;
838     c->from_addr = from_addr;
839     c->buffer_size = IOBUFFER_INIT_SIZE;
840     c->buffer = av_malloc(c->buffer_size);
841     if (!c->buffer)
842         goto fail;
843
844     c->next = first_http_ctx;
845     first_http_ctx = c;
846     nb_connections++;
847
848     start_wait_request(c, is_rtsp);
849
850     return;
851
852  fail:
853     if (c) {
854         av_free(c->buffer);
855         av_free(c);
856     }
857     closesocket(fd);
858 }
859
860 static void close_connection(HTTPContext *c)
861 {
862     HTTPContext **cp, *c1;
863     int i, nb_streams;
864     AVFormatContext *ctx;
865     URLContext *h;
866     AVStream *st;
867
868     /* remove connection from list */
869     cp = &first_http_ctx;
870     while ((*cp) != NULL) {
871         c1 = *cp;
872         if (c1 == c)
873             *cp = c->next;
874         else
875             cp = &c1->next;
876     }
877
878     /* remove references, if any (XXX: do it faster) */
879     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
880         if (c1->rtsp_c == c)
881             c1->rtsp_c = NULL;
882     }
883
884     /* remove connection associated resources */
885     if (c->fd >= 0)
886         closesocket(c->fd);
887     if (c->fmt_in) {
888         /* close each frame parser */
889         for(i=0;i<c->fmt_in->nb_streams;i++) {
890             st = c->fmt_in->streams[i];
891             if (st->codec->codec)
892                 avcodec_close(st->codec);
893         }
894         avformat_close_input(&c->fmt_in);
895     }
896
897     /* free RTP output streams if any */
898     nb_streams = 0;
899     if (c->stream)
900         nb_streams = c->stream->nb_streams;
901
902     for(i=0;i<nb_streams;i++) {
903         ctx = c->rtp_ctx[i];
904         if (ctx) {
905             av_write_trailer(ctx);
906             av_dict_free(&ctx->metadata);
907             av_free(ctx->streams[0]);
908             av_free(ctx);
909         }
910         h = c->rtp_handles[i];
911         if (h)
912             ffurl_close(h);
913     }
914
915     ctx = &c->fmt_ctx;
916
917     if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
918         if (ctx->oformat) {
919             /* prepare header */
920             if (avio_open_dyn_buf(&ctx->pb) >= 0) {
921                 av_write_trailer(ctx);
922                 av_freep(&c->pb_buffer);
923                 avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
924             }
925         }
926     }
927
928     for(i=0; i<ctx->nb_streams; i++)
929         av_free(ctx->streams[i]);
930     av_freep(&ctx->streams);
931     av_freep(&ctx->priv_data);
932
933     if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
934         current_bandwidth -= c->stream->bandwidth;
935
936     /* signal that there is no feed if we are the feeder socket */
937     if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
938         c->stream->feed_opened = 0;
939         close(c->feed_fd);
940     }
941
942     av_freep(&c->pb_buffer);
943     av_freep(&c->packet_buffer);
944     av_free(c->buffer);
945     av_free(c);
946     nb_connections--;
947 }
948
949 static int handle_connection(HTTPContext *c)
950 {
951     int len, ret;
952
953     switch(c->state) {
954     case HTTPSTATE_WAIT_REQUEST:
955     case RTSPSTATE_WAIT_REQUEST:
956         /* timeout ? */
957         if ((c->timeout - cur_time) < 0)
958             return -1;
959         if (c->poll_entry->revents & (POLLERR | POLLHUP))
960             return -1;
961
962         /* no need to read if no events */
963         if (!(c->poll_entry->revents & POLLIN))
964             return 0;
965         /* read the data */
966     read_loop:
967         len = recv(c->fd, c->buffer_ptr, 1, 0);
968         if (len < 0) {
969             if (ff_neterrno() != AVERROR(EAGAIN) &&
970                 ff_neterrno() != AVERROR(EINTR))
971                 return -1;
972         } else if (len == 0) {
973             return -1;
974         } else {
975             /* search for end of request. */
976             uint8_t *ptr;
977             c->buffer_ptr += len;
978             ptr = c->buffer_ptr;
979             if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
980                 (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
981                 /* request found : parse it and reply */
982                 if (c->state == HTTPSTATE_WAIT_REQUEST) {
983                     ret = http_parse_request(c);
984                 } else {
985                     ret = rtsp_parse_request(c);
986                 }
987                 if (ret < 0)
988                     return -1;
989             } else if (ptr >= c->buffer_end) {
990                 /* request too long: cannot do anything */
991                 return -1;
992             } else goto read_loop;
993         }
994         break;
995
996     case HTTPSTATE_SEND_HEADER:
997         if (c->poll_entry->revents & (POLLERR | POLLHUP))
998             return -1;
999
1000         /* no need to write if no events */
1001         if (!(c->poll_entry->revents & POLLOUT))
1002             return 0;
1003         len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
1004         if (len < 0) {
1005             if (ff_neterrno() != AVERROR(EAGAIN) &&
1006                 ff_neterrno() != AVERROR(EINTR)) {
1007                 /* error : close connection */
1008                 av_freep(&c->pb_buffer);
1009                 return -1;
1010             }
1011         } else {
1012             c->buffer_ptr += len;
1013             if (c->stream)
1014                 c->stream->bytes_served += len;
1015             c->data_count += len;
1016             if (c->buffer_ptr >= c->buffer_end) {
1017                 av_freep(&c->pb_buffer);
1018                 /* if error, exit */
1019                 if (c->http_error)
1020                     return -1;
1021                 /* all the buffer was sent : synchronize to the incoming
1022                  * stream */
1023                 c->state = HTTPSTATE_SEND_DATA_HEADER;
1024                 c->buffer_ptr = c->buffer_end = c->buffer;
1025             }
1026         }
1027         break;
1028
1029     case HTTPSTATE_SEND_DATA:
1030     case HTTPSTATE_SEND_DATA_HEADER:
1031     case HTTPSTATE_SEND_DATA_TRAILER:
1032         /* for packetized output, we consider we can always write (the
1033            input streams set the speed). It may be better to verify
1034            that we do not rely too much on the kernel queues */
1035         if (!c->is_packetized) {
1036             if (c->poll_entry->revents & (POLLERR | POLLHUP))
1037                 return -1;
1038
1039             /* no need to read if no events */
1040             if (!(c->poll_entry->revents & POLLOUT))
1041                 return 0;
1042         }
1043         if (http_send_data(c) < 0)
1044             return -1;
1045         /* close connection if trailer sent */
1046         if (c->state == HTTPSTATE_SEND_DATA_TRAILER)
1047             return -1;
1048         break;
1049     case HTTPSTATE_RECEIVE_DATA:
1050         /* no need to read if no events */
1051         if (c->poll_entry->revents & (POLLERR | POLLHUP))
1052             return -1;
1053         if (!(c->poll_entry->revents & POLLIN))
1054             return 0;
1055         if (http_receive_data(c) < 0)
1056             return -1;
1057         break;
1058     case HTTPSTATE_WAIT_FEED:
1059         /* no need to read if no events */
1060         if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))
1061             return -1;
1062
1063         /* nothing to do, we'll be waken up by incoming feed packets */
1064         break;
1065
1066     case RTSPSTATE_SEND_REPLY:
1067         if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
1068             av_freep(&c->pb_buffer);
1069             return -1;
1070         }
1071         /* no need to write if no events */
1072         if (!(c->poll_entry->revents & POLLOUT))
1073             return 0;
1074         len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
1075         if (len < 0) {
1076             if (ff_neterrno() != AVERROR(EAGAIN) &&
1077                 ff_neterrno() != AVERROR(EINTR)) {
1078                 /* error : close connection */
1079                 av_freep(&c->pb_buffer);
1080                 return -1;
1081             }
1082         } else {
1083             c->buffer_ptr += len;
1084             c->data_count += len;
1085             if (c->buffer_ptr >= c->buffer_end) {
1086                 /* all the buffer was sent : wait for a new request */
1087                 av_freep(&c->pb_buffer);
1088                 start_wait_request(c, 1);
1089             }
1090         }
1091         break;
1092     case RTSPSTATE_SEND_PACKET:
1093         if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
1094             av_freep(&c->packet_buffer);
1095             return -1;
1096         }
1097         /* no need to write if no events */
1098         if (!(c->poll_entry->revents & POLLOUT))
1099             return 0;
1100         len = send(c->fd, c->packet_buffer_ptr,
1101                     c->packet_buffer_end - c->packet_buffer_ptr, 0);
1102         if (len < 0) {
1103             if (ff_neterrno() != AVERROR(EAGAIN) &&
1104                 ff_neterrno() != AVERROR(EINTR)) {
1105                 /* error : close connection */
1106                 av_freep(&c->packet_buffer);
1107                 return -1;
1108             }
1109         } else {
1110             c->packet_buffer_ptr += len;
1111             if (c->packet_buffer_ptr >= c->packet_buffer_end) {
1112                 /* all the buffer was sent : wait for a new request */
1113                 av_freep(&c->packet_buffer);
1114                 c->state = RTSPSTATE_WAIT_REQUEST;
1115             }
1116         }
1117         break;
1118     case HTTPSTATE_READY:
1119         /* nothing to do */
1120         break;
1121     default:
1122         return -1;
1123     }
1124     return 0;
1125 }
1126
1127 static int extract_rates(char *rates, int ratelen, const char *request)
1128 {
1129     const char *p;
1130
1131     for (p = request; *p && *p != '\r' && *p != '\n'; ) {
1132         if (av_strncasecmp(p, "Pragma:", 7) == 0) {
1133             const char *q = p + 7;
1134
1135             while (*q && *q != '\n' && av_isspace(*q))
1136                 q++;
1137
1138             if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) {
1139                 int stream_no;
1140                 int rate_no;
1141
1142                 q += 20;
1143
1144                 memset(rates, 0xff, ratelen);
1145
1146                 while (1) {
1147                     while (*q && *q != '\n' && *q != ':')
1148                         q++;
1149
1150                     if (sscanf(q, ":%d:%d", &stream_no, &rate_no) != 2)
1151                         break;
1152
1153                     stream_no--;
1154                     if (stream_no < ratelen && stream_no >= 0)
1155                         rates[stream_no] = rate_no;
1156
1157                     while (*q && *q != '\n' && !av_isspace(*q))
1158                         q++;
1159                 }
1160
1161                 return 1;
1162             }
1163         }
1164         p = strchr(p, '\n');
1165         if (!p)
1166             break;
1167
1168         p++;
1169     }
1170
1171     return 0;
1172 }
1173
1174 static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate)
1175 {
1176     int i;
1177     int best_bitrate = 100000000;
1178     int best = -1;
1179
1180     for (i = 0; i < feed->nb_streams; i++) {
1181         AVCodecContext *feed_codec = feed->streams[i]->codec;
1182
1183         if (feed_codec->codec_id != codec->codec_id ||
1184             feed_codec->sample_rate != codec->sample_rate ||
1185             feed_codec->width != codec->width ||
1186             feed_codec->height != codec->height)
1187             continue;
1188
1189         /* Potential stream */
1190
1191         /* We want the fastest stream less than bit_rate, or the slowest
1192          * faster than bit_rate
1193          */
1194
1195         if (feed_codec->bit_rate <= bit_rate) {
1196             if (best_bitrate > bit_rate || feed_codec->bit_rate > best_bitrate) {
1197                 best_bitrate = feed_codec->bit_rate;
1198                 best = i;
1199             }
1200         } else {
1201             if (feed_codec->bit_rate < best_bitrate) {
1202                 best_bitrate = feed_codec->bit_rate;
1203                 best = i;
1204             }
1205         }
1206     }
1207
1208     return best;
1209 }
1210
1211 static int modify_current_stream(HTTPContext *c, char *rates)
1212 {
1213     int i;
1214     FFStream *req = c->stream;
1215     int action_required = 0;
1216
1217     /* Not much we can do for a feed */
1218     if (!req->feed)
1219         return 0;
1220
1221     for (i = 0; i < req->nb_streams; i++) {
1222         AVCodecContext *codec = req->streams[i]->codec;
1223
1224         switch(rates[i]) {
1225             case 0:
1226                 c->switch_feed_streams[i] = req->feed_streams[i];
1227                 break;
1228             case 1:
1229                 c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 2);
1230                 break;
1231             case 2:
1232                 /* Wants off or slow */
1233                 c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 4);
1234 #ifdef WANTS_OFF
1235                 /* This doesn't work well when it turns off the only stream! */
1236                 c->switch_feed_streams[i] = -2;
1237                 c->feed_streams[i] = -2;
1238 #endif
1239                 break;
1240         }
1241
1242         if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i])
1243             action_required = 1;
1244     }
1245
1246     return action_required;
1247 }
1248
1249 /* XXX: factorize in utils.c ? */
1250 /* XXX: take care with different space meaning */
1251 static void skip_spaces(const char **pp)
1252 {
1253     const char *p;
1254     p = *pp;
1255     while (*p == ' ' || *p == '\t')
1256         p++;
1257     *pp = p;
1258 }
1259
1260 static void get_word(char *buf, int buf_size, const char **pp)
1261 {
1262     const char *p;
1263     char *q;
1264
1265     p = *pp;
1266     skip_spaces(&p);
1267     q = buf;
1268     while (!av_isspace(*p) && *p != '\0') {
1269         if ((q - buf) < buf_size - 1)
1270             *q++ = *p;
1271         p++;
1272     }
1273     if (buf_size > 0)
1274         *q = '\0';
1275     *pp = p;
1276 }
1277
1278 static void get_arg(char *buf, int buf_size, const char **pp)
1279 {
1280     const char *p;
1281     char *q;
1282     int quote;
1283
1284     p = *pp;
1285     while (av_isspace(*p)) p++;
1286     q = buf;
1287     quote = 0;
1288     if (*p == '\"' || *p == '\'')
1289         quote = *p++;
1290     for(;;) {
1291         if (quote) {
1292             if (*p == quote)
1293                 break;
1294         } else {
1295             if (av_isspace(*p))
1296                 break;
1297         }
1298         if (*p == '\0')
1299             break;
1300         if ((q - buf) < buf_size - 1)
1301             *q++ = *p;
1302         p++;
1303     }
1304     *q = '\0';
1305     if (quote && *p == quote)
1306         p++;
1307     *pp = p;
1308 }
1309
1310 static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
1311                          const char *p, const char *filename, int line_num)
1312 {
1313     char arg[1024];
1314     IPAddressACL acl;
1315     int errors = 0;
1316
1317     get_arg(arg, sizeof(arg), &p);
1318     if (av_strcasecmp(arg, "allow") == 0)
1319         acl.action = IP_ALLOW;
1320     else if (av_strcasecmp(arg, "deny") == 0)
1321         acl.action = IP_DENY;
1322     else {
1323         fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
1324                 filename, line_num, arg);
1325         errors++;
1326     }
1327
1328     get_arg(arg, sizeof(arg), &p);
1329
1330     if (resolve_host(&acl.first, arg) != 0) {
1331         fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
1332                 filename, line_num, arg);
1333         errors++;
1334     } else
1335         acl.last = acl.first;
1336
1337     get_arg(arg, sizeof(arg), &p);
1338
1339     if (arg[0]) {
1340         if (resolve_host(&acl.last, arg) != 0) {
1341             fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
1342                     filename, line_num, arg);
1343             errors++;
1344         }
1345     }
1346
1347     if (!errors) {
1348         IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
1349         IPAddressACL **naclp = 0;
1350
1351         acl.next = 0;
1352         *nacl = acl;
1353
1354         if (stream)
1355             naclp = &stream->acl;
1356         else if (feed)
1357             naclp = &feed->acl;
1358         else if (ext_acl)
1359             naclp = &ext_acl;
1360         else {
1361             fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
1362                     filename, line_num);
1363             errors++;
1364         }
1365
1366         if (naclp) {
1367             while (*naclp)
1368                 naclp = &(*naclp)->next;
1369
1370             *naclp = nacl;
1371         }
1372     }
1373 }
1374
1375
1376 static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
1377 {
1378     FILE* f;
1379     char line[1024];
1380     char  cmd[1024];
1381     IPAddressACL *acl = NULL;
1382     int line_num = 0;
1383     const char *p;
1384
1385     f = fopen(stream->dynamic_acl, "r");
1386     if (!f) {
1387         perror(stream->dynamic_acl);
1388         return NULL;
1389     }
1390
1391     acl = av_mallocz(sizeof(IPAddressACL));
1392
1393     /* Build ACL */
1394     for(;;) {
1395         if (fgets(line, sizeof(line), f) == NULL)
1396             break;
1397         line_num++;
1398         p = line;
1399         while (av_isspace(*p))
1400             p++;
1401         if (*p == '\0' || *p == '#')
1402             continue;
1403         get_arg(cmd, sizeof(cmd), &p);
1404
1405         if (!av_strcasecmp(cmd, "ACL"))
1406             parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
1407     }
1408     fclose(f);
1409     return acl;
1410 }
1411
1412
1413 static void free_acl_list(IPAddressACL *in_acl)
1414 {
1415     IPAddressACL *pacl,*pacl2;
1416
1417     pacl = in_acl;
1418     while(pacl) {
1419         pacl2 = pacl;
1420         pacl = pacl->next;
1421         av_freep(pacl2);
1422     }
1423 }
1424
1425 static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)
1426 {
1427     enum IPAddressAction last_action = IP_DENY;
1428     IPAddressACL *acl;
1429     struct in_addr *src = &c->from_addr.sin_addr;
1430     unsigned long src_addr = src->s_addr;
1431
1432     for (acl = in_acl; acl; acl = acl->next) {
1433         if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr)
1434             return (acl->action == IP_ALLOW) ? 1 : 0;
1435         last_action = acl->action;
1436     }
1437
1438     /* Nothing matched, so return not the last action */
1439     return (last_action == IP_DENY) ? 1 : 0;
1440 }
1441
1442 static int validate_acl(FFStream *stream, HTTPContext *c)
1443 {
1444     int ret = 0;
1445     IPAddressACL *acl;
1446
1447
1448     /* if stream->acl is null validate_acl_list will return 1 */
1449     ret = validate_acl_list(stream->acl, c);
1450
1451     if (stream->dynamic_acl[0]) {
1452         acl = parse_dynamic_acl(stream, c);
1453
1454         ret = validate_acl_list(acl, c);
1455
1456         free_acl_list(acl);
1457     }
1458
1459     return ret;
1460 }
1461
1462 /* compute the real filename of a file by matching it without its
1463    extensions to all the stream's filenames */
1464 static void compute_real_filename(char *filename, int max_size)
1465 {
1466     char file1[1024];
1467     char file2[1024];
1468     char *p;
1469     FFStream *stream;
1470
1471     /* compute filename by matching without the file extensions */
1472     av_strlcpy(file1, filename, sizeof(file1));
1473     p = strrchr(file1, '.');
1474     if (p)
1475         *p = '\0';
1476     for(stream = first_stream; stream != NULL; stream = stream->next) {
1477         av_strlcpy(file2, stream->filename, sizeof(file2));
1478         p = strrchr(file2, '.');
1479         if (p)
1480             *p = '\0';
1481         if (!strcmp(file1, file2)) {
1482             av_strlcpy(filename, stream->filename, max_size);
1483             break;
1484         }
1485     }
1486 }
1487
1488 enum RedirType {
1489     REDIR_NONE,
1490     REDIR_ASX,
1491     REDIR_RAM,
1492     REDIR_ASF,
1493     REDIR_RTSP,
1494     REDIR_SDP,
1495 };
1496
1497 /* parse HTTP request and prepare header */
1498 static int http_parse_request(HTTPContext *c)
1499 {
1500     const char *p;
1501     char *p1;
1502     enum RedirType redir_type;
1503     char cmd[32];
1504     char info[1024], filename[1024];
1505     char url[1024], *q;
1506     char protocol[32];
1507     char msg[1024];
1508     const char *mime_type;
1509     FFStream *stream;
1510     int i;
1511     char ratebuf[32];
1512     const char *useragent = 0;
1513
1514     p = c->buffer;
1515     get_word(cmd, sizeof(cmd), &p);
1516     av_strlcpy(c->method, cmd, sizeof(c->method));
1517
1518     if (!strcmp(cmd, "GET"))
1519         c->post = 0;
1520     else if (!strcmp(cmd, "POST"))
1521         c->post = 1;
1522     else
1523         return -1;
1524
1525     get_word(url, sizeof(url), &p);
1526     av_strlcpy(c->url, url, sizeof(c->url));
1527
1528     get_word(protocol, sizeof(protocol), (const char **)&p);
1529     if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
1530         return -1;
1531
1532     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
1533
1534     if (ffserver_debug)
1535         http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
1536
1537     /* find the filename and the optional info string in the request */
1538     p1 = strchr(url, '?');
1539     if (p1) {
1540         av_strlcpy(info, p1, sizeof(info));
1541         *p1 = '\0';
1542     } else
1543         info[0] = '\0';
1544
1545     av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
1546
1547     for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1548         if (av_strncasecmp(p, "User-Agent:", 11) == 0) {
1549             useragent = p + 11;
1550             if (*useragent && *useragent != '\n' && av_isspace(*useragent))
1551                 useragent++;
1552             break;
1553         }
1554         p = strchr(p, '\n');
1555         if (!p)
1556             break;
1557
1558         p++;
1559     }
1560
1561     redir_type = REDIR_NONE;
1562     if (av_match_ext(filename, "asx")) {
1563         redir_type = REDIR_ASX;
1564         filename[strlen(filename)-1] = 'f';
1565     } else if (av_match_ext(filename, "asf") &&
1566         (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) {
1567         /* if this isn't WMP or lookalike, return the redirector file */
1568         redir_type = REDIR_ASF;
1569     } else if (av_match_ext(filename, "rpm,ram")) {
1570         redir_type = REDIR_RAM;
1571         strcpy(filename + strlen(filename)-2, "m");
1572     } else if (av_match_ext(filename, "rtsp")) {
1573         redir_type = REDIR_RTSP;
1574         compute_real_filename(filename, sizeof(filename) - 1);
1575     } else if (av_match_ext(filename, "sdp")) {
1576         redir_type = REDIR_SDP;
1577         compute_real_filename(filename, sizeof(filename) - 1);
1578     }
1579
1580     // "redirect" / request to index.html
1581     if (!strlen(filename))
1582         av_strlcpy(filename, "index.html", sizeof(filename) - 1);
1583
1584     stream = first_stream;
1585     while (stream != NULL) {
1586         if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
1587             break;
1588         stream = stream->next;
1589     }
1590     if (stream == NULL) {
1591         snprintf(msg, sizeof(msg), "File '%s' not found", url);
1592         http_log("File '%s' not found\n", url);
1593         goto send_error;
1594     }
1595
1596     c->stream = stream;
1597     memcpy(c->feed_streams, stream->feed_streams, sizeof(c->feed_streams));
1598     memset(c->switch_feed_streams, -1, sizeof(c->switch_feed_streams));
1599
1600     if (stream->stream_type == STREAM_TYPE_REDIRECT) {
1601         c->http_error = 301;
1602         q = c->buffer;
1603         snprintf(q, c->buffer_size,
1604                       "HTTP/1.0 301 Moved\r\n"
1605                       "Location: %s\r\n"
1606                       "Content-type: text/html\r\n"
1607                       "\r\n"
1608                       "<html><head><title>Moved</title></head><body>\r\n"
1609                       "You should be <a href=\"%s\">redirected</a>.\r\n"
1610                       "</body></html>\r\n", stream->feed_filename, stream->feed_filename);
1611         q += strlen(q);
1612         /* prepare output buffer */
1613         c->buffer_ptr = c->buffer;
1614         c->buffer_end = q;
1615         c->state = HTTPSTATE_SEND_HEADER;
1616         return 0;
1617     }
1618
1619     /* If this is WMP, get the rate information */
1620     if (extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
1621         if (modify_current_stream(c, ratebuf)) {
1622             for (i = 0; i < FF_ARRAY_ELEMS(c->feed_streams); i++) {
1623                 if (c->switch_feed_streams[i] >= 0)
1624                     c->switch_feed_streams[i] = -1;
1625             }
1626         }
1627     }
1628
1629     if (c->post == 0 && stream->stream_type == STREAM_TYPE_LIVE)
1630         current_bandwidth += stream->bandwidth;
1631
1632     /* If already streaming this feed, do not let start another feeder. */
1633     if (stream->feed_opened) {
1634         snprintf(msg, sizeof(msg), "This feed is already being received.");
1635         http_log("Feed '%s' already being received\n", stream->feed_filename);
1636         goto send_error;
1637     }
1638
1639     if (c->post == 0 && max_bandwidth < current_bandwidth) {
1640         c->http_error = 503;
1641         q = c->buffer;
1642         snprintf(q, c->buffer_size,
1643                       "HTTP/1.0 503 Server too busy\r\n"
1644                       "Content-type: text/html\r\n"
1645                       "\r\n"
1646                       "<html><head><title>Too busy</title></head><body>\r\n"
1647                       "<p>The server is too busy to serve your request at this time.</p>\r\n"
1648                       "<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, "
1649                       "and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n"
1650                       "</body></html>\r\n", current_bandwidth, max_bandwidth);
1651         q += strlen(q);
1652         /* prepare output buffer */
1653         c->buffer_ptr = c->buffer;
1654         c->buffer_end = q;
1655         c->state = HTTPSTATE_SEND_HEADER;
1656         return 0;
1657     }
1658
1659     if (redir_type != REDIR_NONE) {
1660         const char *hostinfo = 0;
1661
1662         for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1663             if (av_strncasecmp(p, "Host:", 5) == 0) {
1664                 hostinfo = p + 5;
1665                 break;
1666             }
1667             p = strchr(p, '\n');
1668             if (!p)
1669                 break;
1670
1671             p++;
1672         }
1673
1674         if (hostinfo) {
1675             char *eoh;
1676             char hostbuf[260];
1677
1678             while (av_isspace(*hostinfo))
1679                 hostinfo++;
1680
1681             eoh = strchr(hostinfo, '\n');
1682             if (eoh) {
1683                 if (eoh[-1] == '\r')
1684                     eoh--;
1685
1686                 if (eoh - hostinfo < sizeof(hostbuf) - 1) {
1687                     memcpy(hostbuf, hostinfo, eoh - hostinfo);
1688                     hostbuf[eoh - hostinfo] = 0;
1689
1690                     c->http_error = 200;
1691                     q = c->buffer;
1692                     switch(redir_type) {
1693                     case REDIR_ASX:
1694                         snprintf(q, c->buffer_size,
1695                                       "HTTP/1.0 200 ASX Follows\r\n"
1696                                       "Content-type: video/x-ms-asf\r\n"
1697                                       "\r\n"
1698                                       "<ASX Version=\"3\">\r\n"
1699                                       //"<!-- Autogenerated by ffserver -->\r\n"
1700                                       "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n"
1701                                       "</ASX>\r\n", hostbuf, filename, info);
1702                         q += strlen(q);
1703                         break;
1704                     case REDIR_RAM:
1705                         snprintf(q, c->buffer_size,
1706                                       "HTTP/1.0 200 RAM Follows\r\n"
1707                                       "Content-type: audio/x-pn-realaudio\r\n"
1708                                       "\r\n"
1709                                       "# Autogenerated by ffserver\r\n"
1710                                       "http://%s/%s%s\r\n", hostbuf, filename, info);
1711                         q += strlen(q);
1712                         break;
1713                     case REDIR_ASF:
1714                         snprintf(q, c->buffer_size,
1715                                       "HTTP/1.0 200 ASF Redirect follows\r\n"
1716                                       "Content-type: video/x-ms-asf\r\n"
1717                                       "\r\n"
1718                                       "[Reference]\r\n"
1719                                       "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info);
1720                         q += strlen(q);
1721                         break;
1722                     case REDIR_RTSP:
1723                         {
1724                             char hostname[256], *p;
1725                             /* extract only hostname */
1726                             av_strlcpy(hostname, hostbuf, sizeof(hostname));
1727                             p = strrchr(hostname, ':');
1728                             if (p)
1729                                 *p = '\0';
1730                             snprintf(q, c->buffer_size,
1731                                           "HTTP/1.0 200 RTSP Redirect follows\r\n"
1732                                           /* XXX: incorrect mime type ? */
1733                                           "Content-type: application/x-rtsp\r\n"
1734                                           "\r\n"
1735                                           "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename);
1736                             q += strlen(q);
1737                         }
1738                         break;
1739                     case REDIR_SDP:
1740                         {
1741                             uint8_t *sdp_data;
1742                             int sdp_data_size;
1743                             socklen_t len;
1744                             struct sockaddr_in my_addr;
1745
1746                             snprintf(q, c->buffer_size,
1747                                           "HTTP/1.0 200 OK\r\n"
1748                                           "Content-type: application/sdp\r\n"
1749                                           "\r\n");
1750                             q += strlen(q);
1751
1752                             len = sizeof(my_addr);
1753                             getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
1754
1755                             /* XXX: should use a dynamic buffer */
1756                             sdp_data_size = prepare_sdp_description(stream,
1757                                                                     &sdp_data,
1758                                                                     my_addr.sin_addr);
1759                             if (sdp_data_size > 0) {
1760                                 memcpy(q, sdp_data, sdp_data_size);
1761                                 q += sdp_data_size;
1762                                 *q = '\0';
1763                                 av_free(sdp_data);
1764                             }
1765                         }
1766                         break;
1767                     default:
1768                         abort();
1769                         break;
1770                     }
1771
1772                     /* prepare output buffer */
1773                     c->buffer_ptr = c->buffer;
1774                     c->buffer_end = q;
1775                     c->state = HTTPSTATE_SEND_HEADER;
1776                     return 0;
1777                 }
1778             }
1779         }
1780
1781         snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
1782         goto send_error;
1783     }
1784
1785     stream->conns_served++;
1786
1787     /* XXX: add there authenticate and IP match */
1788
1789     if (c->post) {
1790         /* if post, it means a feed is being sent */
1791         if (!stream->is_feed) {
1792             /* However it might be a status report from WMP! Let us log the
1793              * data as it might come in handy one day. */
1794             const char *logline = 0;
1795             int client_id = 0;
1796
1797             for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1798                 if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) {
1799                     logline = p;
1800                     break;
1801                 }
1802                 if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0)
1803                     client_id = strtol(p + 18, 0, 10);
1804                 p = strchr(p, '\n');
1805                 if (!p)
1806                     break;
1807
1808                 p++;
1809             }
1810
1811             if (logline) {
1812                 char *eol = strchr(logline, '\n');
1813
1814                 logline += 17;
1815
1816                 if (eol) {
1817                     if (eol[-1] == '\r')
1818                         eol--;
1819                     http_log("%.*s\n", (int) (eol - logline), logline);
1820                     c->suppress_log = 1;
1821                 }
1822             }
1823
1824 #ifdef DEBUG
1825             http_log("\nGot request:\n%s\n", c->buffer);
1826 #endif
1827
1828             if (client_id && extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
1829                 HTTPContext *wmpc;
1830
1831                 /* Now we have to find the client_id */
1832                 for (wmpc = first_http_ctx; wmpc; wmpc = wmpc->next) {
1833                     if (wmpc->wmp_client_id == client_id)
1834                         break;
1835                 }
1836
1837                 if (wmpc && modify_current_stream(wmpc, ratebuf))
1838                     wmpc->switch_pending = 1;
1839             }
1840
1841             snprintf(msg, sizeof(msg), "POST command not handled");
1842             c->stream = 0;
1843             goto send_error;
1844         }
1845         if (http_start_receive_data(c) < 0) {
1846             snprintf(msg, sizeof(msg), "could not open feed");
1847             goto send_error;
1848         }
1849         c->http_error = 0;
1850         c->state = HTTPSTATE_RECEIVE_DATA;
1851         return 0;
1852     }
1853
1854 #ifdef DEBUG
1855     if (strcmp(stream->filename + strlen(stream->filename) - 4, ".asf") == 0)
1856         http_log("\nGot request:\n%s\n", c->buffer);
1857 #endif
1858
1859     if (c->stream->stream_type == STREAM_TYPE_STATUS)
1860         goto send_status;
1861
1862     /* open input stream */
1863     if (open_input_stream(c, info) < 0) {
1864         snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
1865         goto send_error;
1866     }
1867
1868     /* prepare HTTP header */
1869     c->buffer[0] = 0;
1870     av_strlcatf(c->buffer, c->buffer_size, "HTTP/1.0 200 OK\r\n");
1871     mime_type = c->stream->fmt->mime_type;
1872     if (!mime_type)
1873         mime_type = "application/x-octet-stream";
1874     av_strlcatf(c->buffer, c->buffer_size, "Pragma: no-cache\r\n");
1875
1876     /* for asf, we need extra headers */
1877     if (!strcmp(c->stream->fmt->name,"asf_stream")) {
1878         /* Need to allocate a client id */
1879
1880         c->wmp_client_id = av_lfg_get(&random_state);
1881
1882         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);
1883     }
1884     av_strlcatf(c->buffer, c->buffer_size, "Content-Type: %s\r\n", mime_type);
1885     av_strlcatf(c->buffer, c->buffer_size, "\r\n");
1886     q = c->buffer + strlen(c->buffer);
1887
1888     /* prepare output buffer */
1889     c->http_error = 0;
1890     c->buffer_ptr = c->buffer;
1891     c->buffer_end = q;
1892     c->state = HTTPSTATE_SEND_HEADER;
1893     return 0;
1894  send_error:
1895     c->http_error = 404;
1896     q = c->buffer;
1897     htmlstrip(msg);
1898     snprintf(q, c->buffer_size,
1899                   "HTTP/1.0 404 Not Found\r\n"
1900                   "Content-type: text/html\r\n"
1901                   "\r\n"
1902                   "<html>\n"
1903                   "<head><title>404 Not Found</title></head>\n"
1904                   "<body>%s</body>\n"
1905                   "</html>\n", msg);
1906     q += strlen(q);
1907     /* prepare output buffer */
1908     c->buffer_ptr = c->buffer;
1909     c->buffer_end = q;
1910     c->state = HTTPSTATE_SEND_HEADER;
1911     return 0;
1912  send_status:
1913     compute_status(c);
1914     c->http_error = 200; /* horrible : we use this value to avoid
1915                             going to the send data state */
1916     c->state = HTTPSTATE_SEND_HEADER;
1917     return 0;
1918 }
1919
1920 static void fmt_bytecount(AVIOContext *pb, int64_t count)
1921 {
1922     static const char suffix[] = " kMGTP";
1923     const char *s;
1924
1925     for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++);
1926
1927     avio_printf(pb, "%"PRId64"%c", count, *s);
1928 }
1929
1930 static void compute_status(HTTPContext *c)
1931 {
1932     HTTPContext *c1;
1933     FFStream *stream;
1934     char *p;
1935     time_t ti;
1936     int i, len;
1937     AVIOContext *pb;
1938
1939     if (avio_open_dyn_buf(&pb) < 0) {
1940         /* XXX: return an error ? */
1941         c->buffer_ptr = c->buffer;
1942         c->buffer_end = c->buffer;
1943         return;
1944     }
1945
1946     avio_printf(pb, "HTTP/1.0 200 OK\r\n");
1947     avio_printf(pb, "Content-type: %s\r\n", "text/html");
1948     avio_printf(pb, "Pragma: no-cache\r\n");
1949     avio_printf(pb, "\r\n");
1950
1951     avio_printf(pb, "<html><head><title>%s Status</title>\n", program_name);
1952     if (c->stream->feed_filename[0])
1953         avio_printf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
1954     avio_printf(pb, "</head>\n<body>");
1955     avio_printf(pb, "<h1>%s Status</h1>\n", program_name);
1956     /* format status */
1957     avio_printf(pb, "<h2>Available Streams</h2>\n");
1958     avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
1959     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");
1960     stream = first_stream;
1961     while (stream != NULL) {
1962         char sfilename[1024];
1963         char *eosf;
1964
1965         if (stream->feed != stream) {
1966             av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);
1967             eosf = sfilename + strlen(sfilename);
1968             if (eosf - sfilename >= 4) {
1969                 if (strcmp(eosf - 4, ".asf") == 0)
1970                     strcpy(eosf - 4, ".asx");
1971                 else if (strcmp(eosf - 3, ".rm") == 0)
1972                     strcpy(eosf - 3, ".ram");
1973                 else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
1974                     /* generate a sample RTSP director if
1975                        unicast. Generate an SDP redirector if
1976                        multicast */
1977                     eosf = strrchr(sfilename, '.');
1978                     if (!eosf)
1979                         eosf = sfilename + strlen(sfilename);
1980                     if (stream->is_multicast)
1981                         strcpy(eosf, ".sdp");
1982                     else
1983                         strcpy(eosf, ".rtsp");
1984                 }
1985             }
1986
1987             avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
1988                          sfilename, stream->filename);
1989             avio_printf(pb, "<td align=right> %d <td align=right> ",
1990                         stream->conns_served);
1991             fmt_bytecount(pb, stream->bytes_served);
1992             switch(stream->stream_type) {
1993             case STREAM_TYPE_LIVE: {
1994                     int audio_bit_rate = 0;
1995                     int video_bit_rate = 0;
1996                     const char *audio_codec_name = "";
1997                     const char *video_codec_name = "";
1998                     const char *audio_codec_name_extra = "";
1999                     const char *video_codec_name_extra = "";
2000
2001                     for(i=0;i<stream->nb_streams;i++) {
2002                         AVStream *st = stream->streams[i];
2003                         AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
2004                         switch(st->codec->codec_type) {
2005                         case AVMEDIA_TYPE_AUDIO:
2006                             audio_bit_rate += st->codec->bit_rate;
2007                             if (codec) {
2008                                 if (*audio_codec_name)
2009                                     audio_codec_name_extra = "...";
2010                                 audio_codec_name = codec->name;
2011                             }
2012                             break;
2013                         case AVMEDIA_TYPE_VIDEO:
2014                             video_bit_rate += st->codec->bit_rate;
2015                             if (codec) {
2016                                 if (*video_codec_name)
2017                                     video_codec_name_extra = "...";
2018                                 video_codec_name = codec->name;
2019                             }
2020                             break;
2021                         case AVMEDIA_TYPE_DATA:
2022                             video_bit_rate += st->codec->bit_rate;
2023                             break;
2024                         default:
2025                             abort();
2026                         }
2027                     }
2028                     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",
2029                                  stream->fmt->name,
2030                                  stream->bandwidth,
2031                                  video_bit_rate / 1000, video_codec_name, video_codec_name_extra,
2032                                  audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra);
2033                     if (stream->feed)
2034                         avio_printf(pb, "<td>%s", stream->feed->filename);
2035                     else
2036                         avio_printf(pb, "<td>%s", stream->feed_filename);
2037                     avio_printf(pb, "\n");
2038                 }
2039                 break;
2040             default:
2041                 avio_printf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
2042                 break;
2043             }
2044         }
2045         stream = stream->next;
2046     }
2047     avio_printf(pb, "</table>\n");
2048
2049     stream = first_stream;
2050     while (stream != NULL) {
2051         if (stream->feed == stream) {
2052             avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
2053             if (stream->pid) {
2054                 avio_printf(pb, "Running as pid %d.\n", stream->pid);
2055
2056 #if defined(linux)
2057                 {
2058                     FILE *pid_stat;
2059                     char ps_cmd[64];
2060
2061                     /* This is somewhat linux specific I guess */
2062                     snprintf(ps_cmd, sizeof(ps_cmd),
2063                              "ps -o \"%%cpu,cputime\" --no-headers %d",
2064                              stream->pid);
2065
2066                     pid_stat = popen(ps_cmd, "r");
2067                     if (pid_stat) {
2068                         char cpuperc[10];
2069                         char cpuused[64];
2070
2071                         if (fscanf(pid_stat, "%9s %63s", cpuperc,
2072                                    cpuused) == 2) {
2073                             avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
2074                                          cpuperc, cpuused);
2075                         }
2076                         fclose(pid_stat);
2077                     }
2078                 }
2079 #endif
2080
2081                 avio_printf(pb, "<p>");
2082             }
2083             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");
2084
2085             for (i = 0; i < stream->nb_streams; i++) {
2086                 AVStream *st = stream->streams[i];
2087                 AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
2088                 const char *type = "unknown";
2089                 char parameters[64];
2090
2091                 parameters[0] = 0;
2092
2093                 switch(st->codec->codec_type) {
2094                 case AVMEDIA_TYPE_AUDIO:
2095                     type = "audio";
2096                     snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate);
2097                     break;
2098                 case AVMEDIA_TYPE_VIDEO:
2099                     type = "video";
2100                     snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height,
2101                                 st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);
2102                     break;
2103                 default:
2104                     abort();
2105                 }
2106                 avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n",
2107                         i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);
2108             }
2109             avio_printf(pb, "</table>\n");
2110
2111         }
2112         stream = stream->next;
2113     }
2114
2115     /* connection status */
2116     avio_printf(pb, "<h2>Connection Status</h2>\n");
2117
2118     avio_printf(pb, "Number of connections: %d / %d<br>\n",
2119                  nb_connections, nb_max_connections);
2120
2121     avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
2122                  current_bandwidth, max_bandwidth);
2123
2124     avio_printf(pb, "<table>\n");
2125     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");
2126     c1 = first_http_ctx;
2127     i = 0;
2128     while (c1 != NULL) {
2129         int bitrate;
2130         int j;
2131
2132         bitrate = 0;
2133         if (c1->stream) {
2134             for (j = 0; j < c1->stream->nb_streams; j++) {
2135                 if (!c1->stream->feed)
2136                     bitrate += c1->stream->streams[j]->codec->bit_rate;
2137                 else if (c1->feed_streams[j] >= 0)
2138                     bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;
2139             }
2140         }
2141
2142         i++;
2143         p = inet_ntoa(c1->from_addr.sin_addr);
2144         avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>",
2145                     i,
2146                     c1->stream ? c1->stream->filename : "",
2147                     c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",
2148                     p,
2149                     c1->protocol,
2150                     http_state[c1->state]);
2151         fmt_bytecount(pb, bitrate);
2152         avio_printf(pb, "<td align=right>");
2153         fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
2154         avio_printf(pb, "<td align=right>");
2155         fmt_bytecount(pb, c1->data_count);
2156         avio_printf(pb, "\n");
2157         c1 = c1->next;
2158     }
2159     avio_printf(pb, "</table>\n");
2160
2161     /* date */
2162     ti = time(NULL);
2163     p = ctime(&ti);
2164     avio_printf(pb, "<hr size=1 noshade>Generated at %s", p);
2165     avio_printf(pb, "</body>\n</html>\n");
2166
2167     len = avio_close_dyn_buf(pb, &c->pb_buffer);
2168     c->buffer_ptr = c->pb_buffer;
2169     c->buffer_end = c->pb_buffer + len;
2170 }
2171
2172 static int open_input_stream(HTTPContext *c, const char *info)
2173 {
2174     char buf[128];
2175     char input_filename[1024];
2176     AVFormatContext *s = NULL;
2177     int buf_size, i, ret;
2178     int64_t stream_pos;
2179
2180     /* find file name */
2181     if (c->stream->feed) {
2182         strcpy(input_filename, c->stream->feed->feed_filename);
2183         buf_size = FFM_PACKET_SIZE;
2184         /* compute position (absolute time) */
2185         if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
2186             if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0) {
2187                 http_log("Invalid date specification '%s' for stream\n", buf);
2188                 return ret;
2189             }
2190         } else if (av_find_info_tag(buf, sizeof(buf), "buffer", info)) {
2191             int prebuffer = strtol(buf, 0, 10);
2192             stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
2193         } else
2194             stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000;
2195     } else {
2196         strcpy(input_filename, c->stream->feed_filename);
2197         buf_size = 0;
2198         /* compute position (relative time) */
2199         if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
2200             if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0) {
2201                 http_log("Invalid date specification '%s' for stream\n", buf);
2202                 return ret;
2203             }
2204         } else
2205             stream_pos = 0;
2206     }
2207     if (!input_filename[0]) {
2208         http_log("No filename was specified for stream\n");
2209         return AVERROR(EINVAL);
2210     }
2211
2212     /* open stream */
2213     if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) {
2214         http_log("Could not open input '%s': %s\n", input_filename, av_err2str(ret));
2215         return ret;
2216     }
2217
2218     /* set buffer size */
2219     if (buf_size > 0) ffio_set_buf_size(s->pb, buf_size);
2220
2221     s->flags |= AVFMT_FLAG_GENPTS;
2222     c->fmt_in = s;
2223     if (strcmp(s->iformat->name, "ffm") &&
2224         (ret = avformat_find_stream_info(c->fmt_in, NULL)) < 0) {
2225         http_log("Could not find stream info for input '%s'\n", input_filename);
2226         avformat_close_input(&s);
2227         return ret;
2228     }
2229
2230     /* choose stream as clock source (we favorize video stream if
2231        present) for packet sending */
2232     c->pts_stream_index = 0;
2233     for(i=0;i<c->stream->nb_streams;i++) {
2234         if (c->pts_stream_index == 0 &&
2235             c->stream->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
2236             c->pts_stream_index = i;
2237         }
2238     }
2239
2240     if (c->fmt_in->iformat->read_seek)
2241         av_seek_frame(c->fmt_in, -1, stream_pos, 0);
2242     /* set the start time (needed for maxtime and RTP packet timing) */
2243     c->start_time = cur_time;
2244     c->first_pts = AV_NOPTS_VALUE;
2245     return 0;
2246 }
2247
2248 /* return the server clock (in us) */
2249 static int64_t get_server_clock(HTTPContext *c)
2250 {
2251     /* compute current pts value from system time */
2252     return (cur_time - c->start_time) * 1000;
2253 }
2254
2255 /* return the estimated time at which the current packet must be sent
2256    (in us) */
2257 static int64_t get_packet_send_clock(HTTPContext *c)
2258 {
2259     int bytes_left, bytes_sent, frame_bytes;
2260
2261     frame_bytes = c->cur_frame_bytes;
2262     if (frame_bytes <= 0)
2263         return c->cur_pts;
2264     else {
2265         bytes_left = c->buffer_end - c->buffer_ptr;
2266         bytes_sent = frame_bytes - bytes_left;
2267         return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
2268     }
2269 }
2270
2271
2272 static int http_prepare_data(HTTPContext *c)
2273 {
2274     int i, len, ret;
2275     AVFormatContext *ctx;
2276
2277     av_freep(&c->pb_buffer);
2278     switch(c->state) {
2279     case HTTPSTATE_SEND_DATA_HEADER:
2280         ctx = avformat_alloc_context();
2281         c->fmt_ctx = *ctx;
2282         av_freep(&ctx);
2283         av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0);
2284         c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
2285
2286         for(i=0;i<c->stream->nb_streams;i++) {
2287             AVStream *src;
2288             c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
2289             /* if file or feed, then just take streams from FFStream struct */
2290             if (!c->stream->feed ||
2291                 c->stream->feed == c->stream)
2292                 src = c->stream->streams[i];
2293             else
2294                 src = c->stream->feed->streams[c->stream->feed_streams[i]];
2295
2296             *(c->fmt_ctx.streams[i]) = *src;
2297             c->fmt_ctx.streams[i]->priv_data = 0;
2298             c->fmt_ctx.streams[i]->codec->frame_number = 0; /* XXX: should be done in
2299                                            AVStream, not in codec */
2300         }
2301         /* set output format parameters */
2302         c->fmt_ctx.oformat = c->stream->fmt;
2303         c->fmt_ctx.nb_streams = c->stream->nb_streams;
2304
2305         c->got_key_frame = 0;
2306
2307         /* prepare header and save header data in a stream */
2308         if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
2309             /* XXX: potential leak */
2310             return -1;
2311         }
2312         c->fmt_ctx.pb->seekable = 0;
2313
2314         /*
2315          * HACK to avoid mpeg ps muxer to spit many underflow errors
2316          * Default value from FFmpeg
2317          * Try to set it use configuration option
2318          */
2319         c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
2320
2321         if ((ret = avformat_write_header(&c->fmt_ctx, NULL)) < 0) {
2322             http_log("Error writing output header for stream '%s': %s\n",
2323                      c->stream->filename, av_err2str(ret));
2324             return ret;
2325         }
2326         av_dict_free(&c->fmt_ctx.metadata);
2327
2328         len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
2329         c->buffer_ptr = c->pb_buffer;
2330         c->buffer_end = c->pb_buffer + len;
2331
2332         c->state = HTTPSTATE_SEND_DATA;
2333         c->last_packet_sent = 0;
2334         break;
2335     case HTTPSTATE_SEND_DATA:
2336         /* find a new packet */
2337         /* read a packet from the input stream */
2338         if (c->stream->feed)
2339             ffm_set_write_index(c->fmt_in,
2340                                 c->stream->feed->feed_write_index,
2341                                 c->stream->feed->feed_size);
2342
2343         if (c->stream->max_time &&
2344             c->stream->max_time + c->start_time - cur_time < 0)
2345             /* We have timed out */
2346             c->state = HTTPSTATE_SEND_DATA_TRAILER;
2347         else {
2348             AVPacket pkt;
2349         redo:
2350             ret = av_read_frame(c->fmt_in, &pkt);
2351             if (ret < 0) {
2352                 if (c->stream->feed) {
2353                     /* if coming from feed, it means we reached the end of the
2354                        ffm file, so must wait for more data */
2355                     c->state = HTTPSTATE_WAIT_FEED;
2356                     return 1; /* state changed */
2357                 } else if (ret == AVERROR(EAGAIN)) {
2358                     /* input not ready, come back later */
2359                     return 0;
2360                 } else {
2361                     if (c->stream->loop) {
2362                         avformat_close_input(&c->fmt_in);
2363                         if (open_input_stream(c, "") < 0)
2364                             goto no_loop;
2365                         goto redo;
2366                     } else {
2367                     no_loop:
2368                         /* must send trailer now because eof or error */
2369                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2370                     }
2371                 }
2372             } else {
2373                 int source_index = pkt.stream_index;
2374                 /* update first pts if needed */
2375                 if (c->first_pts == AV_NOPTS_VALUE) {
2376                     c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
2377                     c->start_time = cur_time;
2378                 }
2379                 /* send it to the appropriate stream */
2380                 if (c->stream->feed) {
2381                     /* if coming from a feed, select the right stream */
2382                     if (c->switch_pending) {
2383                         c->switch_pending = 0;
2384                         for(i=0;i<c->stream->nb_streams;i++) {
2385                             if (c->switch_feed_streams[i] == pkt.stream_index)
2386                                 if (pkt.flags & AV_PKT_FLAG_KEY)
2387                                     c->switch_feed_streams[i] = -1;
2388                             if (c->switch_feed_streams[i] >= 0)
2389                                 c->switch_pending = 1;
2390                         }
2391                     }
2392                     for(i=0;i<c->stream->nb_streams;i++) {
2393                         if (c->stream->feed_streams[i] == pkt.stream_index) {
2394                             AVStream *st = c->fmt_in->streams[source_index];
2395                             pkt.stream_index = i;
2396                             if (pkt.flags & AV_PKT_FLAG_KEY &&
2397                                 (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
2398                                  c->stream->nb_streams == 1))
2399                                 c->got_key_frame = 1;
2400                             if (!c->stream->send_on_key || c->got_key_frame)
2401                                 goto send_it;
2402                         }
2403                     }
2404                 } else {
2405                     AVCodecContext *codec;
2406                     AVStream *ist, *ost;
2407                 send_it:
2408                     ist = c->fmt_in->streams[source_index];
2409                     /* specific handling for RTP: we use several
2410                        output stream (one for each RTP
2411                        connection). XXX: need more abstract handling */
2412                     if (c->is_packetized) {
2413                         /* compute send time and duration */
2414                         c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
2415                         c->cur_pts -= c->first_pts;
2416                         c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
2417                         /* find RTP context */
2418                         c->packet_stream_index = pkt.stream_index;
2419                         ctx = c->rtp_ctx[c->packet_stream_index];
2420                         if(!ctx) {
2421                             av_free_packet(&pkt);
2422                             break;
2423                         }
2424                         codec = ctx->streams[0]->codec;
2425                         /* only one stream per RTP connection */
2426                         pkt.stream_index = 0;
2427                     } else {
2428                         ctx = &c->fmt_ctx;
2429                         /* Fudge here */
2430                         codec = ctx->streams[pkt.stream_index]->codec;
2431                     }
2432
2433                     if (c->is_packetized) {
2434                         int max_packet_size;
2435                         if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
2436                             max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
2437                         else
2438                             max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
2439                         ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size);
2440                     } else {
2441                         ret = avio_open_dyn_buf(&ctx->pb);
2442                     }
2443                     if (ret < 0) {
2444                         /* XXX: potential leak */
2445                         return -1;
2446                     }
2447                     ost = ctx->streams[pkt.stream_index];
2448
2449                     ctx->pb->seekable = 0;
2450                     if (pkt.dts != AV_NOPTS_VALUE)
2451                         pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base);
2452                     if (pkt.pts != AV_NOPTS_VALUE)
2453                         pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base);
2454                     pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base);
2455                     if ((ret = av_write_frame(ctx, &pkt)) < 0) {
2456                         http_log("Error writing frame to output for stream '%s': %s\n",
2457                                  c->stream->filename, av_err2str(ret));
2458                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2459                     }
2460
2461                     len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2462                     c->cur_frame_bytes = len;
2463                     c->buffer_ptr = c->pb_buffer;
2464                     c->buffer_end = c->pb_buffer + len;
2465
2466                     codec->frame_number++;
2467                     if (len == 0) {
2468                         av_free_packet(&pkt);
2469                         goto redo;
2470                     }
2471                 }
2472                 av_free_packet(&pkt);
2473             }
2474         }
2475         break;
2476     default:
2477     case HTTPSTATE_SEND_DATA_TRAILER:
2478         /* last packet test ? */
2479         if (c->last_packet_sent || c->is_packetized)
2480             return -1;
2481         ctx = &c->fmt_ctx;
2482         /* prepare header */
2483         if (avio_open_dyn_buf(&ctx->pb) < 0) {
2484             /* XXX: potential leak */
2485             return -1;
2486         }
2487         c->fmt_ctx.pb->seekable = 0;
2488         av_write_trailer(ctx);
2489         len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2490         c->buffer_ptr = c->pb_buffer;
2491         c->buffer_end = c->pb_buffer + len;
2492
2493         c->last_packet_sent = 1;
2494         break;
2495     }
2496     return 0;
2497 }
2498
2499 /* should convert the format at the same time */
2500 /* send data starting at c->buffer_ptr to the output connection
2501    (either UDP or TCP connection) */
2502 static int http_send_data(HTTPContext *c)
2503 {
2504     int len, ret;
2505
2506     for(;;) {
2507         if (c->buffer_ptr >= c->buffer_end) {
2508             ret = http_prepare_data(c);
2509             if (ret < 0)
2510                 return -1;
2511             else if (ret != 0)
2512                 /* state change requested */
2513                 break;
2514         } else {
2515             if (c->is_packetized) {
2516                 /* RTP data output */
2517                 len = c->buffer_end - c->buffer_ptr;
2518                 if (len < 4) {
2519                     /* fail safe - should never happen */
2520                 fail1:
2521                     c->buffer_ptr = c->buffer_end;
2522                     return 0;
2523                 }
2524                 len = (c->buffer_ptr[0] << 24) |
2525                     (c->buffer_ptr[1] << 16) |
2526                     (c->buffer_ptr[2] << 8) |
2527                     (c->buffer_ptr[3]);
2528                 if (len > (c->buffer_end - c->buffer_ptr))
2529                     goto fail1;
2530                 if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
2531                     /* nothing to send yet: we can wait */
2532                     return 0;
2533                 }
2534
2535                 c->data_count += len;
2536                 update_datarate(&c->datarate, c->data_count);
2537                 if (c->stream)
2538                     c->stream->bytes_served += len;
2539
2540                 if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
2541                     /* RTP packets are sent inside the RTSP TCP connection */
2542                     AVIOContext *pb;
2543                     int interleaved_index, size;
2544                     uint8_t header[4];
2545                     HTTPContext *rtsp_c;
2546
2547                     rtsp_c = c->rtsp_c;
2548                     /* if no RTSP connection left, error */
2549                     if (!rtsp_c)
2550                         return -1;
2551                     /* if already sending something, then wait. */
2552                     if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
2553                         break;
2554                     if (avio_open_dyn_buf(&pb) < 0)
2555                         goto fail1;
2556                     interleaved_index = c->packet_stream_index * 2;
2557                     /* RTCP packets are sent at odd indexes */
2558                     if (c->buffer_ptr[1] == 200)
2559                         interleaved_index++;
2560                     /* write RTSP TCP header */
2561                     header[0] = '$';
2562                     header[1] = interleaved_index;
2563                     header[2] = len >> 8;
2564                     header[3] = len;
2565                     avio_write(pb, header, 4);
2566                     /* write RTP packet data */
2567                     c->buffer_ptr += 4;
2568                     avio_write(pb, c->buffer_ptr, len);
2569                     size = avio_close_dyn_buf(pb, &c->packet_buffer);
2570                     /* prepare asynchronous TCP sending */
2571                     rtsp_c->packet_buffer_ptr = c->packet_buffer;
2572                     rtsp_c->packet_buffer_end = c->packet_buffer + size;
2573                     c->buffer_ptr += len;
2574
2575                     /* send everything we can NOW */
2576                     len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
2577                                 rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
2578                     if (len > 0)
2579                         rtsp_c->packet_buffer_ptr += len;
2580                     if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
2581                         /* if we could not send all the data, we will
2582                            send it later, so a new state is needed to
2583                            "lock" the RTSP TCP connection */
2584                         rtsp_c->state = RTSPSTATE_SEND_PACKET;
2585                         break;
2586                     } else
2587                         /* all data has been sent */
2588                         av_freep(&c->packet_buffer);
2589                 } else {
2590                     /* send RTP packet directly in UDP */
2591                     c->buffer_ptr += 4;
2592                     ffurl_write(c->rtp_handles[c->packet_stream_index],
2593                                 c->buffer_ptr, len);
2594                     c->buffer_ptr += len;
2595                     /* here we continue as we can send several packets per 10 ms slot */
2596                 }
2597             } else {
2598                 /* TCP data output */
2599                 len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
2600                 if (len < 0) {
2601                     if (ff_neterrno() != AVERROR(EAGAIN) &&
2602                         ff_neterrno() != AVERROR(EINTR))
2603                         /* error : close connection */
2604                         return -1;
2605                     else
2606                         return 0;
2607                 } else
2608                     c->buffer_ptr += len;
2609
2610                 c->data_count += len;
2611                 update_datarate(&c->datarate, c->data_count);
2612                 if (c->stream)
2613                     c->stream->bytes_served += len;
2614                 break;
2615             }
2616         }
2617     } /* for(;;) */
2618     return 0;
2619 }
2620
2621 static int http_start_receive_data(HTTPContext *c)
2622 {
2623     int fd;
2624     int ret;
2625
2626     if (c->stream->feed_opened) {
2627         http_log("Stream feed '%s' was not opened\n", c->stream->feed_filename);
2628         return AVERROR(EINVAL);
2629     }
2630
2631     /* Don't permit writing to this one */
2632     if (c->stream->readonly) {
2633         http_log("Cannot write to read-only file '%s'\n", c->stream->feed_filename);
2634         return AVERROR(EINVAL);
2635     }
2636
2637     /* open feed */
2638     fd = open(c->stream->feed_filename, O_RDWR);
2639     if (fd < 0) {
2640         ret = AVERROR(errno);
2641         http_log("Could not open feed file '%s': %s\n",
2642                  c->stream->feed_filename, strerror(errno));
2643         return ret;
2644     }
2645     c->feed_fd = fd;
2646
2647     if (c->stream->truncate) {
2648         /* truncate feed file */
2649         ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
2650         http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
2651         if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
2652             ret = AVERROR(errno);
2653             http_log("Error truncating feed file '%s': %s\n",
2654                      c->stream->feed_filename, strerror(errno));
2655             return ret;
2656         }
2657     } else {
2658         ret = ffm_read_write_index(fd);
2659         if (ret < 0) {
2660             http_log("Error reading write index from feed file '%s': %s\n",
2661                      c->stream->feed_filename, strerror(errno));
2662             return ret;
2663         } else {
2664             c->stream->feed_write_index = ret;
2665         }
2666     }
2667
2668     c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
2669     c->stream->feed_size = lseek(fd, 0, SEEK_END);
2670     lseek(fd, 0, SEEK_SET);
2671
2672     /* init buffer input */
2673     c->buffer_ptr = c->buffer;
2674     c->buffer_end = c->buffer + FFM_PACKET_SIZE;
2675     c->stream->feed_opened = 1;
2676     c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
2677     return 0;
2678 }
2679
2680 static int http_receive_data(HTTPContext *c)
2681 {
2682     HTTPContext *c1;
2683     int len, loop_run = 0;
2684
2685     while (c->chunked_encoding && !c->chunk_size &&
2686            c->buffer_end > c->buffer_ptr) {
2687         /* read chunk header, if present */
2688         len = recv(c->fd, c->buffer_ptr, 1, 0);
2689
2690         if (len < 0) {
2691             if (ff_neterrno() != AVERROR(EAGAIN) &&
2692                 ff_neterrno() != AVERROR(EINTR))
2693                 /* error : close connection */
2694                 goto fail;
2695             return 0;
2696         } else if (len == 0) {
2697             /* end of connection : close it */
2698             goto fail;
2699         } else if (c->buffer_ptr - c->buffer >= 2 &&
2700                    !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
2701             c->chunk_size = strtol(c->buffer, 0, 16);
2702             if (c->chunk_size == 0) // end of stream
2703                 goto fail;
2704             c->buffer_ptr = c->buffer;
2705             break;
2706         } else if (++loop_run > 10) {
2707             /* no chunk header, abort */
2708             goto fail;
2709         } else {
2710             c->buffer_ptr++;
2711         }
2712     }
2713
2714     if (c->buffer_end > c->buffer_ptr) {
2715         len = recv(c->fd, c->buffer_ptr,
2716                    FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
2717         if (len < 0) {
2718             if (ff_neterrno() != AVERROR(EAGAIN) &&
2719                 ff_neterrno() != AVERROR(EINTR))
2720                 /* error : close connection */
2721                 goto fail;
2722         } else if (len == 0)
2723             /* end of connection : close it */
2724             goto fail;
2725         else {
2726             c->chunk_size -= len;
2727             c->buffer_ptr += len;
2728             c->data_count += len;
2729             update_datarate(&c->datarate, c->data_count);
2730         }
2731     }
2732
2733     if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
2734         if (c->buffer[0] != 'f' ||
2735             c->buffer[1] != 'm') {
2736             http_log("Feed stream has become desynchronized -- disconnecting\n");
2737             goto fail;
2738         }
2739     }
2740
2741     if (c->buffer_ptr >= c->buffer_end) {
2742         FFStream *feed = c->stream;
2743         /* a packet has been received : write it in the store, except
2744            if header */
2745         if (c->data_count > FFM_PACKET_SIZE) {
2746             /* XXX: use llseek or url_seek */
2747             lseek(c->feed_fd, feed->feed_write_index, SEEK_SET);
2748             if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
2749                 http_log("Error writing to feed file: %s\n", strerror(errno));
2750                 goto fail;
2751             }
2752
2753             feed->feed_write_index += FFM_PACKET_SIZE;
2754             /* update file size */
2755             if (feed->feed_write_index > c->stream->feed_size)
2756                 feed->feed_size = feed->feed_write_index;
2757
2758             /* handle wrap around if max file size reached */
2759             if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size)
2760                 feed->feed_write_index = FFM_PACKET_SIZE;
2761
2762             /* write index */
2763             if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
2764                 http_log("Error writing index to feed file: %s\n", strerror(errno));
2765                 goto fail;
2766             }
2767
2768             /* wake up any waiting connections */
2769             for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2770                 if (c1->state == HTTPSTATE_WAIT_FEED &&
2771                     c1->stream->feed == c->stream->feed)
2772                     c1->state = HTTPSTATE_SEND_DATA;
2773             }
2774         } else {
2775             /* We have a header in our hands that contains useful data */
2776             AVFormatContext *s = avformat_alloc_context();
2777             AVIOContext *pb;
2778             AVInputFormat *fmt_in;
2779             int i;
2780
2781             if (!s)
2782                 goto fail;
2783
2784             /* use feed output format name to find corresponding input format */
2785             fmt_in = av_find_input_format(feed->fmt->name);
2786             if (!fmt_in)
2787                 goto fail;
2788
2789             pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
2790                                     0, NULL, NULL, NULL, NULL);
2791             pb->seekable = 0;
2792
2793             s->pb = pb;
2794             if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) {
2795                 av_free(pb);
2796                 goto fail;
2797             }
2798
2799             /* Now we have the actual streams */
2800             if (s->nb_streams != feed->nb_streams) {
2801                 avformat_close_input(&s);
2802                 av_free(pb);
2803                 http_log("Feed '%s' stream number does not match registered feed\n",
2804                          c->stream->feed_filename);
2805                 goto fail;
2806             }
2807
2808             for (i = 0; i < s->nb_streams; i++) {
2809                 AVStream *fst = feed->streams[i];
2810                 AVStream *st = s->streams[i];
2811                 avcodec_copy_context(fst->codec, st->codec);
2812             }
2813
2814             avformat_close_input(&s);
2815             av_free(pb);
2816         }
2817         c->buffer_ptr = c->buffer;
2818     }
2819
2820     return 0;
2821  fail:
2822     c->stream->feed_opened = 0;
2823     close(c->feed_fd);
2824     /* wake up any waiting connections to stop waiting for feed */
2825     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2826         if (c1->state == HTTPSTATE_WAIT_FEED &&
2827             c1->stream->feed == c->stream->feed)
2828             c1->state = HTTPSTATE_SEND_DATA_TRAILER;
2829     }
2830     return -1;
2831 }
2832
2833 /********************************************************************/
2834 /* RTSP handling */
2835
2836 static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
2837 {
2838     const char *str;
2839     time_t ti;
2840     struct tm *tm;
2841     char buf2[32];
2842
2843     switch(error_number) {
2844     case RTSP_STATUS_OK:
2845         str = "OK";
2846         break;
2847     case RTSP_STATUS_METHOD:
2848         str = "Method Not Allowed";
2849         break;
2850     case RTSP_STATUS_BANDWIDTH:
2851         str = "Not Enough Bandwidth";
2852         break;
2853     case RTSP_STATUS_SESSION:
2854         str = "Session Not Found";
2855         break;
2856     case RTSP_STATUS_STATE:
2857         str = "Method Not Valid in This State";
2858         break;
2859     case RTSP_STATUS_AGGREGATE:
2860         str = "Aggregate operation not allowed";
2861         break;
2862     case RTSP_STATUS_ONLY_AGGREGATE:
2863         str = "Only aggregate operation allowed";
2864         break;
2865     case RTSP_STATUS_TRANSPORT:
2866         str = "Unsupported transport";
2867         break;
2868     case RTSP_STATUS_INTERNAL:
2869         str = "Internal Server Error";
2870         break;
2871     case RTSP_STATUS_SERVICE:
2872         str = "Service Unavailable";
2873         break;
2874     case RTSP_STATUS_VERSION:
2875         str = "RTSP Version not supported";
2876         break;
2877     default:
2878         str = "Unknown Error";
2879         break;
2880     }
2881
2882     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
2883     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
2884
2885     /* output GMT time */
2886     ti = time(NULL);
2887     tm = gmtime(&ti);
2888     strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
2889     avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
2890 }
2891
2892 static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
2893 {
2894     rtsp_reply_header(c, error_number);
2895     avio_printf(c->pb, "\r\n");
2896 }
2897
2898 static int rtsp_parse_request(HTTPContext *c)
2899 {
2900     const char *p, *p1, *p2;
2901     char cmd[32];
2902     char url[1024];
2903     char protocol[32];
2904     char line[1024];
2905     int len;
2906     RTSPMessageHeader header1 = { 0 }, *header = &header1;
2907
2908     c->buffer_ptr[0] = '\0';
2909     p = c->buffer;
2910
2911     get_word(cmd, sizeof(cmd), &p);
2912     get_word(url, sizeof(url), &p);
2913     get_word(protocol, sizeof(protocol), &p);
2914
2915     av_strlcpy(c->method, cmd, sizeof(c->method));
2916     av_strlcpy(c->url, url, sizeof(c->url));
2917     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
2918
2919     if (avio_open_dyn_buf(&c->pb) < 0) {
2920         /* XXX: cannot do more */
2921         c->pb = NULL; /* safety */
2922         return -1;
2923     }
2924
2925     /* check version name */
2926     if (strcmp(protocol, "RTSP/1.0") != 0) {
2927         rtsp_reply_error(c, RTSP_STATUS_VERSION);
2928         goto the_end;
2929     }
2930
2931     /* parse each header line */
2932     /* skip to next line */
2933     while (*p != '\n' && *p != '\0')
2934         p++;
2935     if (*p == '\n')
2936         p++;
2937     while (*p != '\0') {
2938         p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
2939         if (!p1)
2940             break;
2941         p2 = p1;
2942         if (p2 > p && p2[-1] == '\r')
2943             p2--;
2944         /* skip empty line */
2945         if (p2 == p)
2946             break;
2947         len = p2 - p;
2948         if (len > sizeof(line) - 1)
2949             len = sizeof(line) - 1;
2950         memcpy(line, p, len);
2951         line[len] = '\0';
2952         ff_rtsp_parse_line(header, line, NULL, NULL);
2953         p = p1 + 1;
2954     }
2955
2956     /* handle sequence number */
2957     c->seq = header->seq;
2958
2959     if (!strcmp(cmd, "DESCRIBE"))
2960         rtsp_cmd_describe(c, url);
2961     else if (!strcmp(cmd, "OPTIONS"))
2962         rtsp_cmd_options(c, url);
2963     else if (!strcmp(cmd, "SETUP"))
2964         rtsp_cmd_setup(c, url, header);
2965     else if (!strcmp(cmd, "PLAY"))
2966         rtsp_cmd_play(c, url, header);
2967     else if (!strcmp(cmd, "PAUSE"))
2968         rtsp_cmd_pause(c, url, header);
2969     else if (!strcmp(cmd, "TEARDOWN"))
2970         rtsp_cmd_teardown(c, url, header);
2971     else
2972         rtsp_reply_error(c, RTSP_STATUS_METHOD);
2973
2974  the_end:
2975     len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
2976     c->pb = NULL; /* safety */
2977     if (len < 0) {
2978         /* XXX: cannot do more */
2979         return -1;
2980     }
2981     c->buffer_ptr = c->pb_buffer;
2982     c->buffer_end = c->pb_buffer + len;
2983     c->state = RTSPSTATE_SEND_REPLY;
2984     return 0;
2985 }
2986
2987 static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
2988                                    struct in_addr my_ip)
2989 {
2990     AVFormatContext *avc;
2991     AVStream *avs = NULL;
2992     AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
2993     AVDictionaryEntry *entry = av_dict_get(stream->metadata, "title", NULL, 0);
2994     int i;
2995
2996     avc =  avformat_alloc_context();
2997     if (avc == NULL || !rtp_format) {
2998         return -1;
2999     }
3000     avc->oformat = rtp_format;
3001     av_dict_set(&avc->metadata, "title",
3002                 entry ? entry->value : "No Title", 0);
3003     avc->nb_streams = stream->nb_streams;
3004     if (stream->is_multicast) {
3005         snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
3006                  inet_ntoa(stream->multicast_ip),
3007                  stream->multicast_port, stream->multicast_ttl);
3008     } else {
3009         snprintf(avc->filename, 1024, "rtp://0.0.0.0");
3010     }
3011
3012     if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) ||
3013         !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams))))
3014         goto sdp_done;
3015     if (avc->nb_streams >= INT_MAX/sizeof(*avs) ||
3016         !(avs = av_malloc(avc->nb_streams * sizeof(*avs))))
3017         goto sdp_done;
3018
3019     for(i = 0; i < stream->nb_streams; i++) {
3020         avc->streams[i] = &avs[i];
3021         avc->streams[i]->codec = stream->streams[i]->codec;
3022     }
3023     *pbuffer = av_mallocz(2048);
3024     av_sdp_create(&avc, 1, *pbuffer, 2048);
3025
3026  sdp_done:
3027     av_free(avc->streams);
3028     av_dict_free(&avc->metadata);
3029     av_free(avc);
3030     av_free(avs);
3031
3032     return strlen(*pbuffer);
3033 }
3034
3035 static void rtsp_cmd_options(HTTPContext *c, const char *url)
3036 {
3037 //    rtsp_reply_header(c, RTSP_STATUS_OK);
3038     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
3039     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
3040     avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
3041     avio_printf(c->pb, "\r\n");
3042 }
3043
3044 static void rtsp_cmd_describe(HTTPContext *c, const char *url)
3045 {
3046     FFStream *stream;
3047     char path1[1024];
3048     const char *path;
3049     uint8_t *content;
3050     int content_length;
3051     socklen_t len;
3052     struct sockaddr_in my_addr;
3053
3054     /* find which url is asked */
3055     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3056     path = path1;
3057     if (*path == '/')
3058         path++;
3059
3060     for(stream = first_stream; stream != NULL; stream = stream->next) {
3061         if (!stream->is_feed &&
3062             stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
3063             !strcmp(path, stream->filename)) {
3064             goto found;
3065         }
3066     }
3067     /* no stream found */
3068     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
3069     return;
3070
3071  found:
3072     /* prepare the media description in sdp format */
3073
3074     /* get the host IP */
3075     len = sizeof(my_addr);
3076     getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
3077     content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);
3078     if (content_length < 0) {
3079         rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
3080         return;
3081     }
3082     rtsp_reply_header(c, RTSP_STATUS_OK);
3083     avio_printf(c->pb, "Content-Base: %s/\r\n", url);
3084     avio_printf(c->pb, "Content-Type: application/sdp\r\n");
3085     avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
3086     avio_printf(c->pb, "\r\n");
3087     avio_write(c->pb, content, content_length);
3088     av_free(content);
3089 }
3090
3091 static HTTPContext *find_rtp_session(const char *session_id)
3092 {
3093     HTTPContext *c;
3094
3095     if (session_id[0] == '\0')
3096         return NULL;
3097
3098     for(c = first_http_ctx; c != NULL; c = c->next) {
3099         if (!strcmp(c->session_id, session_id))
3100             return c;
3101     }
3102     return NULL;
3103 }
3104
3105 static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
3106 {
3107     RTSPTransportField *th;
3108     int i;
3109
3110     for(i=0;i<h->nb_transports;i++) {
3111         th = &h->transports[i];
3112         if (th->lower_transport == lower_transport)
3113             return th;
3114     }
3115     return NULL;
3116 }
3117
3118 static void rtsp_cmd_setup(HTTPContext *c, const char *url,
3119                            RTSPMessageHeader *h)
3120 {
3121     FFStream *stream;
3122     int stream_index, rtp_port, rtcp_port;
3123     char buf[1024];
3124     char path1[1024];
3125     const char *path;
3126     HTTPContext *rtp_c;
3127     RTSPTransportField *th;
3128     struct sockaddr_in dest_addr;
3129     RTSPActionServerSetup setup;
3130
3131     /* find which url is asked */
3132     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3133     path = path1;
3134     if (*path == '/')
3135         path++;
3136
3137     /* now check each stream */
3138     for(stream = first_stream; stream != NULL; stream = stream->next) {
3139         if (!stream->is_feed &&
3140             stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
3141             /* accept aggregate filenames only if single stream */
3142             if (!strcmp(path, stream->filename)) {
3143                 if (stream->nb_streams != 1) {
3144                     rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);
3145                     return;
3146                 }
3147                 stream_index = 0;
3148                 goto found;
3149             }
3150
3151             for(stream_index = 0; stream_index < stream->nb_streams;
3152                 stream_index++) {
3153                 snprintf(buf, sizeof(buf), "%s/streamid=%d",
3154                          stream->filename, stream_index);
3155                 if (!strcmp(path, buf))
3156                     goto found;
3157             }
3158         }
3159     }
3160     /* no stream found */
3161     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
3162     return;
3163  found:
3164
3165     /* generate session id if needed */
3166     if (h->session_id[0] == '\0') {
3167         unsigned random0 = av_lfg_get(&random_state);
3168         unsigned random1 = av_lfg_get(&random_state);
3169         snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
3170                  random0, random1);
3171     }
3172
3173     /* find rtp session, and create it if none found */
3174     rtp_c = find_rtp_session(h->session_id);
3175     if (!rtp_c) {
3176         /* always prefer UDP */
3177         th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
3178         if (!th) {
3179             th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
3180             if (!th) {
3181                 rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3182                 return;
3183             }
3184         }
3185
3186         rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
3187                                    th->lower_transport);
3188         if (!rtp_c) {
3189             rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
3190             return;
3191         }
3192
3193         /* open input stream */
3194         if (open_input_stream(rtp_c, "") < 0) {
3195             rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
3196             return;
3197         }
3198     }
3199
3200     /* test if stream is OK (test needed because several SETUP needs
3201        to be done for a given file) */
3202     if (rtp_c->stream != stream) {
3203         rtsp_reply_error(c, RTSP_STATUS_SERVICE);
3204         return;
3205     }
3206
3207     /* test if stream is already set up */
3208     if (rtp_c->rtp_ctx[stream_index]) {
3209         rtsp_reply_error(c, RTSP_STATUS_STATE);
3210         return;
3211     }
3212
3213     /* check transport */
3214     th = find_transport(h, rtp_c->rtp_protocol);
3215     if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
3216                 th->client_port_min <= 0)) {
3217         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3218         return;
3219     }
3220
3221     /* setup default options */
3222     setup.transport_option[0] = '\0';
3223     dest_addr = rtp_c->from_addr;
3224     dest_addr.sin_port = htons(th->client_port_min);
3225
3226     /* setup stream */
3227     if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
3228         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3229         return;
3230     }
3231
3232     /* now everything is OK, so we can send the connection parameters */
3233     rtsp_reply_header(c, RTSP_STATUS_OK);
3234     /* session ID */
3235     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3236
3237     switch(rtp_c->rtp_protocol) {
3238     case RTSP_LOWER_TRANSPORT_UDP:
3239         rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
3240         rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
3241         avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
3242                     "client_port=%d-%d;server_port=%d-%d",
3243                     th->client_port_min, th->client_port_max,
3244                     rtp_port, rtcp_port);
3245         break;
3246     case RTSP_LOWER_TRANSPORT_TCP:
3247         avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
3248                     stream_index * 2, stream_index * 2 + 1);
3249         break;
3250     default:
3251         break;
3252     }
3253     if (setup.transport_option[0] != '\0')
3254         avio_printf(c->pb, ";%s", setup.transport_option);
3255     avio_printf(c->pb, "\r\n");
3256
3257
3258     avio_printf(c->pb, "\r\n");
3259 }
3260
3261
3262 /* find an rtp connection by using the session ID. Check consistency
3263    with filename */
3264 static HTTPContext *find_rtp_session_with_url(const char *url,
3265                                               const char *session_id)
3266 {
3267     HTTPContext *rtp_c;
3268     char path1[1024];
3269     const char *path;
3270     char buf[1024];
3271     int s, len;
3272
3273     rtp_c = find_rtp_session(session_id);
3274     if (!rtp_c)
3275         return NULL;
3276
3277     /* find which url is asked */
3278     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3279     path = path1;
3280     if (*path == '/')
3281         path++;
3282     if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
3283     for(s=0; s<rtp_c->stream->nb_streams; ++s) {
3284       snprintf(buf, sizeof(buf), "%s/streamid=%d",
3285         rtp_c->stream->filename, s);
3286       if(!strncmp(path, buf, sizeof(buf))) {
3287     // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
3288         return rtp_c;
3289       }
3290     }
3291     len = strlen(path);
3292     if (len > 0 && path[len - 1] == '/' &&
3293         !strncmp(path, rtp_c->stream->filename, len - 1))
3294         return rtp_c;
3295     return NULL;
3296 }
3297
3298 static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3299 {
3300     HTTPContext *rtp_c;
3301
3302     rtp_c = find_rtp_session_with_url(url, h->session_id);
3303     if (!rtp_c) {
3304         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3305         return;
3306     }
3307
3308     if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3309         rtp_c->state != HTTPSTATE_WAIT_FEED &&
3310         rtp_c->state != HTTPSTATE_READY) {
3311         rtsp_reply_error(c, RTSP_STATUS_STATE);
3312         return;
3313     }
3314
3315     rtp_c->state = HTTPSTATE_SEND_DATA;
3316
3317     /* now everything is OK, so we can send the connection parameters */
3318     rtsp_reply_header(c, RTSP_STATUS_OK);
3319     /* session ID */
3320     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3321     avio_printf(c->pb, "\r\n");
3322 }
3323
3324 static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3325 {
3326     HTTPContext *rtp_c;
3327
3328     rtp_c = find_rtp_session_with_url(url, h->session_id);
3329     if (!rtp_c) {
3330         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3331         return;
3332     }
3333
3334     if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3335         rtp_c->state != HTTPSTATE_WAIT_FEED) {
3336         rtsp_reply_error(c, RTSP_STATUS_STATE);
3337         return;
3338     }
3339
3340     rtp_c->state = HTTPSTATE_READY;
3341     rtp_c->first_pts = AV_NOPTS_VALUE;
3342     /* now everything is OK, so we can send the connection parameters */
3343     rtsp_reply_header(c, RTSP_STATUS_OK);
3344     /* session ID */
3345     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3346     avio_printf(c->pb, "\r\n");
3347 }
3348
3349 static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3350 {
3351     HTTPContext *rtp_c;
3352
3353     rtp_c = find_rtp_session_with_url(url, h->session_id);
3354     if (!rtp_c) {
3355         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3356         return;
3357     }
3358
3359     /* now everything is OK, so we can send the connection parameters */
3360     rtsp_reply_header(c, RTSP_STATUS_OK);
3361     /* session ID */
3362     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3363     avio_printf(c->pb, "\r\n");
3364
3365     /* abort the session */
3366     close_connection(rtp_c);
3367 }
3368
3369
3370 /********************************************************************/
3371 /* RTP handling */
3372
3373 static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
3374                                        FFStream *stream, const char *session_id,
3375                                        enum RTSPLowerTransport rtp_protocol)
3376 {
3377     HTTPContext *c = NULL;
3378     const char *proto_str;
3379
3380     /* XXX: should output a warning page when coming
3381        close to the connection limit */
3382     if (nb_connections >= nb_max_connections)
3383         goto fail;
3384
3385     /* add a new connection */
3386     c = av_mallocz(sizeof(HTTPContext));
3387     if (!c)
3388         goto fail;
3389
3390     c->fd = -1;
3391     c->poll_entry = NULL;
3392     c->from_addr = *from_addr;
3393     c->buffer_size = IOBUFFER_INIT_SIZE;
3394     c->buffer = av_malloc(c->buffer_size);
3395     if (!c->buffer)
3396         goto fail;
3397     nb_connections++;
3398     c->stream = stream;
3399     av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
3400     c->state = HTTPSTATE_READY;
3401     c->is_packetized = 1;
3402     c->rtp_protocol = rtp_protocol;
3403
3404     /* protocol is shown in statistics */
3405     switch(c->rtp_protocol) {
3406     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3407         proto_str = "MCAST";
3408         break;
3409     case RTSP_LOWER_TRANSPORT_UDP:
3410         proto_str = "UDP";
3411         break;
3412     case RTSP_LOWER_TRANSPORT_TCP:
3413         proto_str = "TCP";
3414         break;
3415     default:
3416         proto_str = "???";
3417         break;
3418     }
3419     av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
3420     av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
3421
3422     current_bandwidth += stream->bandwidth;
3423
3424     c->next = first_http_ctx;
3425     first_http_ctx = c;
3426     return c;
3427
3428  fail:
3429     if (c) {
3430         av_free(c->buffer);
3431         av_free(c);
3432     }
3433     return NULL;
3434 }
3435
3436 /* add a new RTP stream in an RTP connection (used in RTSP SETUP
3437    command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
3438    used. */
3439 static int rtp_new_av_stream(HTTPContext *c,
3440                              int stream_index, struct sockaddr_in *dest_addr,
3441                              HTTPContext *rtsp_c)
3442 {
3443     AVFormatContext *ctx;
3444     AVStream *st;
3445     char *ipaddr;
3446     URLContext *h = NULL;
3447     uint8_t *dummy_buf;
3448     int max_packet_size;
3449
3450     /* now we can open the relevant output stream */
3451     ctx = avformat_alloc_context();
3452     if (!ctx)
3453         return -1;
3454     ctx->oformat = av_guess_format("rtp", NULL, NULL);
3455
3456     st = av_mallocz(sizeof(AVStream));
3457     if (!st)
3458         goto fail;
3459     ctx->nb_streams = 1;
3460     ctx->streams = av_mallocz(sizeof(AVStream *) * ctx->nb_streams);
3461     if (!ctx->streams)
3462       goto fail;
3463     ctx->streams[0] = st;
3464
3465     if (!c->stream->feed ||
3466         c->stream->feed == c->stream)
3467         memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
3468     else
3469         memcpy(st,
3470                c->stream->feed->streams[c->stream->feed_streams[stream_index]],
3471                sizeof(AVStream));
3472     st->priv_data = NULL;
3473
3474     /* build destination RTP address */
3475     ipaddr = inet_ntoa(dest_addr->sin_addr);
3476
3477     switch(c->rtp_protocol) {
3478     case RTSP_LOWER_TRANSPORT_UDP:
3479     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3480         /* RTP/UDP case */
3481
3482         /* XXX: also pass as parameter to function ? */
3483         if (c->stream->is_multicast) {
3484             int ttl;
3485             ttl = c->stream->multicast_ttl;
3486             if (!ttl)
3487                 ttl = 16;
3488             snprintf(ctx->filename, sizeof(ctx->filename),
3489                      "rtp://%s:%d?multicast=1&ttl=%d",
3490                      ipaddr, ntohs(dest_addr->sin_port), ttl);
3491         } else {
3492             snprintf(ctx->filename, sizeof(ctx->filename),
3493                      "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
3494         }
3495
3496         if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
3497             goto fail;
3498         c->rtp_handles[stream_index] = h;
3499         max_packet_size = h->max_packet_size;
3500         break;
3501     case RTSP_LOWER_TRANSPORT_TCP:
3502         /* RTP/TCP case */
3503         c->rtsp_c = rtsp_c;
3504         max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
3505         break;
3506     default:
3507         goto fail;
3508     }
3509
3510     http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
3511              ipaddr, ntohs(dest_addr->sin_port),
3512              c->stream->filename, stream_index, c->protocol);
3513
3514     /* normally, no packets should be output here, but the packet size may
3515      * be checked */
3516     if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
3517         /* XXX: close stream */
3518         goto fail;
3519     }
3520     if (avformat_write_header(ctx, NULL) < 0) {
3521     fail:
3522         if (h)
3523             ffurl_close(h);
3524         av_free(ctx);
3525         return -1;
3526     }
3527     avio_close_dyn_buf(ctx->pb, &dummy_buf);
3528     av_free(dummy_buf);
3529
3530     c->rtp_ctx[stream_index] = ctx;
3531     return 0;
3532 }
3533
3534 /********************************************************************/
3535 /* ffserver initialization */
3536
3537 static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
3538 {
3539     AVStream *fst;
3540
3541     if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
3542         return NULL;
3543
3544     fst = av_mallocz(sizeof(AVStream));
3545     if (!fst)
3546         return NULL;
3547     if (copy) {
3548         fst->codec = avcodec_alloc_context3(NULL);
3549         memcpy(fst->codec, codec, sizeof(AVCodecContext));
3550         if (codec->extradata_size) {
3551             fst->codec->extradata = av_mallocz(codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
3552             memcpy(fst->codec->extradata, codec->extradata,
3553                 codec->extradata_size);
3554         }
3555     } else {
3556         /* live streams must use the actual feed's codec since it may be
3557          * updated later to carry extradata needed by the streams.
3558          */
3559         fst->codec = codec;
3560     }
3561     fst->priv_data = av_mallocz(sizeof(FeedData));
3562     fst->index = stream->nb_streams;
3563     avpriv_set_pts_info(fst, 33, 1, 90000);
3564     fst->sample_aspect_ratio = codec->sample_aspect_ratio;
3565     stream->streams[stream->nb_streams++] = fst;
3566     return fst;
3567 }
3568
3569 /* return the stream number in the feed */
3570 static int add_av_stream(FFStream *feed, AVStream *st)
3571 {
3572     AVStream *fst;
3573     AVCodecContext *av, *av1;
3574     int i;
3575
3576     av = st->codec;
3577     for(i=0;i<feed->nb_streams;i++) {
3578         st = feed->streams[i];
3579         av1 = st->codec;
3580         if (av1->codec_id == av->codec_id &&
3581             av1->codec_type == av->codec_type &&
3582             av1->bit_rate == av->bit_rate) {
3583
3584             switch(av->codec_type) {
3585             case AVMEDIA_TYPE_AUDIO:
3586                 if (av1->channels == av->channels &&
3587                     av1->sample_rate == av->sample_rate)
3588                     return i;
3589                 break;
3590             case AVMEDIA_TYPE_VIDEO:
3591                 if (av1->width == av->width &&
3592                     av1->height == av->height &&
3593                     av1->time_base.den == av->time_base.den &&
3594                     av1->time_base.num == av->time_base.num &&
3595                     av1->gop_size == av->gop_size)
3596                     return i;
3597                 break;
3598             default:
3599                 abort();
3600             }
3601         }
3602     }
3603
3604     fst = add_av_stream1(feed, av, 0);
3605     if (!fst)
3606         return -1;
3607     return feed->nb_streams - 1;
3608 }
3609
3610 static void remove_stream(FFStream *stream)
3611 {
3612     FFStream **ps;
3613     ps = &first_stream;
3614     while (*ps != NULL) {
3615         if (*ps == stream)
3616             *ps = (*ps)->next;
3617         else
3618             ps = &(*ps)->next;
3619     }
3620 }
3621
3622 /* specific mpeg4 handling : we extract the raw parameters */
3623 static void extract_mpeg4_header(AVFormatContext *infile)
3624 {
3625     int mpeg4_count, i, size;
3626     AVPacket pkt;
3627     AVStream *st;
3628     const uint8_t *p;
3629
3630     infile->flags |= AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE;
3631
3632     mpeg4_count = 0;
3633     for(i=0;i<infile->nb_streams;i++) {
3634         st = infile->streams[i];
3635         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3636             st->codec->extradata_size == 0) {
3637             mpeg4_count++;
3638         }
3639     }
3640     if (!mpeg4_count)
3641         return;
3642
3643     printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
3644     while (mpeg4_count > 0) {
3645         if (av_read_frame(infile, &pkt) < 0)
3646             break;
3647         st = infile->streams[pkt.stream_index];
3648         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3649             st->codec->extradata_size == 0) {
3650             av_freep(&st->codec->extradata);
3651             /* fill extradata with the header */
3652             /* XXX: we make hard suppositions here ! */
3653             p = pkt.data;
3654             while (p < pkt.data + pkt.size - 4) {
3655                 /* stop when vop header is found */
3656                 if (p[0] == 0x00 && p[1] == 0x00 &&
3657                     p[2] == 0x01 && p[3] == 0xb6) {
3658                     size = p - pkt.data;
3659                     //                    av_hex_dump_log(infile, AV_LOG_DEBUG, pkt.data, size);
3660                     st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
3661                     st->codec->extradata_size = size;
3662                     memcpy(st->codec->extradata, pkt.data, size);
3663                     break;
3664                 }
3665                 p++;
3666             }
3667             mpeg4_count--;
3668         }
3669         av_free_packet(&pkt);
3670     }
3671 }
3672
3673 /* compute the needed AVStream for each file */
3674 static void build_file_streams(void)
3675 {
3676     FFStream *stream, *stream_next;
3677     int i, ret;
3678
3679     /* gather all streams */
3680     for(stream = first_stream; stream != NULL; stream = stream_next) {
3681         AVFormatContext *infile = NULL;