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