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