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