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