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