ffserver: do not ignore setsockopt 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     send(fd, buffer, len, 0);
815 }
816
817
818 static void new_connection(int server_fd, int is_rtsp)
819 {
820     struct sockaddr_in from_addr;
821     socklen_t len;
822     int fd;
823     HTTPContext *c = NULL;
824
825     len = sizeof(from_addr);
826     fd = accept(server_fd, (struct sockaddr *)&from_addr,
827                 &len);
828     if (fd < 0) {
829         http_log("error during accept %s\n", strerror(errno));
830         return;
831     }
832     if (ff_socket_nonblock(fd, 1) < 0)
833         av_log(NULL, AV_LOG_WARNING, "ff_socket_nonblock failed\n");
834
835     if (nb_connections >= nb_max_connections) {
836         http_send_too_busy_reply(fd);
837         goto fail;
838     }
839
840     /* add a new connection */
841     c = av_mallocz(sizeof(HTTPContext));
842     if (!c)
843         goto fail;
844
845     c->fd = fd;
846     c->poll_entry = NULL;
847     c->from_addr = from_addr;
848     c->buffer_size = IOBUFFER_INIT_SIZE;
849     c->buffer = av_malloc(c->buffer_size);
850     if (!c->buffer)
851         goto fail;
852
853     c->next = first_http_ctx;
854     first_http_ctx = c;
855     nb_connections++;
856
857     start_wait_request(c, is_rtsp);
858
859     return;
860
861  fail:
862     if (c) {
863         av_free(c->buffer);
864         av_free(c);
865     }
866     closesocket(fd);
867 }
868
869 static void close_connection(HTTPContext *c)
870 {
871     HTTPContext **cp, *c1;
872     int i, nb_streams;
873     AVFormatContext *ctx;
874     URLContext *h;
875     AVStream *st;
876
877     /* remove connection from list */
878     cp = &first_http_ctx;
879     while ((*cp) != NULL) {
880         c1 = *cp;
881         if (c1 == c)
882             *cp = c->next;
883         else
884             cp = &c1->next;
885     }
886
887     /* remove references, if any (XXX: do it faster) */
888     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
889         if (c1->rtsp_c == c)
890             c1->rtsp_c = NULL;
891     }
892
893     /* remove connection associated resources */
894     if (c->fd >= 0)
895         closesocket(c->fd);
896     if (c->fmt_in) {
897         /* close each frame parser */
898         for(i=0;i<c->fmt_in->nb_streams;i++) {
899             st = c->fmt_in->streams[i];
900             if (st->codec->codec)
901                 avcodec_close(st->codec);
902         }
903         avformat_close_input(&c->fmt_in);
904     }
905
906     /* free RTP output streams if any */
907     nb_streams = 0;
908     if (c->stream)
909         nb_streams = c->stream->nb_streams;
910
911     for(i=0;i<nb_streams;i++) {
912         ctx = c->rtp_ctx[i];
913         if (ctx) {
914             av_write_trailer(ctx);
915             av_dict_free(&ctx->metadata);
916             av_free(ctx->streams[0]);
917             av_free(ctx);
918         }
919         h = c->rtp_handles[i];
920         if (h)
921             ffurl_close(h);
922     }
923
924     ctx = &c->fmt_ctx;
925
926     if (!c->last_packet_sent && c->state == HTTPSTATE_SEND_DATA_TRAILER) {
927         if (ctx->oformat) {
928             /* prepare header */
929             if (avio_open_dyn_buf(&ctx->pb) >= 0) {
930                 av_write_trailer(ctx);
931                 av_freep(&c->pb_buffer);
932                 avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
933             }
934         }
935     }
936
937     for(i=0; i<ctx->nb_streams; i++)
938         av_free(ctx->streams[i]);
939     av_freep(&ctx->streams);
940     av_freep(&ctx->priv_data);
941
942     if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
943         current_bandwidth -= c->stream->bandwidth;
944
945     /* signal that there is no feed if we are the feeder socket */
946     if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
947         c->stream->feed_opened = 0;
948         close(c->feed_fd);
949     }
950
951     av_freep(&c->pb_buffer);
952     av_freep(&c->packet_buffer);
953     av_free(c->buffer);
954     av_free(c);
955     nb_connections--;
956 }
957
958 static int handle_connection(HTTPContext *c)
959 {
960     int len, ret;
961
962     switch(c->state) {
963     case HTTPSTATE_WAIT_REQUEST:
964     case RTSPSTATE_WAIT_REQUEST:
965         /* timeout ? */
966         if ((c->timeout - cur_time) < 0)
967             return -1;
968         if (c->poll_entry->revents & (POLLERR | POLLHUP))
969             return -1;
970
971         /* no need to read if no events */
972         if (!(c->poll_entry->revents & POLLIN))
973             return 0;
974         /* read the data */
975     read_loop:
976         len = recv(c->fd, c->buffer_ptr, 1, 0);
977         if (len < 0) {
978             if (ff_neterrno() != AVERROR(EAGAIN) &&
979                 ff_neterrno() != AVERROR(EINTR))
980                 return -1;
981         } else if (len == 0) {
982             return -1;
983         } else {
984             /* search for end of request. */
985             uint8_t *ptr;
986             c->buffer_ptr += len;
987             ptr = c->buffer_ptr;
988             if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
989                 (ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
990                 /* request found : parse it and reply */
991                 if (c->state == HTTPSTATE_WAIT_REQUEST) {
992                     ret = http_parse_request(c);
993                 } else {
994                     ret = rtsp_parse_request(c);
995                 }
996                 if (ret < 0)
997                     return -1;
998             } else if (ptr >= c->buffer_end) {
999                 /* request too long: cannot do anything */
1000                 return -1;
1001             } else goto read_loop;
1002         }
1003         break;
1004
1005     case HTTPSTATE_SEND_HEADER:
1006         if (c->poll_entry->revents & (POLLERR | POLLHUP))
1007             return -1;
1008
1009         /* no need to write if no events */
1010         if (!(c->poll_entry->revents & POLLOUT))
1011             return 0;
1012         len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
1013         if (len < 0) {
1014             if (ff_neterrno() != AVERROR(EAGAIN) &&
1015                 ff_neterrno() != AVERROR(EINTR)) {
1016                 goto close_connection;
1017             }
1018         } else {
1019             c->buffer_ptr += len;
1020             if (c->stream)
1021                 c->stream->bytes_served += len;
1022             c->data_count += len;
1023             if (c->buffer_ptr >= c->buffer_end) {
1024                 av_freep(&c->pb_buffer);
1025                 /* if error, exit */
1026                 if (c->http_error)
1027                     return -1;
1028                 /* all the buffer was sent : synchronize to the incoming
1029                  * stream */
1030                 c->state = HTTPSTATE_SEND_DATA_HEADER;
1031                 c->buffer_ptr = c->buffer_end = c->buffer;
1032             }
1033         }
1034         break;
1035
1036     case HTTPSTATE_SEND_DATA:
1037     case HTTPSTATE_SEND_DATA_HEADER:
1038     case HTTPSTATE_SEND_DATA_TRAILER:
1039         /* for packetized output, we consider we can always write (the
1040            input streams set the speed). It may be better to verify
1041            that we do not rely too much on the kernel queues */
1042         if (!c->is_packetized) {
1043             if (c->poll_entry->revents & (POLLERR | POLLHUP))
1044                 return -1;
1045
1046             /* no need to read if no events */
1047             if (!(c->poll_entry->revents & POLLOUT))
1048                 return 0;
1049         }
1050         if (http_send_data(c) < 0)
1051             return -1;
1052         /* close connection if trailer sent */
1053         if (c->state == HTTPSTATE_SEND_DATA_TRAILER)
1054             return -1;
1055         break;
1056     case HTTPSTATE_RECEIVE_DATA:
1057         /* no need to read if no events */
1058         if (c->poll_entry->revents & (POLLERR | POLLHUP))
1059             return -1;
1060         if (!(c->poll_entry->revents & POLLIN))
1061             return 0;
1062         if (http_receive_data(c) < 0)
1063             return -1;
1064         break;
1065     case HTTPSTATE_WAIT_FEED:
1066         /* no need to read if no events */
1067         if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP))
1068             return -1;
1069
1070         /* nothing to do, we'll be waken up by incoming feed packets */
1071         break;
1072
1073     case RTSPSTATE_SEND_REPLY:
1074         if (c->poll_entry->revents & (POLLERR | POLLHUP))
1075             goto close_connection;
1076         /* no need to write if no events */
1077         if (!(c->poll_entry->revents & POLLOUT))
1078             return 0;
1079         len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
1080         if (len < 0) {
1081             if (ff_neterrno() != AVERROR(EAGAIN) &&
1082                 ff_neterrno() != AVERROR(EINTR)) {
1083                 goto close_connection;
1084             }
1085         } else {
1086             c->buffer_ptr += len;
1087             c->data_count += len;
1088             if (c->buffer_ptr >= c->buffer_end) {
1089                 /* all the buffer was sent : wait for a new request */
1090                 av_freep(&c->pb_buffer);
1091                 start_wait_request(c, 1);
1092             }
1093         }
1094         break;
1095     case RTSPSTATE_SEND_PACKET:
1096         if (c->poll_entry->revents & (POLLERR | POLLHUP)) {
1097             av_freep(&c->packet_buffer);
1098             return -1;
1099         }
1100         /* no need to write if no events */
1101         if (!(c->poll_entry->revents & POLLOUT))
1102             return 0;
1103         len = send(c->fd, c->packet_buffer_ptr,
1104                     c->packet_buffer_end - c->packet_buffer_ptr, 0);
1105         if (len < 0) {
1106             if (ff_neterrno() != AVERROR(EAGAIN) &&
1107                 ff_neterrno() != AVERROR(EINTR)) {
1108                 /* error : close connection */
1109                 av_freep(&c->packet_buffer);
1110                 return -1;
1111             }
1112         } else {
1113             c->packet_buffer_ptr += len;
1114             if (c->packet_buffer_ptr >= c->packet_buffer_end) {
1115                 /* all the buffer was sent : wait for a new request */
1116                 av_freep(&c->packet_buffer);
1117                 c->state = RTSPSTATE_WAIT_REQUEST;
1118             }
1119         }
1120         break;
1121     case HTTPSTATE_READY:
1122         /* nothing to do */
1123         break;
1124     default:
1125         return -1;
1126     }
1127     return 0;
1128
1129 close_connection:
1130     av_freep(&c->pb_buffer);
1131     return -1;
1132 }
1133
1134 static int extract_rates(char *rates, int ratelen, const char *request)
1135 {
1136     const char *p;
1137
1138     for (p = request; *p && *p != '\r' && *p != '\n'; ) {
1139         if (av_strncasecmp(p, "Pragma:", 7) == 0) {
1140             const char *q = p + 7;
1141
1142             while (*q && *q != '\n' && av_isspace(*q))
1143                 q++;
1144
1145             if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) {
1146                 int stream_no;
1147                 int rate_no;
1148
1149                 q += 20;
1150
1151                 memset(rates, 0xff, ratelen);
1152
1153                 while (1) {
1154                     while (*q && *q != '\n' && *q != ':')
1155                         q++;
1156
1157                     if (sscanf(q, ":%d:%d", &stream_no, &rate_no) != 2)
1158                         break;
1159
1160                     stream_no--;
1161                     if (stream_no < ratelen && stream_no >= 0)
1162                         rates[stream_no] = rate_no;
1163
1164                     while (*q && *q != '\n' && !av_isspace(*q))
1165                         q++;
1166                 }
1167
1168                 return 1;
1169             }
1170         }
1171         p = strchr(p, '\n');
1172         if (!p)
1173             break;
1174
1175         p++;
1176     }
1177
1178     return 0;
1179 }
1180
1181 static int find_stream_in_feed(FFStream *feed, AVCodecContext *codec, int bit_rate)
1182 {
1183     int i;
1184     int best_bitrate = 100000000;
1185     int best = -1;
1186
1187     for (i = 0; i < feed->nb_streams; i++) {
1188         AVCodecContext *feed_codec = feed->streams[i]->codec;
1189
1190         if (feed_codec->codec_id != codec->codec_id ||
1191             feed_codec->sample_rate != codec->sample_rate ||
1192             feed_codec->width != codec->width ||
1193             feed_codec->height != codec->height)
1194             continue;
1195
1196         /* Potential stream */
1197
1198         /* We want the fastest stream less than bit_rate, or the slowest
1199          * faster than bit_rate
1200          */
1201
1202         if (feed_codec->bit_rate <= bit_rate) {
1203             if (best_bitrate > bit_rate || feed_codec->bit_rate > best_bitrate) {
1204                 best_bitrate = feed_codec->bit_rate;
1205                 best = i;
1206             }
1207         } else {
1208             if (feed_codec->bit_rate < best_bitrate) {
1209                 best_bitrate = feed_codec->bit_rate;
1210                 best = i;
1211             }
1212         }
1213     }
1214
1215     return best;
1216 }
1217
1218 static int modify_current_stream(HTTPContext *c, char *rates)
1219 {
1220     int i;
1221     FFStream *req = c->stream;
1222     int action_required = 0;
1223
1224     /* Not much we can do for a feed */
1225     if (!req->feed)
1226         return 0;
1227
1228     for (i = 0; i < req->nb_streams; i++) {
1229         AVCodecContext *codec = req->streams[i]->codec;
1230
1231         switch(rates[i]) {
1232             case 0:
1233                 c->switch_feed_streams[i] = req->feed_streams[i];
1234                 break;
1235             case 1:
1236                 c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 2);
1237                 break;
1238             case 2:
1239                 /* Wants off or slow */
1240                 c->switch_feed_streams[i] = find_stream_in_feed(req->feed, codec, codec->bit_rate / 4);
1241 #ifdef WANTS_OFF
1242                 /* This doesn't work well when it turns off the only stream! */
1243                 c->switch_feed_streams[i] = -2;
1244                 c->feed_streams[i] = -2;
1245 #endif
1246                 break;
1247         }
1248
1249         if (c->switch_feed_streams[i] >= 0 && c->switch_feed_streams[i] != c->feed_streams[i])
1250             action_required = 1;
1251     }
1252
1253     return action_required;
1254 }
1255
1256 /* XXX: factorize in utils.c ? */
1257 /* XXX: take care with different space meaning */
1258 static void skip_spaces(const char **pp)
1259 {
1260     const char *p;
1261     p = *pp;
1262     while (*p == ' ' || *p == '\t')
1263         p++;
1264     *pp = p;
1265 }
1266
1267 static void get_word(char *buf, int buf_size, const char **pp)
1268 {
1269     const char *p;
1270     char *q;
1271
1272     p = *pp;
1273     skip_spaces(&p);
1274     q = buf;
1275     while (!av_isspace(*p) && *p != '\0') {
1276         if ((q - buf) < buf_size - 1)
1277             *q++ = *p;
1278         p++;
1279     }
1280     if (buf_size > 0)
1281         *q = '\0';
1282     *pp = p;
1283 }
1284
1285 static void get_arg(char *buf, int buf_size, const char **pp)
1286 {
1287     const char *p;
1288     char *q;
1289     int quote;
1290
1291     p = *pp;
1292     while (av_isspace(*p)) p++;
1293     q = buf;
1294     quote = 0;
1295     if (*p == '\"' || *p == '\'')
1296         quote = *p++;
1297     for(;;) {
1298         if (quote) {
1299             if (*p == quote)
1300                 break;
1301         } else {
1302             if (av_isspace(*p))
1303                 break;
1304         }
1305         if (*p == '\0')
1306             break;
1307         if ((q - buf) < buf_size - 1)
1308             *q++ = *p;
1309         p++;
1310     }
1311     *q = '\0';
1312     if (quote && *p == quote)
1313         p++;
1314     *pp = p;
1315 }
1316
1317 static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
1318                          const char *p, const char *filename, int line_num)
1319 {
1320     char arg[1024];
1321     IPAddressACL acl;
1322     int errors = 0;
1323
1324     get_arg(arg, sizeof(arg), &p);
1325     if (av_strcasecmp(arg, "allow") == 0)
1326         acl.action = IP_ALLOW;
1327     else if (av_strcasecmp(arg, "deny") == 0)
1328         acl.action = IP_DENY;
1329     else {
1330         fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
1331                 filename, line_num, arg);
1332         errors++;
1333     }
1334
1335     get_arg(arg, sizeof(arg), &p);
1336
1337     if (resolve_host(&acl.first, arg) != 0) {
1338         fprintf(stderr, "%s:%d: ACL refers to invalid host or IP address '%s'\n",
1339                 filename, line_num, arg);
1340         errors++;
1341     } else
1342         acl.last = acl.first;
1343
1344     get_arg(arg, sizeof(arg), &p);
1345
1346     if (arg[0]) {
1347         if (resolve_host(&acl.last, arg) != 0) {
1348             fprintf(stderr, "%s:%d: ACL refers to invalid host or IP address '%s'\n",
1349                     filename, line_num, arg);
1350             errors++;
1351         }
1352     }
1353
1354     if (!errors) {
1355         IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
1356         IPAddressACL **naclp = 0;
1357
1358         acl.next = 0;
1359         *nacl = acl;
1360
1361         if (stream)
1362             naclp = &stream->acl;
1363         else if (feed)
1364             naclp = &feed->acl;
1365         else if (ext_acl)
1366             naclp = &ext_acl;
1367         else {
1368             fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
1369                     filename, line_num);
1370             errors++;
1371         }
1372
1373         if (naclp) {
1374             while (*naclp)
1375                 naclp = &(*naclp)->next;
1376
1377             *naclp = nacl;
1378         } else
1379             av_free(nacl);
1380     }
1381 }
1382
1383
1384 static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
1385 {
1386     FILE* f;
1387     char line[1024];
1388     char  cmd[1024];
1389     IPAddressACL *acl = NULL;
1390     int line_num = 0;
1391     const char *p;
1392
1393     f = fopen(stream->dynamic_acl, "r");
1394     if (!f) {
1395         perror(stream->dynamic_acl);
1396         return NULL;
1397     }
1398
1399     acl = av_mallocz(sizeof(IPAddressACL));
1400
1401     /* Build ACL */
1402     for(;;) {
1403         if (fgets(line, sizeof(line), f) == NULL)
1404             break;
1405         line_num++;
1406         p = line;
1407         while (av_isspace(*p))
1408             p++;
1409         if (*p == '\0' || *p == '#')
1410             continue;
1411         get_arg(cmd, sizeof(cmd), &p);
1412
1413         if (!av_strcasecmp(cmd, "ACL"))
1414             parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
1415     }
1416     fclose(f);
1417     return acl;
1418 }
1419
1420
1421 static void free_acl_list(IPAddressACL *in_acl)
1422 {
1423     IPAddressACL *pacl,*pacl2;
1424
1425     pacl = in_acl;
1426     while(pacl) {
1427         pacl2 = pacl;
1428         pacl = pacl->next;
1429         av_freep(pacl2);
1430     }
1431 }
1432
1433 static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)
1434 {
1435     enum IPAddressAction last_action = IP_DENY;
1436     IPAddressACL *acl;
1437     struct in_addr *src = &c->from_addr.sin_addr;
1438     unsigned long src_addr = src->s_addr;
1439
1440     for (acl = in_acl; acl; acl = acl->next) {
1441         if (src_addr >= acl->first.s_addr && src_addr <= acl->last.s_addr)
1442             return (acl->action == IP_ALLOW) ? 1 : 0;
1443         last_action = acl->action;
1444     }
1445
1446     /* Nothing matched, so return not the last action */
1447     return (last_action == IP_DENY) ? 1 : 0;
1448 }
1449
1450 static int validate_acl(FFStream *stream, HTTPContext *c)
1451 {
1452     int ret = 0;
1453     IPAddressACL *acl;
1454
1455
1456     /* if stream->acl is null validate_acl_list will return 1 */
1457     ret = validate_acl_list(stream->acl, c);
1458
1459     if (stream->dynamic_acl[0]) {
1460         acl = parse_dynamic_acl(stream, c);
1461
1462         ret = validate_acl_list(acl, c);
1463
1464         free_acl_list(acl);
1465     }
1466
1467     return ret;
1468 }
1469
1470 /* compute the real filename of a file by matching it without its
1471    extensions to all the stream's filenames */
1472 static void compute_real_filename(char *filename, int max_size)
1473 {
1474     char file1[1024];
1475     char file2[1024];
1476     char *p;
1477     FFStream *stream;
1478
1479     /* compute filename by matching without the file extensions */
1480     av_strlcpy(file1, filename, sizeof(file1));
1481     p = strrchr(file1, '.');
1482     if (p)
1483         *p = '\0';
1484     for(stream = first_stream; stream != NULL; stream = stream->next) {
1485         av_strlcpy(file2, stream->filename, sizeof(file2));
1486         p = strrchr(file2, '.');
1487         if (p)
1488             *p = '\0';
1489         if (!strcmp(file1, file2)) {
1490             av_strlcpy(filename, stream->filename, max_size);
1491             break;
1492         }
1493     }
1494 }
1495
1496 enum RedirType {
1497     REDIR_NONE,
1498     REDIR_ASX,
1499     REDIR_RAM,
1500     REDIR_ASF,
1501     REDIR_RTSP,
1502     REDIR_SDP,
1503 };
1504
1505 /* parse HTTP request and prepare header */
1506 static int http_parse_request(HTTPContext *c)
1507 {
1508     const char *p;
1509     char *p1;
1510     enum RedirType redir_type;
1511     char cmd[32];
1512     char info[1024], filename[1024];
1513     char url[1024], *q;
1514     char protocol[32];
1515     char msg[1024];
1516     const char *mime_type;
1517     FFStream *stream;
1518     int i;
1519     char ratebuf[32];
1520     const char *useragent = 0;
1521
1522     p = c->buffer;
1523     get_word(cmd, sizeof(cmd), &p);
1524     av_strlcpy(c->method, cmd, sizeof(c->method));
1525
1526     if (!strcmp(cmd, "GET"))
1527         c->post = 0;
1528     else if (!strcmp(cmd, "POST"))
1529         c->post = 1;
1530     else
1531         return -1;
1532
1533     get_word(url, sizeof(url), &p);
1534     av_strlcpy(c->url, url, sizeof(c->url));
1535
1536     get_word(protocol, sizeof(protocol), (const char **)&p);
1537     if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
1538         return -1;
1539
1540     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
1541
1542     if (ffserver_debug)
1543         http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
1544
1545     /* find the filename and the optional info string in the request */
1546     p1 = strchr(url, '?');
1547     if (p1) {
1548         av_strlcpy(info, p1, sizeof(info));
1549         *p1 = '\0';
1550     } else
1551         info[0] = '\0';
1552
1553     av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
1554
1555     for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1556         if (av_strncasecmp(p, "User-Agent:", 11) == 0) {
1557             useragent = p + 11;
1558             if (*useragent && *useragent != '\n' && av_isspace(*useragent))
1559                 useragent++;
1560             break;
1561         }
1562         p = strchr(p, '\n');
1563         if (!p)
1564             break;
1565
1566         p++;
1567     }
1568
1569     redir_type = REDIR_NONE;
1570     if (av_match_ext(filename, "asx")) {
1571         redir_type = REDIR_ASX;
1572         filename[strlen(filename)-1] = 'f';
1573     } else if (av_match_ext(filename, "asf") &&
1574         (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) {
1575         /* if this isn't WMP or lookalike, return the redirector file */
1576         redir_type = REDIR_ASF;
1577     } else if (av_match_ext(filename, "rpm,ram")) {
1578         redir_type = REDIR_RAM;
1579         strcpy(filename + strlen(filename)-2, "m");
1580     } else if (av_match_ext(filename, "rtsp")) {
1581         redir_type = REDIR_RTSP;
1582         compute_real_filename(filename, sizeof(filename) - 1);
1583     } else if (av_match_ext(filename, "sdp")) {
1584         redir_type = REDIR_SDP;
1585         compute_real_filename(filename, sizeof(filename) - 1);
1586     }
1587
1588     // "redirect" / request to index.html
1589     if (!strlen(filename))
1590         av_strlcpy(filename, "index.html", sizeof(filename) - 1);
1591
1592     stream = first_stream;
1593     while (stream != NULL) {
1594         if (!strcmp(stream->filename, filename) && validate_acl(stream, c))
1595             break;
1596         stream = stream->next;
1597     }
1598     if (stream == NULL) {
1599         snprintf(msg, sizeof(msg), "File '%s' not found", url);
1600         http_log("File '%s' not found\n", url);
1601         goto send_error;
1602     }
1603
1604     c->stream = stream;
1605     memcpy(c->feed_streams, stream->feed_streams, sizeof(c->feed_streams));
1606     memset(c->switch_feed_streams, -1, sizeof(c->switch_feed_streams));
1607
1608     if (stream->stream_type == STREAM_TYPE_REDIRECT) {
1609         c->http_error = 301;
1610         q = c->buffer;
1611         snprintf(q, c->buffer_size,
1612                       "HTTP/1.0 301 Moved\r\n"
1613                       "Location: %s\r\n"
1614                       "Content-type: text/html\r\n"
1615                       "\r\n"
1616                       "<html><head><title>Moved</title></head><body>\r\n"
1617                       "You should be <a href=\"%s\">redirected</a>.\r\n"
1618                       "</body></html>\r\n", stream->feed_filename, stream->feed_filename);
1619         q += strlen(q);
1620         /* prepare output buffer */
1621         c->buffer_ptr = c->buffer;
1622         c->buffer_end = q;
1623         c->state = HTTPSTATE_SEND_HEADER;
1624         return 0;
1625     }
1626
1627     /* If this is WMP, get the rate information */
1628     if (extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
1629         if (modify_current_stream(c, ratebuf)) {
1630             for (i = 0; i < FF_ARRAY_ELEMS(c->feed_streams); i++) {
1631                 if (c->switch_feed_streams[i] >= 0)
1632                     c->switch_feed_streams[i] = -1;
1633             }
1634         }
1635     }
1636
1637     if (c->post == 0 && stream->stream_type == STREAM_TYPE_LIVE)
1638         current_bandwidth += stream->bandwidth;
1639
1640     /* If already streaming this feed, do not let start another feeder. */
1641     if (stream->feed_opened) {
1642         snprintf(msg, sizeof(msg), "This feed is already being received.");
1643         http_log("Feed '%s' already being received\n", stream->feed_filename);
1644         goto send_error;
1645     }
1646
1647     if (c->post == 0 && max_bandwidth < current_bandwidth) {
1648         c->http_error = 503;
1649         q = c->buffer;
1650         snprintf(q, c->buffer_size,
1651                       "HTTP/1.0 503 Server too busy\r\n"
1652                       "Content-type: text/html\r\n"
1653                       "\r\n"
1654                       "<html><head><title>Too busy</title></head><body>\r\n"
1655                       "<p>The server is too busy to serve your request at this time.</p>\r\n"
1656                       "<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, "
1657                       "and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n"
1658                       "</body></html>\r\n", current_bandwidth, max_bandwidth);
1659         q += strlen(q);
1660         /* prepare output buffer */
1661         c->buffer_ptr = c->buffer;
1662         c->buffer_end = q;
1663         c->state = HTTPSTATE_SEND_HEADER;
1664         return 0;
1665     }
1666
1667     if (redir_type != REDIR_NONE) {
1668         const char *hostinfo = 0;
1669
1670         for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1671             if (av_strncasecmp(p, "Host:", 5) == 0) {
1672                 hostinfo = p + 5;
1673                 break;
1674             }
1675             p = strchr(p, '\n');
1676             if (!p)
1677                 break;
1678
1679             p++;
1680         }
1681
1682         if (hostinfo) {
1683             char *eoh;
1684             char hostbuf[260];
1685
1686             while (av_isspace(*hostinfo))
1687                 hostinfo++;
1688
1689             eoh = strchr(hostinfo, '\n');
1690             if (eoh) {
1691                 if (eoh[-1] == '\r')
1692                     eoh--;
1693
1694                 if (eoh - hostinfo < sizeof(hostbuf) - 1) {
1695                     memcpy(hostbuf, hostinfo, eoh - hostinfo);
1696                     hostbuf[eoh - hostinfo] = 0;
1697
1698                     c->http_error = 200;
1699                     q = c->buffer;
1700                     switch(redir_type) {
1701                     case REDIR_ASX:
1702                         snprintf(q, c->buffer_size,
1703                                       "HTTP/1.0 200 ASX Follows\r\n"
1704                                       "Content-type: video/x-ms-asf\r\n"
1705                                       "\r\n"
1706                                       "<ASX Version=\"3\">\r\n"
1707                                       //"<!-- Autogenerated by ffserver -->\r\n"
1708                                       "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n"
1709                                       "</ASX>\r\n", hostbuf, filename, info);
1710                         q += strlen(q);
1711                         break;
1712                     case REDIR_RAM:
1713                         snprintf(q, c->buffer_size,
1714                                       "HTTP/1.0 200 RAM Follows\r\n"
1715                                       "Content-type: audio/x-pn-realaudio\r\n"
1716                                       "\r\n"
1717                                       "# Autogenerated by ffserver\r\n"
1718                                       "http://%s/%s%s\r\n", hostbuf, filename, info);
1719                         q += strlen(q);
1720                         break;
1721                     case REDIR_ASF:
1722                         snprintf(q, c->buffer_size,
1723                                       "HTTP/1.0 200 ASF Redirect follows\r\n"
1724                                       "Content-type: video/x-ms-asf\r\n"
1725                                       "\r\n"
1726                                       "[Reference]\r\n"
1727                                       "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info);
1728                         q += strlen(q);
1729                         break;
1730                     case REDIR_RTSP:
1731                         {
1732                             char hostname[256], *p;
1733                             /* extract only hostname */
1734                             av_strlcpy(hostname, hostbuf, sizeof(hostname));
1735                             p = strrchr(hostname, ':');
1736                             if (p)
1737                                 *p = '\0';
1738                             snprintf(q, c->buffer_size,
1739                                           "HTTP/1.0 200 RTSP Redirect follows\r\n"
1740                                           /* XXX: incorrect MIME type ? */
1741                                           "Content-type: application/x-rtsp\r\n"
1742                                           "\r\n"
1743                                           "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename);
1744                             q += strlen(q);
1745                         }
1746                         break;
1747                     case REDIR_SDP:
1748                         {
1749                             uint8_t *sdp_data;
1750                             int sdp_data_size;
1751                             socklen_t len;
1752                             struct sockaddr_in my_addr;
1753
1754                             snprintf(q, c->buffer_size,
1755                                           "HTTP/1.0 200 OK\r\n"
1756                                           "Content-type: application/sdp\r\n"
1757                                           "\r\n");
1758                             q += strlen(q);
1759
1760                             len = sizeof(my_addr);
1761                             getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
1762
1763                             /* XXX: should use a dynamic buffer */
1764                             sdp_data_size = prepare_sdp_description(stream,
1765                                                                     &sdp_data,
1766                                                                     my_addr.sin_addr);
1767                             if (sdp_data_size > 0) {
1768                                 memcpy(q, sdp_data, sdp_data_size);
1769                                 q += sdp_data_size;
1770                                 *q = '\0';
1771                                 av_free(sdp_data);
1772                             }
1773                         }
1774                         break;
1775                     default:
1776                         abort();
1777                         break;
1778                     }
1779
1780                     /* prepare output buffer */
1781                     c->buffer_ptr = c->buffer;
1782                     c->buffer_end = q;
1783                     c->state = HTTPSTATE_SEND_HEADER;
1784                     return 0;
1785                 }
1786             }
1787         }
1788
1789         snprintf(msg, sizeof(msg), "ASX/RAM file not handled");
1790         goto send_error;
1791     }
1792
1793     stream->conns_served++;
1794
1795     /* XXX: add there authenticate and IP match */
1796
1797     if (c->post) {
1798         /* if post, it means a feed is being sent */
1799         if (!stream->is_feed) {
1800             /* However it might be a status report from WMP! Let us log the
1801              * data as it might come handy one day. */
1802             const char *logline = 0;
1803             int client_id = 0;
1804
1805             for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
1806                 if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) {
1807                     logline = p;
1808                     break;
1809                 }
1810                 if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0)
1811                     client_id = strtol(p + 18, 0, 10);
1812                 p = strchr(p, '\n');
1813                 if (!p)
1814                     break;
1815
1816                 p++;
1817             }
1818
1819             if (logline) {
1820                 char *eol = strchr(logline, '\n');
1821
1822                 logline += 17;
1823
1824                 if (eol) {
1825                     if (eol[-1] == '\r')
1826                         eol--;
1827                     http_log("%.*s\n", (int) (eol - logline), logline);
1828                     c->suppress_log = 1;
1829                 }
1830             }
1831
1832 #ifdef DEBUG
1833             http_log("\nGot request:\n%s\n", c->buffer);
1834 #endif
1835
1836             if (client_id && extract_rates(ratebuf, sizeof(ratebuf), c->buffer)) {
1837                 HTTPContext *wmpc;
1838
1839                 /* Now we have to find the client_id */
1840                 for (wmpc = first_http_ctx; wmpc; wmpc = wmpc->next) {
1841                     if (wmpc->wmp_client_id == client_id)
1842                         break;
1843                 }
1844
1845                 if (wmpc && modify_current_stream(wmpc, ratebuf))
1846                     wmpc->switch_pending = 1;
1847             }
1848
1849             snprintf(msg, sizeof(msg), "POST command not handled");
1850             c->stream = 0;
1851             goto send_error;
1852         }
1853         if (http_start_receive_data(c) < 0) {
1854             snprintf(msg, sizeof(msg), "could not open feed");
1855             goto send_error;
1856         }
1857         c->http_error = 0;
1858         c->state = HTTPSTATE_RECEIVE_DATA;
1859         return 0;
1860     }
1861
1862 #ifdef DEBUG
1863     if (strcmp(stream->filename + strlen(stream->filename) - 4, ".asf") == 0)
1864         http_log("\nGot request:\n%s\n", c->buffer);
1865 #endif
1866
1867     if (c->stream->stream_type == STREAM_TYPE_STATUS)
1868         goto send_status;
1869
1870     /* open input stream */
1871     if (open_input_stream(c, info) < 0) {
1872         snprintf(msg, sizeof(msg), "Input stream corresponding to '%s' not found", url);
1873         goto send_error;
1874     }
1875
1876     /* prepare HTTP header */
1877     c->buffer[0] = 0;
1878     av_strlcatf(c->buffer, c->buffer_size, "HTTP/1.0 200 OK\r\n");
1879     mime_type = c->stream->fmt->mime_type;
1880     if (!mime_type)
1881         mime_type = "application/x-octet-stream";
1882     av_strlcatf(c->buffer, c->buffer_size, "Pragma: no-cache\r\n");
1883
1884     /* for asf, we need extra headers */
1885     if (!strcmp(c->stream->fmt->name,"asf_stream")) {
1886         /* Need to allocate a client id */
1887
1888         c->wmp_client_id = av_lfg_get(&random_state);
1889
1890         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);
1891     }
1892     av_strlcatf(c->buffer, c->buffer_size, "Content-Type: %s\r\n", mime_type);
1893     av_strlcatf(c->buffer, c->buffer_size, "\r\n");
1894     q = c->buffer + strlen(c->buffer);
1895
1896     /* prepare output buffer */
1897     c->http_error = 0;
1898     c->buffer_ptr = c->buffer;
1899     c->buffer_end = q;
1900     c->state = HTTPSTATE_SEND_HEADER;
1901     return 0;
1902  send_error:
1903     c->http_error = 404;
1904     q = c->buffer;
1905     htmlstrip(msg);
1906     snprintf(q, c->buffer_size,
1907                   "HTTP/1.0 404 Not Found\r\n"
1908                   "Content-type: text/html\r\n"
1909                   "\r\n"
1910                   "<html>\n"
1911                   "<head><title>404 Not Found</title></head>\n"
1912                   "<body>%s</body>\n"
1913                   "</html>\n", msg);
1914     q += strlen(q);
1915     /* prepare output buffer */
1916     c->buffer_ptr = c->buffer;
1917     c->buffer_end = q;
1918     c->state = HTTPSTATE_SEND_HEADER;
1919     return 0;
1920  send_status:
1921     compute_status(c);
1922     c->http_error = 200; /* horrible : we use this value to avoid
1923                             going to the send data state */
1924     c->state = HTTPSTATE_SEND_HEADER;
1925     return 0;
1926 }
1927
1928 static void fmt_bytecount(AVIOContext *pb, int64_t count)
1929 {
1930     static const char suffix[] = " kMGTP";
1931     const char *s;
1932
1933     for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++);
1934
1935     avio_printf(pb, "%"PRId64"%c", count, *s);
1936 }
1937
1938 static void compute_status(HTTPContext *c)
1939 {
1940     HTTPContext *c1;
1941     FFStream *stream;
1942     char *p;
1943     time_t ti;
1944     int i, len;
1945     AVIOContext *pb;
1946
1947     if (avio_open_dyn_buf(&pb) < 0) {
1948         /* XXX: return an error ? */
1949         c->buffer_ptr = c->buffer;
1950         c->buffer_end = c->buffer;
1951         return;
1952     }
1953
1954     avio_printf(pb, "HTTP/1.0 200 OK\r\n");
1955     avio_printf(pb, "Content-type: text/html\r\n");
1956     avio_printf(pb, "Pragma: no-cache\r\n");
1957     avio_printf(pb, "\r\n");
1958
1959     avio_printf(pb, "<html><head><title>%s Status</title>\n", program_name);
1960     if (c->stream->feed_filename[0])
1961         avio_printf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
1962     avio_printf(pb, "</head>\n<body>");
1963     avio_printf(pb, "<h1>%s Status</h1>\n", program_name);
1964     /* format status */
1965     avio_printf(pb, "<h2>Available Streams</h2>\n");
1966     avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
1967     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");
1968     stream = first_stream;
1969     while (stream != NULL) {
1970         char sfilename[1024];
1971         char *eosf;
1972
1973         if (stream->feed != stream) {
1974             av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10);
1975             eosf = sfilename + strlen(sfilename);
1976             if (eosf - sfilename >= 4) {
1977                 if (strcmp(eosf - 4, ".asf") == 0)
1978                     strcpy(eosf - 4, ".asx");
1979                 else if (strcmp(eosf - 3, ".rm") == 0)
1980                     strcpy(eosf - 3, ".ram");
1981                 else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
1982                     /* generate a sample RTSP director if
1983                        unicast. Generate an SDP redirector if
1984                        multicast */
1985                     eosf = strrchr(sfilename, '.');
1986                     if (!eosf)
1987                         eosf = sfilename + strlen(sfilename);
1988                     if (stream->is_multicast)
1989                         strcpy(eosf, ".sdp");
1990                     else
1991                         strcpy(eosf, ".rtsp");
1992                 }
1993             }
1994
1995             avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
1996                          sfilename, stream->filename);
1997             avio_printf(pb, "<td align=right> %d <td align=right> ",
1998                         stream->conns_served);
1999             fmt_bytecount(pb, stream->bytes_served);
2000             switch(stream->stream_type) {
2001             case STREAM_TYPE_LIVE: {
2002                     int audio_bit_rate = 0;
2003                     int video_bit_rate = 0;
2004                     const char *audio_codec_name = "";
2005                     const char *video_codec_name = "";
2006                     const char *audio_codec_name_extra = "";
2007                     const char *video_codec_name_extra = "";
2008
2009                     for(i=0;i<stream->nb_streams;i++) {
2010                         AVStream *st = stream->streams[i];
2011                         AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
2012                         switch(st->codec->codec_type) {
2013                         case AVMEDIA_TYPE_AUDIO:
2014                             audio_bit_rate += st->codec->bit_rate;
2015                             if (codec) {
2016                                 if (*audio_codec_name)
2017                                     audio_codec_name_extra = "...";
2018                                 audio_codec_name = codec->name;
2019                             }
2020                             break;
2021                         case AVMEDIA_TYPE_VIDEO:
2022                             video_bit_rate += st->codec->bit_rate;
2023                             if (codec) {
2024                                 if (*video_codec_name)
2025                                     video_codec_name_extra = "...";
2026                                 video_codec_name = codec->name;
2027                             }
2028                             break;
2029                         case AVMEDIA_TYPE_DATA:
2030                             video_bit_rate += st->codec->bit_rate;
2031                             break;
2032                         default:
2033                             abort();
2034                         }
2035                     }
2036                     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",
2037                                  stream->fmt->name,
2038                                  stream->bandwidth,
2039                                  video_bit_rate / 1000, video_codec_name, video_codec_name_extra,
2040                                  audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra);
2041                     if (stream->feed)
2042                         avio_printf(pb, "<td>%s", stream->feed->filename);
2043                     else
2044                         avio_printf(pb, "<td>%s", stream->feed_filename);
2045                     avio_printf(pb, "\n");
2046                 }
2047                 break;
2048             default:
2049                 avio_printf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
2050                 break;
2051             }
2052         }
2053         stream = stream->next;
2054     }
2055     avio_printf(pb, "</table>\n");
2056
2057     stream = first_stream;
2058     while (stream != NULL) {
2059         if (stream->feed == stream) {
2060             avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
2061             if (stream->pid) {
2062                 avio_printf(pb, "Running as pid %d.\n", stream->pid);
2063
2064 #if defined(linux)
2065                 {
2066                     FILE *pid_stat;
2067                     char ps_cmd[64];
2068
2069                     /* This is somewhat linux specific I guess */
2070                     snprintf(ps_cmd, sizeof(ps_cmd),
2071                              "ps -o \"%%cpu,cputime\" --no-headers %d",
2072                              stream->pid);
2073
2074                     pid_stat = popen(ps_cmd, "r");
2075                     if (pid_stat) {
2076                         char cpuperc[10];
2077                         char cpuused[64];
2078
2079                         if (fscanf(pid_stat, "%9s %63s", cpuperc,
2080                                    cpuused) == 2) {
2081                             avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
2082                                          cpuperc, cpuused);
2083                         }
2084                         fclose(pid_stat);
2085                     }
2086                 }
2087 #endif
2088
2089                 avio_printf(pb, "<p>");
2090             }
2091             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");
2092
2093             for (i = 0; i < stream->nb_streams; i++) {
2094                 AVStream *st = stream->streams[i];
2095                 AVCodec *codec = avcodec_find_encoder(st->codec->codec_id);
2096                 const char *type = "unknown";
2097                 char parameters[64];
2098
2099                 parameters[0] = 0;
2100
2101                 switch(st->codec->codec_type) {
2102                 case AVMEDIA_TYPE_AUDIO:
2103                     type = "audio";
2104                     snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate);
2105                     break;
2106                 case AVMEDIA_TYPE_VIDEO:
2107                     type = "video";
2108                     snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height,
2109                                 st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num);
2110                     break;
2111                 default:
2112                     abort();
2113                 }
2114                 avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n",
2115                         i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters);
2116             }
2117             avio_printf(pb, "</table>\n");
2118
2119         }
2120         stream = stream->next;
2121     }
2122
2123     /* connection status */
2124     avio_printf(pb, "<h2>Connection Status</h2>\n");
2125
2126     avio_printf(pb, "Number of connections: %d / %d<br>\n",
2127                  nb_connections, nb_max_connections);
2128
2129     avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
2130                  current_bandwidth, max_bandwidth);
2131
2132     avio_printf(pb, "<table>\n");
2133     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");
2134     c1 = first_http_ctx;
2135     i = 0;
2136     while (c1 != NULL) {
2137         int bitrate;
2138         int j;
2139
2140         bitrate = 0;
2141         if (c1->stream) {
2142             for (j = 0; j < c1->stream->nb_streams; j++) {
2143                 if (!c1->stream->feed)
2144                     bitrate += c1->stream->streams[j]->codec->bit_rate;
2145                 else if (c1->feed_streams[j] >= 0)
2146                     bitrate += c1->stream->feed->streams[c1->feed_streams[j]]->codec->bit_rate;
2147             }
2148         }
2149
2150         i++;
2151         p = inet_ntoa(c1->from_addr.sin_addr);
2152         avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>",
2153                     i,
2154                     c1->stream ? c1->stream->filename : "",
2155                     c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "",
2156                     p,
2157                     c1->protocol,
2158                     http_state[c1->state]);
2159         fmt_bytecount(pb, bitrate);
2160         avio_printf(pb, "<td align=right>");
2161         fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
2162         avio_printf(pb, "<td align=right>");
2163         fmt_bytecount(pb, c1->data_count);
2164         avio_printf(pb, "\n");
2165         c1 = c1->next;
2166     }
2167     avio_printf(pb, "</table>\n");
2168
2169     /* date */
2170     ti = time(NULL);
2171     p = ctime(&ti);
2172     avio_printf(pb, "<hr size=1 noshade>Generated at %s", p);
2173     avio_printf(pb, "</body>\n</html>\n");
2174
2175     len = avio_close_dyn_buf(pb, &c->pb_buffer);
2176     c->buffer_ptr = c->pb_buffer;
2177     c->buffer_end = c->pb_buffer + len;
2178 }
2179
2180 static int open_input_stream(HTTPContext *c, const char *info)
2181 {
2182     char buf[128];
2183     char input_filename[1024];
2184     AVFormatContext *s = NULL;
2185     int buf_size, i, ret;
2186     int64_t stream_pos;
2187
2188     /* find file name */
2189     if (c->stream->feed) {
2190         strcpy(input_filename, c->stream->feed->feed_filename);
2191         buf_size = FFM_PACKET_SIZE;
2192         /* compute position (absolute time) */
2193         if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
2194             if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0) {
2195                 http_log("Invalid date specification '%s' for stream\n", buf);
2196                 return ret;
2197             }
2198         } else if (av_find_info_tag(buf, sizeof(buf), "buffer", info)) {
2199             int prebuffer = strtol(buf, 0, 10);
2200             stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
2201         } else
2202             stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000;
2203     } else {
2204         strcpy(input_filename, c->stream->feed_filename);
2205         buf_size = 0;
2206         /* compute position (relative time) */
2207         if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
2208             if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0) {
2209                 http_log("Invalid date specification '%s' for stream\n", buf);
2210                 return ret;
2211             }
2212         } else
2213             stream_pos = 0;
2214     }
2215     if (!input_filename[0]) {
2216         http_log("No filename was specified for stream\n");
2217         return AVERROR(EINVAL);
2218     }
2219
2220     /* open stream */
2221     if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) {
2222         http_log("Could not open input '%s': %s\n", input_filename, av_err2str(ret));
2223         return ret;
2224     }
2225
2226     /* set buffer size */
2227     if (buf_size > 0) ffio_set_buf_size(s->pb, buf_size);
2228
2229     s->flags |= AVFMT_FLAG_GENPTS;
2230     c->fmt_in = s;
2231     if (strcmp(s->iformat->name, "ffm") &&
2232         (ret = avformat_find_stream_info(c->fmt_in, NULL)) < 0) {
2233         http_log("Could not find stream info for input '%s'\n", input_filename);
2234         avformat_close_input(&s);
2235         return ret;
2236     }
2237
2238     /* choose stream as clock source (we favor the video stream if
2239      * present) for packet sending */
2240     c->pts_stream_index = 0;
2241     for(i=0;i<c->stream->nb_streams;i++) {
2242         if (c->pts_stream_index == 0 &&
2243             c->stream->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
2244             c->pts_stream_index = i;
2245         }
2246     }
2247
2248     if (c->fmt_in->iformat->read_seek)
2249         av_seek_frame(c->fmt_in, -1, stream_pos, 0);
2250     /* set the start time (needed for maxtime and RTP packet timing) */
2251     c->start_time = cur_time;
2252     c->first_pts = AV_NOPTS_VALUE;
2253     return 0;
2254 }
2255
2256 /* return the server clock (in us) */
2257 static int64_t get_server_clock(HTTPContext *c)
2258 {
2259     /* compute current pts value from system time */
2260     return (cur_time - c->start_time) * 1000;
2261 }
2262
2263 /* return the estimated time at which the current packet must be sent
2264    (in us) */
2265 static int64_t get_packet_send_clock(HTTPContext *c)
2266 {
2267     int bytes_left, bytes_sent, frame_bytes;
2268
2269     frame_bytes = c->cur_frame_bytes;
2270     if (frame_bytes <= 0)
2271         return c->cur_pts;
2272     else {
2273         bytes_left = c->buffer_end - c->buffer_ptr;
2274         bytes_sent = frame_bytes - bytes_left;
2275         return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
2276     }
2277 }
2278
2279
2280 static int http_prepare_data(HTTPContext *c)
2281 {
2282     int i, len, ret;
2283     AVFormatContext *ctx;
2284
2285     av_freep(&c->pb_buffer);
2286     switch(c->state) {
2287     case HTTPSTATE_SEND_DATA_HEADER:
2288         ctx = avformat_alloc_context();
2289         c->fmt_ctx = *ctx;
2290         av_freep(&ctx);
2291         av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0);
2292         c->fmt_ctx.streams = av_mallocz(sizeof(AVStream *) * c->stream->nb_streams);
2293
2294         for(i=0;i<c->stream->nb_streams;i++) {
2295             AVStream *src;
2296             c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
2297             /* if file or feed, then just take streams from FFStream struct */
2298             if (!c->stream->feed ||
2299                 c->stream->feed == c->stream)
2300                 src = c->stream->streams[i];
2301             else
2302                 src = c->stream->feed->streams[c->stream->feed_streams[i]];
2303
2304             *(c->fmt_ctx.streams[i]) = *src;
2305             c->fmt_ctx.streams[i]->priv_data = 0;
2306             /* XXX: should be done in AVStream, not in codec */
2307             c->fmt_ctx.streams[i]->codec->frame_number = 0;
2308         }
2309         /* set output format parameters */
2310         c->fmt_ctx.oformat = c->stream->fmt;
2311         c->fmt_ctx.nb_streams = c->stream->nb_streams;
2312
2313         c->got_key_frame = 0;
2314
2315         /* prepare header and save header data in a stream */
2316         if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
2317             /* XXX: potential leak */
2318             return -1;
2319         }
2320         c->fmt_ctx.pb->seekable = 0;
2321
2322         /*
2323          * HACK to avoid MPEG-PS muxer to spit many underflow errors
2324          * Default value from FFmpeg
2325          * Try to set it using configuration option
2326          */
2327         c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
2328
2329         if ((ret = avformat_write_header(&c->fmt_ctx, NULL)) < 0) {
2330             http_log("Error writing output header for stream '%s': %s\n",
2331                      c->stream->filename, av_err2str(ret));
2332             return ret;
2333         }
2334         av_dict_free(&c->fmt_ctx.metadata);
2335
2336         len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
2337         c->buffer_ptr = c->pb_buffer;
2338         c->buffer_end = c->pb_buffer + len;
2339
2340         c->state = HTTPSTATE_SEND_DATA;
2341         c->last_packet_sent = 0;
2342         break;
2343     case HTTPSTATE_SEND_DATA:
2344         /* find a new packet */
2345         /* read a packet from the input stream */
2346         if (c->stream->feed)
2347             ffm_set_write_index(c->fmt_in,
2348                                 c->stream->feed->feed_write_index,
2349                                 c->stream->feed->feed_size);
2350
2351         if (c->stream->max_time &&
2352             c->stream->max_time + c->start_time - cur_time < 0)
2353             /* We have timed out */
2354             c->state = HTTPSTATE_SEND_DATA_TRAILER;
2355         else {
2356             AVPacket pkt;
2357         redo:
2358             ret = av_read_frame(c->fmt_in, &pkt);
2359             if (ret < 0) {
2360                 if (c->stream->feed) {
2361                     /* if coming from feed, it means we reached the end of the
2362                        ffm file, so must wait for more data */
2363                     c->state = HTTPSTATE_WAIT_FEED;
2364                     return 1; /* state changed */
2365                 } else if (ret == AVERROR(EAGAIN)) {
2366                     /* input not ready, come back later */
2367                     return 0;
2368                 } else {
2369                     if (c->stream->loop) {
2370                         avformat_close_input(&c->fmt_in);
2371                         if (open_input_stream(c, "") < 0)
2372                             goto no_loop;
2373                         goto redo;
2374                     } else {
2375                     no_loop:
2376                         /* must send trailer now because EOF or error */
2377                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2378                     }
2379                 }
2380             } else {
2381                 int source_index = pkt.stream_index;
2382                 /* update first pts if needed */
2383                 if (c->first_pts == AV_NOPTS_VALUE) {
2384                     c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
2385                     c->start_time = cur_time;
2386                 }
2387                 /* send it to the appropriate stream */
2388                 if (c->stream->feed) {
2389                     /* if coming from a feed, select the right stream */
2390                     if (c->switch_pending) {
2391                         c->switch_pending = 0;
2392                         for(i=0;i<c->stream->nb_streams;i++) {
2393                             if (c->switch_feed_streams[i] == pkt.stream_index)
2394                                 if (pkt.flags & AV_PKT_FLAG_KEY)
2395                                     c->switch_feed_streams[i] = -1;
2396                             if (c->switch_feed_streams[i] >= 0)
2397                                 c->switch_pending = 1;
2398                         }
2399                     }
2400                     for(i=0;i<c->stream->nb_streams;i++) {
2401                         if (c->stream->feed_streams[i] == pkt.stream_index) {
2402                             AVStream *st = c->fmt_in->streams[source_index];
2403                             pkt.stream_index = i;
2404                             if (pkt.flags & AV_PKT_FLAG_KEY &&
2405                                 (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
2406                                  c->stream->nb_streams == 1))
2407                                 c->got_key_frame = 1;
2408                             if (!c->stream->send_on_key || c->got_key_frame)
2409                                 goto send_it;
2410                         }
2411                     }
2412                 } else {
2413                     AVCodecContext *codec;
2414                     AVStream *ist, *ost;
2415                 send_it:
2416                     ist = c->fmt_in->streams[source_index];
2417                     /* specific handling for RTP: we use several
2418                      * output streams (one for each RTP connection).
2419                      * XXX: need more abstract handling */
2420                     if (c->is_packetized) {
2421                         /* compute send time and duration */
2422                         c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
2423                         c->cur_pts -= c->first_pts;
2424                         c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
2425                         /* find RTP context */
2426                         c->packet_stream_index = pkt.stream_index;
2427                         ctx = c->rtp_ctx[c->packet_stream_index];
2428                         if(!ctx) {
2429                             av_free_packet(&pkt);
2430                             break;
2431                         }
2432                         codec = ctx->streams[0]->codec;
2433                         /* only one stream per RTP connection */
2434                         pkt.stream_index = 0;
2435                     } else {
2436                         ctx = &c->fmt_ctx;
2437                         /* Fudge here */
2438                         codec = ctx->streams[pkt.stream_index]->codec;
2439                     }
2440
2441                     if (c->is_packetized) {
2442                         int max_packet_size;
2443                         if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
2444                             max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
2445                         else
2446                             max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
2447                         ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size);
2448                     } else {
2449                         ret = avio_open_dyn_buf(&ctx->pb);
2450                     }
2451                     if (ret < 0) {
2452                         /* XXX: potential leak */
2453                         return -1;
2454                     }
2455                     ost = ctx->streams[pkt.stream_index];
2456
2457                     ctx->pb->seekable = 0;
2458                     if (pkt.dts != AV_NOPTS_VALUE)
2459                         pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base);
2460                     if (pkt.pts != AV_NOPTS_VALUE)
2461                         pkt.pts = av_rescale_q(pkt.pts, ist->time_base, ost->time_base);
2462                     pkt.duration = av_rescale_q(pkt.duration, ist->time_base, ost->time_base);
2463                     if ((ret = av_write_frame(ctx, &pkt)) < 0) {
2464                         http_log("Error writing frame to output for stream '%s': %s\n",
2465                                  c->stream->filename, av_err2str(ret));
2466                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2467                     }
2468
2469                     len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2470                     c->cur_frame_bytes = len;
2471                     c->buffer_ptr = c->pb_buffer;
2472                     c->buffer_end = c->pb_buffer + len;
2473
2474                     codec->frame_number++;
2475                     if (len == 0) {
2476                         av_free_packet(&pkt);
2477                         goto redo;
2478                     }
2479                 }
2480                 av_free_packet(&pkt);
2481             }
2482         }
2483         break;
2484     default:
2485     case HTTPSTATE_SEND_DATA_TRAILER:
2486         /* last packet test ? */
2487         if (c->last_packet_sent || c->is_packetized)
2488             return -1;
2489         ctx = &c->fmt_ctx;
2490         /* prepare header */
2491         if (avio_open_dyn_buf(&ctx->pb) < 0) {
2492             /* XXX: potential leak */
2493             return -1;
2494         }
2495         c->fmt_ctx.pb->seekable = 0;
2496         av_write_trailer(ctx);
2497         len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2498         c->buffer_ptr = c->pb_buffer;
2499         c->buffer_end = c->pb_buffer + len;
2500
2501         c->last_packet_sent = 1;
2502         break;
2503     }
2504     return 0;
2505 }
2506
2507 /* should convert the format at the same time */
2508 /* send data starting at c->buffer_ptr to the output connection
2509  * (either UDP or TCP) */
2510 static int http_send_data(HTTPContext *c)
2511 {
2512     int len, ret;
2513
2514     for(;;) {
2515         if (c->buffer_ptr >= c->buffer_end) {
2516             ret = http_prepare_data(c);
2517             if (ret < 0)
2518                 return -1;
2519             else if (ret != 0)
2520                 /* state change requested */
2521                 break;
2522         } else {
2523             if (c->is_packetized) {
2524                 /* RTP data output */
2525                 len = c->buffer_end - c->buffer_ptr;
2526                 if (len < 4) {
2527                     /* fail safe - should never happen */
2528                 fail1:
2529                     c->buffer_ptr = c->buffer_end;
2530                     return 0;
2531                 }
2532                 len = (c->buffer_ptr[0] << 24) |
2533                     (c->buffer_ptr[1] << 16) |
2534                     (c->buffer_ptr[2] << 8) |
2535                     (c->buffer_ptr[3]);
2536                 if (len > (c->buffer_end - c->buffer_ptr))
2537                     goto fail1;
2538                 if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
2539                     /* nothing to send yet: we can wait */
2540                     return 0;
2541                 }
2542
2543                 c->data_count += len;
2544                 update_datarate(&c->datarate, c->data_count);
2545                 if (c->stream)
2546                     c->stream->bytes_served += len;
2547
2548                 if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
2549                     /* RTP packets are sent inside the RTSP TCP connection */
2550                     AVIOContext *pb;
2551                     int interleaved_index, size;
2552                     uint8_t header[4];
2553                     HTTPContext *rtsp_c;
2554
2555                     rtsp_c = c->rtsp_c;
2556                     /* if no RTSP connection left, error */
2557                     if (!rtsp_c)
2558                         return -1;
2559                     /* if already sending something, then wait. */
2560                     if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
2561                         break;
2562                     if (avio_open_dyn_buf(&pb) < 0)
2563                         goto fail1;
2564                     interleaved_index = c->packet_stream_index * 2;
2565                     /* RTCP packets are sent at odd indexes */
2566                     if (c->buffer_ptr[1] == 200)
2567                         interleaved_index++;
2568                     /* write RTSP TCP header */
2569                     header[0] = '$';
2570                     header[1] = interleaved_index;
2571                     header[2] = len >> 8;
2572                     header[3] = len;
2573                     avio_write(pb, header, 4);
2574                     /* write RTP packet data */
2575                     c->buffer_ptr += 4;
2576                     avio_write(pb, c->buffer_ptr, len);
2577                     size = avio_close_dyn_buf(pb, &c->packet_buffer);
2578                     /* prepare asynchronous TCP sending */
2579                     rtsp_c->packet_buffer_ptr = c->packet_buffer;
2580                     rtsp_c->packet_buffer_end = c->packet_buffer + size;
2581                     c->buffer_ptr += len;
2582
2583                     /* send everything we can NOW */
2584                     len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
2585                                 rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
2586                     if (len > 0)
2587                         rtsp_c->packet_buffer_ptr += len;
2588                     if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
2589                         /* if we could not send all the data, we will
2590                            send it later, so a new state is needed to
2591                            "lock" the RTSP TCP connection */
2592                         rtsp_c->state = RTSPSTATE_SEND_PACKET;
2593                         break;
2594                     } else
2595                         /* all data has been sent */
2596                         av_freep(&c->packet_buffer);
2597                 } else {
2598                     /* send RTP packet directly in UDP */
2599                     c->buffer_ptr += 4;
2600                     ffurl_write(c->rtp_handles[c->packet_stream_index],
2601                                 c->buffer_ptr, len);
2602                     c->buffer_ptr += len;
2603                     /* here we continue as we can send several packets per 10 ms slot */
2604                 }
2605             } else {
2606                 /* TCP data output */
2607                 len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
2608                 if (len < 0) {
2609                     if (ff_neterrno() != AVERROR(EAGAIN) &&
2610                         ff_neterrno() != AVERROR(EINTR))
2611                         /* error : close connection */
2612                         return -1;
2613                     else
2614                         return 0;
2615                 } else
2616                     c->buffer_ptr += len;
2617
2618                 c->data_count += len;
2619                 update_datarate(&c->datarate, c->data_count);
2620                 if (c->stream)
2621                     c->stream->bytes_served += len;
2622                 break;
2623             }
2624         }
2625     } /* for(;;) */
2626     return 0;
2627 }
2628
2629 static int http_start_receive_data(HTTPContext *c)
2630 {
2631     int fd;
2632     int ret;
2633
2634     if (c->stream->feed_opened) {
2635         http_log("Stream feed '%s' was not opened\n", c->stream->feed_filename);
2636         return AVERROR(EINVAL);
2637     }
2638
2639     /* Don't permit writing to this one */
2640     if (c->stream->readonly) {
2641         http_log("Cannot write to read-only file '%s'\n", c->stream->feed_filename);
2642         return AVERROR(EINVAL);
2643     }
2644
2645     /* open feed */
2646     fd = open(c->stream->feed_filename, O_RDWR);
2647     if (fd < 0) {
2648         ret = AVERROR(errno);
2649         http_log("Could not open feed file '%s': %s\n",
2650                  c->stream->feed_filename, strerror(errno));
2651         return ret;
2652     }
2653     c->feed_fd = fd;
2654
2655     if (c->stream->truncate) {
2656         /* truncate feed file */
2657         ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
2658         http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
2659         if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
2660             ret = AVERROR(errno);
2661             http_log("Error truncating feed file '%s': %s\n",
2662                      c->stream->feed_filename, strerror(errno));
2663             return ret;
2664         }
2665     } else {
2666         ret = ffm_read_write_index(fd);
2667         if (ret < 0) {
2668             http_log("Error reading write index from feed file '%s': %s\n",
2669                      c->stream->feed_filename, strerror(errno));
2670             return ret;
2671         } else {
2672             c->stream->feed_write_index = ret;
2673         }
2674     }
2675
2676     c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
2677     c->stream->feed_size = lseek(fd, 0, SEEK_END);
2678     lseek(fd, 0, SEEK_SET);
2679
2680     /* init buffer input */
2681     c->buffer_ptr = c->buffer;
2682     c->buffer_end = c->buffer + FFM_PACKET_SIZE;
2683     c->stream->feed_opened = 1;
2684     c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
2685     return 0;
2686 }
2687
2688 static int http_receive_data(HTTPContext *c)
2689 {
2690     HTTPContext *c1;
2691     int len, loop_run = 0;
2692
2693     while (c->chunked_encoding && !c->chunk_size &&
2694            c->buffer_end > c->buffer_ptr) {
2695         /* read chunk header, if present */
2696         len = recv(c->fd, c->buffer_ptr, 1, 0);
2697
2698         if (len < 0) {
2699             if (ff_neterrno() != AVERROR(EAGAIN) &&
2700                 ff_neterrno() != AVERROR(EINTR))
2701                 /* error : close connection */
2702                 goto fail;
2703             return 0;
2704         } else if (len == 0) {
2705             /* end of connection : close it */
2706             goto fail;
2707         } else if (c->buffer_ptr - c->buffer >= 2 &&
2708                    !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
2709             c->chunk_size = strtol(c->buffer, 0, 16);
2710             if (c->chunk_size == 0) // end of stream
2711                 goto fail;
2712             c->buffer_ptr = c->buffer;
2713             break;
2714         } else if (++loop_run > 10) {
2715             /* no chunk header, abort */
2716             goto fail;
2717         } else {
2718             c->buffer_ptr++;
2719         }
2720     }
2721
2722     if (c->buffer_end > c->buffer_ptr) {
2723         len = recv(c->fd, c->buffer_ptr,
2724                    FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
2725         if (len < 0) {
2726             if (ff_neterrno() != AVERROR(EAGAIN) &&
2727                 ff_neterrno() != AVERROR(EINTR))
2728                 /* error : close connection */
2729                 goto fail;
2730         } else if (len == 0)
2731             /* end of connection : close it */
2732             goto fail;
2733         else {
2734             c->chunk_size -= len;
2735             c->buffer_ptr += len;
2736             c->data_count += len;
2737             update_datarate(&c->datarate, c->data_count);
2738         }
2739     }
2740
2741     if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
2742         if (c->buffer[0] != 'f' ||
2743             c->buffer[1] != 'm') {
2744             http_log("Feed stream has become desynchronized -- disconnecting\n");
2745             goto fail;
2746         }
2747     }
2748
2749     if (c->buffer_ptr >= c->buffer_end) {
2750         FFStream *feed = c->stream;
2751         /* a packet has been received : write it in the store, except
2752            if header */
2753         if (c->data_count > FFM_PACKET_SIZE) {
2754             /* XXX: use llseek or url_seek */
2755             lseek(c->feed_fd, feed->feed_write_index, SEEK_SET);
2756             if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
2757                 http_log("Error writing to feed file: %s\n", strerror(errno));
2758                 goto fail;
2759             }
2760
2761             feed->feed_write_index += FFM_PACKET_SIZE;
2762             /* update file size */
2763             if (feed->feed_write_index > c->stream->feed_size)
2764                 feed->feed_size = feed->feed_write_index;
2765
2766             /* handle wrap around if max file size reached */
2767             if (c->stream->feed_max_size && feed->feed_write_index >= c->stream->feed_max_size)
2768                 feed->feed_write_index = FFM_PACKET_SIZE;
2769
2770             /* write index */
2771             if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
2772                 http_log("Error writing index to feed file: %s\n", strerror(errno));
2773                 goto fail;
2774             }
2775
2776             /* wake up any waiting connections */
2777             for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2778                 if (c1->state == HTTPSTATE_WAIT_FEED &&
2779                     c1->stream->feed == c->stream->feed)
2780                     c1->state = HTTPSTATE_SEND_DATA;
2781             }
2782         } else {
2783             /* We have a header in our hands that contains useful data */
2784             AVFormatContext *s = avformat_alloc_context();
2785             AVIOContext *pb;
2786             AVInputFormat *fmt_in;
2787             int i;
2788
2789             if (!s)
2790                 goto fail;
2791
2792             /* use feed output format name to find corresponding input format */
2793             fmt_in = av_find_input_format(feed->fmt->name);
2794             if (!fmt_in)
2795                 goto fail;
2796
2797             pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
2798                                     0, NULL, NULL, NULL, NULL);
2799             pb->seekable = 0;
2800
2801             s->pb = pb;
2802             if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) {
2803                 av_free(pb);
2804                 goto fail;
2805             }
2806
2807             /* Now we have the actual streams */
2808             if (s->nb_streams != feed->nb_streams) {
2809                 avformat_close_input(&s);
2810                 av_free(pb);
2811                 http_log("Feed '%s' stream number does not match registered feed\n",
2812                          c->stream->feed_filename);
2813                 goto fail;
2814             }
2815
2816             for (i = 0; i < s->nb_streams; i++) {
2817                 AVStream *fst = feed->streams[i];
2818                 AVStream *st = s->streams[i];
2819                 avcodec_copy_context(fst->codec, st->codec);
2820             }
2821
2822             avformat_close_input(&s);
2823             av_free(pb);
2824         }
2825         c->buffer_ptr = c->buffer;
2826     }
2827
2828     return 0;
2829  fail:
2830     c->stream->feed_opened = 0;
2831     close(c->feed_fd);
2832     /* wake up any waiting connections to stop waiting for feed */
2833     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
2834         if (c1->state == HTTPSTATE_WAIT_FEED &&
2835             c1->stream->feed == c->stream->feed)
2836             c1->state = HTTPSTATE_SEND_DATA_TRAILER;
2837     }
2838     return -1;
2839 }
2840
2841 /********************************************************************/
2842 /* RTSP handling */
2843
2844 static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
2845 {
2846     const char *str;
2847     time_t ti;
2848     struct tm *tm;
2849     char buf2[32];
2850
2851     str = RTSP_STATUS_CODE2STRING(error_number);
2852     if (!str)
2853         str = "Unknown Error";
2854
2855     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
2856     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
2857
2858     /* output GMT time */
2859     ti = time(NULL);
2860     tm = gmtime(&ti);
2861     strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
2862     avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
2863 }
2864
2865 static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
2866 {
2867     rtsp_reply_header(c, error_number);
2868     avio_printf(c->pb, "\r\n");
2869 }
2870
2871 static int rtsp_parse_request(HTTPContext *c)
2872 {
2873     const char *p, *p1, *p2;
2874     char cmd[32];
2875     char url[1024];
2876     char protocol[32];
2877     char line[1024];
2878     int len;
2879     RTSPMessageHeader header1 = { 0 }, *header = &header1;
2880
2881     c->buffer_ptr[0] = '\0';
2882     p = c->buffer;
2883
2884     get_word(cmd, sizeof(cmd), &p);
2885     get_word(url, sizeof(url), &p);
2886     get_word(protocol, sizeof(protocol), &p);
2887
2888     av_strlcpy(c->method, cmd, sizeof(c->method));
2889     av_strlcpy(c->url, url, sizeof(c->url));
2890     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
2891
2892     if (avio_open_dyn_buf(&c->pb) < 0) {
2893         /* XXX: cannot do more */
2894         c->pb = NULL; /* safety */
2895         return -1;
2896     }
2897
2898     /* check version name */
2899     if (strcmp(protocol, "RTSP/1.0") != 0) {
2900         rtsp_reply_error(c, RTSP_STATUS_VERSION);
2901         goto the_end;
2902     }
2903
2904     /* parse each header line */
2905     /* skip to next line */
2906     while (*p != '\n' && *p != '\0')
2907         p++;
2908     if (*p == '\n')
2909         p++;
2910     while (*p != '\0') {
2911         p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
2912         if (!p1)
2913             break;
2914         p2 = p1;
2915         if (p2 > p && p2[-1] == '\r')
2916             p2--;
2917         /* skip empty line */
2918         if (p2 == p)
2919             break;
2920         len = p2 - p;
2921         if (len > sizeof(line) - 1)
2922             len = sizeof(line) - 1;
2923         memcpy(line, p, len);
2924         line[len] = '\0';
2925         ff_rtsp_parse_line(header, line, NULL, NULL);
2926         p = p1 + 1;
2927     }
2928
2929     /* handle sequence number */
2930     c->seq = header->seq;
2931
2932     if (!strcmp(cmd, "DESCRIBE"))
2933         rtsp_cmd_describe(c, url);
2934     else if (!strcmp(cmd, "OPTIONS"))
2935         rtsp_cmd_options(c, url);
2936     else if (!strcmp(cmd, "SETUP"))
2937         rtsp_cmd_setup(c, url, header);
2938     else if (!strcmp(cmd, "PLAY"))
2939         rtsp_cmd_play(c, url, header);
2940     else if (!strcmp(cmd, "PAUSE"))
2941         rtsp_cmd_interrupt(c, url, header, 1);
2942     else if (!strcmp(cmd, "TEARDOWN"))
2943         rtsp_cmd_interrupt(c, url, header, 0);
2944     else
2945         rtsp_reply_error(c, RTSP_STATUS_METHOD);
2946
2947  the_end:
2948     len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
2949     c->pb = NULL; /* safety */
2950     if (len < 0) {
2951         /* XXX: cannot do more */
2952         return -1;
2953     }
2954     c->buffer_ptr = c->pb_buffer;
2955     c->buffer_end = c->pb_buffer + len;
2956     c->state = RTSPSTATE_SEND_REPLY;
2957     return 0;
2958 }
2959
2960 static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
2961                                    struct in_addr my_ip)
2962 {
2963     AVFormatContext *avc;
2964     AVStream *avs = NULL;
2965     AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
2966     AVDictionaryEntry *entry = av_dict_get(stream->metadata, "title", NULL, 0);
2967     int i;
2968
2969     avc =  avformat_alloc_context();
2970     if (avc == NULL || !rtp_format) {
2971         return -1;
2972     }
2973     avc->oformat = rtp_format;
2974     av_dict_set(&avc->metadata, "title",
2975                 entry ? entry->value : "No Title", 0);
2976     avc->nb_streams = stream->nb_streams;
2977     if (stream->is_multicast) {
2978         snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
2979                  inet_ntoa(stream->multicast_ip),
2980                  stream->multicast_port, stream->multicast_ttl);
2981     } else {
2982         snprintf(avc->filename, 1024, "rtp://0.0.0.0");
2983     }
2984
2985     if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) ||
2986         !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams))))
2987         goto sdp_done;
2988     if (avc->nb_streams >= INT_MAX/sizeof(*avs) ||
2989         !(avs = av_malloc(avc->nb_streams * sizeof(*avs))))
2990         goto sdp_done;
2991
2992     for(i = 0; i < stream->nb_streams; i++) {
2993         avc->streams[i] = &avs[i];
2994         avc->streams[i]->codec = stream->streams[i]->codec;
2995     }
2996     *pbuffer = av_mallocz(2048);
2997     av_sdp_create(&avc, 1, *pbuffer, 2048);
2998
2999  sdp_done:
3000     av_free(avc->streams);
3001     av_dict_free(&avc->metadata);
3002     av_free(avc);
3003     av_free(avs);
3004
3005     return strlen(*pbuffer);
3006 }
3007
3008 static void rtsp_cmd_options(HTTPContext *c, const char *url)
3009 {
3010 //    rtsp_reply_header(c, RTSP_STATUS_OK);
3011     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
3012     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
3013     avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
3014     avio_printf(c->pb, "\r\n");
3015 }
3016
3017 static void rtsp_cmd_describe(HTTPContext *c, const char *url)
3018 {
3019     FFStream *stream;
3020     char path1[1024];
3021     const char *path;
3022     uint8_t *content;
3023     int content_length;
3024     socklen_t len;
3025     struct sockaddr_in my_addr;
3026
3027     /* find which URL is asked */
3028     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3029     path = path1;
3030     if (*path == '/')
3031         path++;
3032
3033     for(stream = first_stream; stream != NULL; stream = stream->next) {
3034         if (!stream->is_feed &&
3035             stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
3036             !strcmp(path, stream->filename)) {
3037             goto found;
3038         }
3039     }
3040     /* no stream found */
3041     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
3042     return;
3043
3044  found:
3045     /* prepare the media description in SDP format */
3046
3047     /* get the host IP */
3048     len = sizeof(my_addr);
3049     getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
3050     content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);
3051     if (content_length < 0) {
3052         rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
3053         return;
3054     }
3055     rtsp_reply_header(c, RTSP_STATUS_OK);
3056     avio_printf(c->pb, "Content-Base: %s/\r\n", url);
3057     avio_printf(c->pb, "Content-Type: application/sdp\r\n");
3058     avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
3059     avio_printf(c->pb, "\r\n");
3060     avio_write(c->pb, content, content_length);
3061     av_free(content);
3062 }
3063
3064 static HTTPContext *find_rtp_session(const char *session_id)
3065 {
3066     HTTPContext *c;
3067
3068     if (session_id[0] == '\0')
3069         return NULL;
3070
3071     for(c = first_http_ctx; c != NULL; c = c->next) {
3072         if (!strcmp(c->session_id, session_id))
3073             return c;
3074     }
3075     return NULL;
3076 }
3077
3078 static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
3079 {
3080     RTSPTransportField *th;
3081     int i;
3082
3083     for(i=0;i<h->nb_transports;i++) {
3084         th = &h->transports[i];
3085         if (th->lower_transport == lower_transport)
3086             return th;
3087     }
3088     return NULL;
3089 }
3090
3091 static void rtsp_cmd_setup(HTTPContext *c, const char *url,
3092                            RTSPMessageHeader *h)
3093 {
3094     FFStream *stream;
3095     int stream_index, rtp_port, rtcp_port;
3096     char buf[1024];
3097     char path1[1024];
3098     const char *path;
3099     HTTPContext *rtp_c;
3100     RTSPTransportField *th;
3101     struct sockaddr_in dest_addr;
3102     RTSPActionServerSetup setup;
3103
3104     /* find which URL is asked */
3105     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3106     path = path1;
3107     if (*path == '/')
3108         path++;
3109
3110     /* now check each stream */
3111     for(stream = first_stream; stream != NULL; stream = stream->next) {
3112         if (!stream->is_feed &&
3113             stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
3114             /* accept aggregate filenames only if single stream */
3115             if (!strcmp(path, stream->filename)) {
3116                 if (stream->nb_streams != 1) {
3117                     rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);
3118                     return;
3119                 }
3120                 stream_index = 0;
3121                 goto found;
3122             }
3123
3124             for(stream_index = 0; stream_index < stream->nb_streams;
3125                 stream_index++) {
3126                 snprintf(buf, sizeof(buf), "%s/streamid=%d",
3127                          stream->filename, stream_index);
3128                 if (!strcmp(path, buf))
3129                     goto found;
3130             }
3131         }
3132     }
3133     /* no stream found */
3134     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
3135     return;
3136  found:
3137
3138     /* generate session id if needed */
3139     if (h->session_id[0] == '\0') {
3140         unsigned random0 = av_lfg_get(&random_state);
3141         unsigned random1 = av_lfg_get(&random_state);
3142         snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
3143                  random0, random1);
3144     }
3145
3146     /* find RTP session, and create it if none found */
3147     rtp_c = find_rtp_session(h->session_id);
3148     if (!rtp_c) {
3149         /* always prefer UDP */
3150         th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
3151         if (!th) {
3152             th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
3153             if (!th) {
3154                 rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3155                 return;
3156             }
3157         }
3158
3159         rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
3160                                    th->lower_transport);
3161         if (!rtp_c) {
3162             rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
3163             return;
3164         }
3165
3166         /* open input stream */
3167         if (open_input_stream(rtp_c, "") < 0) {
3168             rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
3169             return;
3170         }
3171     }
3172
3173     /* test if stream is OK (test needed because several SETUP needs
3174        to be done for a given file) */
3175     if (rtp_c->stream != stream) {
3176         rtsp_reply_error(c, RTSP_STATUS_SERVICE);
3177         return;
3178     }
3179
3180     /* test if stream is already set up */
3181     if (rtp_c->rtp_ctx[stream_index]) {
3182         rtsp_reply_error(c, RTSP_STATUS_STATE);
3183         return;
3184     }
3185
3186     /* check transport */
3187     th = find_transport(h, rtp_c->rtp_protocol);
3188     if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
3189                 th->client_port_min <= 0)) {
3190         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3191         return;
3192     }
3193
3194     /* setup default options */
3195     setup.transport_option[0] = '\0';
3196     dest_addr = rtp_c->from_addr;
3197     dest_addr.sin_port = htons(th->client_port_min);
3198
3199     /* setup stream */
3200     if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
3201         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3202         return;
3203     }
3204
3205     /* now everything is OK, so we can send the connection parameters */
3206     rtsp_reply_header(c, RTSP_STATUS_OK);
3207     /* session ID */
3208     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3209
3210     switch(rtp_c->rtp_protocol) {
3211     case RTSP_LOWER_TRANSPORT_UDP:
3212         rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
3213         rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
3214         avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
3215                     "client_port=%d-%d;server_port=%d-%d",
3216                     th->client_port_min, th->client_port_max,
3217                     rtp_port, rtcp_port);
3218         break;
3219     case RTSP_LOWER_TRANSPORT_TCP:
3220         avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
3221                     stream_index * 2, stream_index * 2 + 1);
3222         break;
3223     default:
3224         break;
3225     }
3226     if (setup.transport_option[0] != '\0')
3227         avio_printf(c->pb, ";%s", setup.transport_option);
3228     avio_printf(c->pb, "\r\n");
3229
3230
3231     avio_printf(c->pb, "\r\n");
3232 }
3233
3234
3235 /* find an RTP connection by using the session ID. Check consistency
3236    with filename */
3237 static HTTPContext *find_rtp_session_with_url(const char *url,
3238                                               const char *session_id)
3239 {
3240     HTTPContext *rtp_c;
3241     char path1[1024];
3242     const char *path;
3243     char buf[1024];
3244     int s, len;
3245
3246     rtp_c = find_rtp_session(session_id);
3247     if (!rtp_c)
3248         return NULL;
3249
3250     /* find which URL is asked */
3251     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3252     path = path1;
3253     if (*path == '/')
3254         path++;
3255     if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
3256     for(s=0; s<rtp_c->stream->nb_streams; ++s) {
3257       snprintf(buf, sizeof(buf), "%s/streamid=%d",
3258         rtp_c->stream->filename, s);
3259       if(!strncmp(path, buf, sizeof(buf))) {
3260     // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
3261         return rtp_c;
3262       }
3263     }
3264     len = strlen(path);
3265     if (len > 0 && path[len - 1] == '/' &&
3266         !strncmp(path, rtp_c->stream->filename, len - 1))
3267         return rtp_c;
3268     return NULL;
3269 }
3270
3271 static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3272 {
3273     HTTPContext *rtp_c;
3274
3275     rtp_c = find_rtp_session_with_url(url, h->session_id);
3276     if (!rtp_c) {
3277         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3278         return;
3279     }
3280
3281     if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3282         rtp_c->state != HTTPSTATE_WAIT_FEED &&
3283         rtp_c->state != HTTPSTATE_READY) {
3284         rtsp_reply_error(c, RTSP_STATUS_STATE);
3285         return;
3286     }
3287
3288     rtp_c->state = HTTPSTATE_SEND_DATA;
3289
3290     /* now everything is OK, so we can send the connection parameters */
3291     rtsp_reply_header(c, RTSP_STATUS_OK);
3292     /* session ID */
3293     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3294     avio_printf(c->pb, "\r\n");
3295 }
3296
3297 static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeader *h, int pause_only)
3298 {
3299     HTTPContext *rtp_c;
3300
3301     rtp_c = find_rtp_session_with_url(url, h->session_id);
3302     if (!rtp_c) {
3303         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3304         return;
3305     }
3306
3307     if (pause_only) {
3308         if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3309             rtp_c->state != HTTPSTATE_WAIT_FEED) {
3310             rtsp_reply_error(c, RTSP_STATUS_STATE);
3311             return;
3312         }
3313         rtp_c->state = HTTPSTATE_READY;
3314         rtp_c->first_pts = AV_NOPTS_VALUE;
3315     }
3316
3317     /* now everything is OK, so we can send the connection parameters */
3318     rtsp_reply_header(c, RTSP_STATUS_OK);
3319     /* session ID */
3320     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3321     avio_printf(c->pb, "\r\n");
3322
3323     if (!pause_only)
3324         close_connection(rtp_c);
3325 }
3326
3327 /********************************************************************/
3328 /* RTP handling */
3329
3330 static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
3331                                        FFStream *stream, const char *session_id,
3332                                        enum RTSPLowerTransport rtp_protocol)
3333 {
3334     HTTPContext *c = NULL;
3335     const char *proto_str;
3336
3337     /* XXX: should output a warning page when coming
3338        close to the connection limit */
3339     if (nb_connections >= nb_max_connections)
3340         goto fail;
3341
3342     /* add a new connection */
3343     c = av_mallocz(sizeof(HTTPContext));
3344     if (!c)
3345         goto fail;
3346
3347     c->fd = -1;
3348     c->poll_entry = NULL;
3349     c->from_addr = *from_addr;
3350     c->buffer_size = IOBUFFER_INIT_SIZE;
3351     c->buffer = av_malloc(c->buffer_size);
3352     if (!c->buffer)
3353         goto fail;
3354     nb_connections++;
3355     c->stream = stream;
3356     av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
3357     c->state = HTTPSTATE_READY;
3358     c->is_packetized = 1;
3359     c->rtp_protocol = rtp_protocol;
3360
3361     /* protocol is shown in statistics */
3362     switch(c->rtp_protocol) {
3363     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3364         proto_str = "MCAST";
3365         break;
3366     case RTSP_LOWER_TRANSPORT_UDP:
3367         proto_str = "UDP";
3368         break;
3369     case RTSP_LOWER_TRANSPORT_TCP:
3370         proto_str = "TCP";
3371         break;
3372     default:
3373         proto_str = "???";
3374         break;
3375     }
3376     av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
3377     av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
3378
3379     current_bandwidth += stream->bandwidth;
3380
3381     c->next = first_http_ctx;
3382     first_http_ctx = c;
3383     return c;
3384
3385  fail:
3386     if (c) {
3387         av_free(c->buffer);
3388         av_free(c);
3389     }
3390     return NULL;
3391 }
3392
3393 /* add a new RTP stream in an RTP connection (used in RTSP SETUP
3394    command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
3395    used. */
3396 static int rtp_new_av_stream(HTTPContext *c,
3397                              int stream_index, struct sockaddr_in *dest_addr,
3398                              HTTPContext *rtsp_c)
3399 {
3400     AVFormatContext *ctx;
3401     AVStream *st;
3402     char *ipaddr;
3403     URLContext *h = NULL;
3404     uint8_t *dummy_buf;
3405     int max_packet_size;
3406
3407     /* now we can open the relevant output stream */
3408     ctx = avformat_alloc_context();
3409     if (!ctx)
3410         return -1;
3411     ctx->oformat = av_guess_format("rtp", NULL, NULL);
3412
3413     st = av_mallocz(sizeof(AVStream));
3414     if (!st)
3415         goto fail;
3416     ctx->nb_streams = 1;
3417     ctx->streams = av_mallocz(sizeof(AVStream *) * ctx->nb_streams);
3418     if (!ctx->streams)
3419       goto fail;
3420     ctx->streams[0] = st;
3421
3422     if (!c->stream->feed ||
3423         c->stream->feed == c->stream)
3424         memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
3425     else
3426         memcpy(st,
3427                c->stream->feed->streams[c->stream->feed_streams[stream_index]],
3428                sizeof(AVStream));
3429     st->priv_data = NULL;
3430
3431     /* build destination RTP address */
3432     ipaddr = inet_ntoa(dest_addr->sin_addr);
3433
3434     switch(c->rtp_protocol) {
3435     case RTSP_LOWER_TRANSPORT_UDP:
3436     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3437         /* RTP/UDP case */
3438
3439         /* XXX: also pass as parameter to function ? */
3440         if (c->stream->is_multicast) {
3441             int ttl;
3442             ttl = c->stream->multicast_ttl;
3443             if (!ttl)
3444                 ttl = 16;
3445             snprintf(ctx->filename, sizeof(ctx->filename),
3446                      "rtp://%s:%d?multicast=1&ttl=%d",
3447                      ipaddr, ntohs(dest_addr->sin_port), ttl);
3448         } else {
3449             snprintf(ctx->filename, sizeof(ctx->filename),
3450                      "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
3451         }
3452
3453         if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
3454             goto fail;
3455         c->rtp_handles[stream_index] = h;
3456         max_packet_size = h->max_packet_size;
3457         break;
3458     case RTSP_LOWER_TRANSPORT_TCP:
3459         /* RTP/TCP case */
3460         c->rtsp_c = rtsp_c;
3461         max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
3462         break;
3463     default:
3464         goto fail;
3465     }
3466
3467     http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
3468              ipaddr, ntohs(dest_addr->sin_port),
3469              c->stream->filename, stream_index, c->protocol);
3470
3471     /* normally, no packets should be output here, but the packet size may
3472      * be checked */
3473     if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
3474         /* XXX: close stream */
3475         goto fail;
3476     }
3477     if (avformat_write_header(ctx, NULL) < 0) {
3478     fail:
3479         if (h)
3480             ffurl_close(h);
3481         av_free(st);
3482         av_free(ctx);
3483         return -1;
3484     }
3485     avio_close_dyn_buf(ctx->pb, &dummy_buf);
3486     av_free(dummy_buf);
3487
3488     c->rtp_ctx[stream_index] = ctx;
3489     return 0;
3490 }
3491
3492 /********************************************************************/
3493 /* ffserver initialization */
3494
3495 static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
3496 {
3497     AVStream *fst;
3498
3499     if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
3500         return NULL;
3501
3502     fst = av_mallocz(sizeof(AVStream));
3503     if (!fst)
3504         return NULL;
3505     if (copy) {
3506         fst->codec = avcodec_alloc_context3(NULL);
3507         memcpy(fst->codec, codec, sizeof(AVCodecContext));
3508         if (codec->extradata_size) {
3509             fst->codec->extradata = av_mallocz(codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
3510             memcpy(fst->codec->extradata, codec->extradata,
3511                 codec->extradata_size);
3512         }
3513     } else {
3514         /* live streams must use the actual feed's codec since it may be
3515          * updated later to carry extradata needed by them.
3516          */
3517         fst->codec = codec;
3518     }
3519     fst->priv_data = av_mallocz(sizeof(FeedData));
3520     fst->index = stream->nb_streams;
3521     avpriv_set_pts_info(fst, 33, 1, 90000);
3522     fst->sample_aspect_ratio = codec->sample_aspect_ratio;
3523     stream->streams[stream->nb_streams++] = fst;
3524     return fst;
3525 }
3526
3527 /* return the stream number in the feed */
3528 static int add_av_stream(FFStream *feed, AVStream *st)
3529 {
3530     AVStream *fst;
3531     AVCodecContext *av, *av1;
3532     int i;
3533
3534     av = st->codec;
3535     for(i=0;i<feed->nb_streams;i++) {
3536         st = feed->streams[i];
3537         av1 = st->codec;
3538         if (av1->codec_id == av->codec_id &&
3539             av1->codec_type == av->codec_type &&
3540             av1->bit_rate == av->bit_rate) {
3541
3542             switch(av->codec_type) {
3543             case AVMEDIA_TYPE_AUDIO:
3544                 if (av1->channels == av->channels &&
3545                     av1->sample_rate == av->sample_rate)
3546                     return i;
3547                 break;
3548             case AVMEDIA_TYPE_VIDEO:
3549                 if (av1->width == av->width &&
3550                     av1->height == av->height &&
3551                     av1->time_base.den == av->time_base.den &&
3552                     av1->time_base.num == av->time_base.num &&
3553                     av1->gop_size == av->gop_size)
3554                     return i;
3555                 break;
3556             default:
3557                 abort();
3558             }
3559         }
3560     }
3561
3562     fst = add_av_stream1(feed, av, 0);
3563     if (!fst)
3564         return -1;
3565     return feed->nb_streams - 1;
3566 }
3567
3568 static void remove_stream(FFStream *stream)
3569 {
3570     FFStream **ps;
3571     ps = &first_stream;
3572     while (*ps != NULL) {
3573         if (*ps == stream)
3574             *ps = (*ps)->next;
3575         else
3576             ps = &(*ps)->next;
3577     }
3578 }
3579
3580 /* specific MPEG4 handling : we extract the raw parameters */
3581 static void extract_mpeg4_header(AVFormatContext *infile)
3582 {
3583     int mpeg4_count, i, size;
3584     AVPacket pkt;
3585     AVStream *st;
3586     const uint8_t *p;
3587
3588     infile->flags |= AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE;
3589
3590     mpeg4_count = 0;
3591     for(i=0;i<infile->nb_streams;i++) {
3592         st = infile->streams[i];
3593         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3594             st->codec->extradata_size == 0) {
3595             mpeg4_count++;
3596         }
3597     }
3598     if (!mpeg4_count)
3599         return;
3600
3601     printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
3602     while (mpeg4_count > 0) {
3603         if (av_read_frame(infile, &pkt) < 0)
3604             break;
3605         st = infile->streams[pkt.stream_index];
3606         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3607             st->codec->extradata_size == 0) {
3608             av_freep(&st->codec->extradata);
3609             /* fill extradata with the header */
3610             /* XXX: we make hard suppositions here ! */
3611             p = pkt.data;
3612             while (p < pkt.data + pkt.size - 4) {
3613                 /* stop when vop header is found */
3614                 if (p[0] == 0x00 && p[1] == 0x00 &&
3615                     p[2] == 0x01 && p[3] == 0xb6) {
3616                     size = p - pkt.data;
3617                     //                    av_hex_dump_log(infile, AV_LOG_DEBUG, pkt.data, size);
3618                     st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
3619                     st->codec->extradata_size = size;
3620                     memcpy(st->codec->extradata, pkt.data, size);
3621                     break;
3622                 }
3623                 p++;
3624             }
3625             mpeg4_count--;
3626         }
3627         av_free_packet(&pkt);
3628     }
3629 }
3630
3631 /* compute the needed AVStream for each file */
3632 static void build_file_streams(void)
3633 {
3634     FFStream *stream, *stream_next;
3635     int i, ret;
3636
3637     /* gather all streams */
3638     for(stream = first_stream; stream != NULL; stream = stream_next) {
3639         AVFormatContext *infile = NULL;
3640         stream_next = stream->next;
3641         if (stream->stream_type == STREAM_TYPE_LIVE &&
3642             !stream->feed) {
3643             /* the stream comes from a file */
3644             /* try to open the file */
3645             /* open stream */
3646             if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
3647                 /* specific case : if transport stream output to RTP,
3648                    we use a raw transport stream reader */
3649                 av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
3650             }
3651
3652             if (!stream->feed_filename[0]) {
3653                 http_log("Unspecified feed file for stream '%s'\n", stream->filename);
3654                 goto fail;
3655             }
3656
3657             http_log("Opening feed file '%s' for stream '%s'\n", stream->feed_filename, stream->filename);
3658             if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
3659                 http_log("Could not open '%s': %s\n", stream->feed_filename, av_err2str(ret));
3660                 /* remove stream (no need to spend more time on it) */
3661             fail:
3662                 remove_stream(stream);
3663             } else {
3664                 /* find all the AVStreams inside and reference them in
3665                    'stream' */
3666                 if (avformat_find_stream_info(infile, NULL) < 0) {
3667                     http_log("Could not find codec parameters from '%s'\n",
3668                              stream->feed_filename);
3669                     avformat_close_input(&infile);
3670                     goto fail;
3671                 }
3672                 extract_mpeg4_header(infile);