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