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