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