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