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