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