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