2de35ba0b9913e13f56fcb2cf205fb742e91f6ee
[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
2123     bytes_left = c->buffer_end - c->buffer_ptr;
2124     bytes_sent = frame_bytes - bytes_left;
2125     return c->cur_pts + (c->cur_frame_duration * bytes_sent) / frame_bytes;
2126 }
2127
2128
2129 static int http_prepare_data(HTTPContext *c)
2130 {
2131     int i, len, ret;
2132     AVFormatContext *ctx;
2133
2134     av_freep(&c->pb_buffer);
2135     switch(c->state) {
2136     case HTTPSTATE_SEND_DATA_HEADER:
2137         ctx = avformat_alloc_context();
2138         if (!ctx)
2139             return AVERROR(ENOMEM);
2140         c->fmt_ctx = *ctx;
2141         av_freep(&ctx);
2142         av_dict_copy(&(c->fmt_ctx.metadata), c->stream->metadata, 0);
2143         c->fmt_ctx.streams = av_mallocz_array(c->stream->nb_streams,
2144                                               sizeof(AVStream *));
2145         if (!c->fmt_ctx.streams)
2146             return AVERROR(ENOMEM);
2147
2148         for(i=0;i<c->stream->nb_streams;i++) {
2149             AVStream *src;
2150             c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
2151
2152             /* if file or feed, then just take streams from FFServerStream struct */
2153             if (!c->stream->feed ||
2154                 c->stream->feed == c->stream)
2155                 src = c->stream->streams[i];
2156             else
2157                 src = c->stream->feed->streams[c->stream->feed_streams[i]];
2158
2159             *(c->fmt_ctx.streams[i]) = *src;
2160             c->fmt_ctx.streams[i]->priv_data = 0;
2161             /* XXX: should be done in AVStream, not in codec */
2162             c->fmt_ctx.streams[i]->codec->frame_number = 0;
2163         }
2164         /* set output format parameters */
2165         c->fmt_ctx.oformat = c->stream->fmt;
2166         c->fmt_ctx.nb_streams = c->stream->nb_streams;
2167
2168         c->got_key_frame = 0;
2169
2170         /* prepare header and save header data in a stream */
2171         if (avio_open_dyn_buf(&c->fmt_ctx.pb) < 0) {
2172             /* XXX: potential leak */
2173             return -1;
2174         }
2175         c->fmt_ctx.pb->seekable = 0;
2176
2177         /*
2178          * HACK to avoid MPEG-PS muxer to spit many underflow errors
2179          * Default value from FFmpeg
2180          * Try to set it using configuration option
2181          */
2182         c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
2183
2184         if ((ret = avformat_write_header(&c->fmt_ctx, NULL)) < 0) {
2185             http_log("Error writing output header for stream '%s': %s\n",
2186                      c->stream->filename, av_err2str(ret));
2187             return ret;
2188         }
2189         av_dict_free(&c->fmt_ctx.metadata);
2190
2191         len = avio_close_dyn_buf(c->fmt_ctx.pb, &c->pb_buffer);
2192         c->buffer_ptr = c->pb_buffer;
2193         c->buffer_end = c->pb_buffer + len;
2194
2195         c->state = HTTPSTATE_SEND_DATA;
2196         c->last_packet_sent = 0;
2197         break;
2198     case HTTPSTATE_SEND_DATA:
2199         /* find a new packet */
2200         /* read a packet from the input stream */
2201         if (c->stream->feed)
2202             ffm_set_write_index(c->fmt_in,
2203                                 c->stream->feed->feed_write_index,
2204                                 c->stream->feed->feed_size);
2205
2206         if (c->stream->max_time &&
2207             c->stream->max_time + c->start_time - cur_time < 0)
2208             /* We have timed out */
2209             c->state = HTTPSTATE_SEND_DATA_TRAILER;
2210         else {
2211             AVPacket pkt;
2212         redo:
2213             ret = av_read_frame(c->fmt_in, &pkt);
2214             if (ret < 0) {
2215                 if (c->stream->feed) {
2216                     /* if coming from feed, it means we reached the end of the
2217                        ffm file, so must wait for more data */
2218                     c->state = HTTPSTATE_WAIT_FEED;
2219                     return 1; /* state changed */
2220                 } else if (ret == AVERROR(EAGAIN)) {
2221                     /* input not ready, come back later */
2222                     return 0;
2223                 }
2224                 if (c->stream->loop) {
2225                     avformat_close_input(&c->fmt_in);
2226                     if (open_input_stream(c, "") < 0)
2227                         goto no_loop;
2228                     goto redo;
2229                 } else {
2230                     no_loop:
2231                         /* must send trailer now because EOF or error */
2232                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2233                 }
2234             } else {
2235                 int source_index = pkt.stream_index;
2236                 /* update first pts if needed */
2237                 if (c->first_pts == AV_NOPTS_VALUE) {
2238                     c->first_pts = av_rescale_q(pkt.dts, c->fmt_in->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
2239                     c->start_time = cur_time;
2240                 }
2241                 /* send it to the appropriate stream */
2242                 if (c->stream->feed) {
2243                     /* if coming from a feed, select the right stream */
2244                     if (c->switch_pending) {
2245                         c->switch_pending = 0;
2246                         for(i=0;i<c->stream->nb_streams;i++) {
2247                             if (c->switch_feed_streams[i] == pkt.stream_index)
2248                                 if (pkt.flags & AV_PKT_FLAG_KEY)
2249                                     c->switch_feed_streams[i] = -1;
2250                             if (c->switch_feed_streams[i] >= 0)
2251                                 c->switch_pending = 1;
2252                         }
2253                     }
2254                     for(i=0;i<c->stream->nb_streams;i++) {
2255                         if (c->stream->feed_streams[i] == pkt.stream_index) {
2256                             AVStream *st = c->fmt_in->streams[source_index];
2257                             pkt.stream_index = i;
2258                             if (pkt.flags & AV_PKT_FLAG_KEY &&
2259                                 (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
2260                                  c->stream->nb_streams == 1))
2261                                 c->got_key_frame = 1;
2262                             if (!c->stream->send_on_key || c->got_key_frame)
2263                                 goto send_it;
2264                         }
2265                     }
2266                 } else {
2267                     AVCodecContext *codec;
2268                     AVStream *ist, *ost;
2269                 send_it:
2270                     ist = c->fmt_in->streams[source_index];
2271                     /* specific handling for RTP: we use several
2272                      * output streams (one for each RTP connection).
2273                      * XXX: need more abstract handling */
2274                     if (c->is_packetized) {
2275                         /* compute send time and duration */
2276                         c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
2277                         c->cur_pts -= c->first_pts;
2278                         c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
2279                         /* find RTP context */
2280                         c->packet_stream_index = pkt.stream_index;
2281                         ctx = c->rtp_ctx[c->packet_stream_index];
2282                         if(!ctx) {
2283                             av_free_packet(&pkt);
2284                             break;
2285                         }
2286                         codec = ctx->streams[0]->codec;
2287                         /* only one stream per RTP connection */
2288                         pkt.stream_index = 0;
2289                     } else {
2290                         ctx = &c->fmt_ctx;
2291                         /* Fudge here */
2292                         codec = ctx->streams[pkt.stream_index]->codec;
2293                     }
2294
2295                     if (c->is_packetized) {
2296                         int max_packet_size;
2297                         if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
2298                             max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
2299                         else
2300                             max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
2301                         ret = ffio_open_dyn_packet_buf(&ctx->pb,
2302                                                        max_packet_size);
2303                     } else {
2304                         ret = avio_open_dyn_buf(&ctx->pb);
2305                     }
2306                     if (ret < 0) {
2307                         /* XXX: potential leak */
2308                         return -1;
2309                     }
2310                     ost = ctx->streams[pkt.stream_index];
2311
2312                     ctx->pb->seekable = 0;
2313                     if (pkt.dts != AV_NOPTS_VALUE)
2314                         pkt.dts = av_rescale_q(pkt.dts, ist->time_base,
2315                                                ost->time_base);
2316                     if (pkt.pts != AV_NOPTS_VALUE)
2317                         pkt.pts = av_rescale_q(pkt.pts, ist->time_base,
2318                                                ost->time_base);
2319                     pkt.duration = av_rescale_q(pkt.duration, ist->time_base,
2320                                                 ost->time_base);
2321                     if ((ret = av_write_frame(ctx, &pkt)) < 0) {
2322                         http_log("Error writing frame to output for stream '%s': %s\n",
2323                                  c->stream->filename, av_err2str(ret));
2324                         c->state = HTTPSTATE_SEND_DATA_TRAILER;
2325                     }
2326
2327                     av_freep(&c->pb_buffer);
2328                     len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2329                     c->cur_frame_bytes = len;
2330                     c->buffer_ptr = c->pb_buffer;
2331                     c->buffer_end = c->pb_buffer + len;
2332
2333                     codec->frame_number++;
2334                     if (len == 0) {
2335                         av_free_packet(&pkt);
2336                         goto redo;
2337                     }
2338                 }
2339                 av_free_packet(&pkt);
2340             }
2341         }
2342         break;
2343     default:
2344     case HTTPSTATE_SEND_DATA_TRAILER:
2345         /* last packet test ? */
2346         if (c->last_packet_sent || c->is_packetized)
2347             return -1;
2348         ctx = &c->fmt_ctx;
2349         /* prepare header */
2350         if (avio_open_dyn_buf(&ctx->pb) < 0) {
2351             /* XXX: potential leak */
2352             return -1;
2353         }
2354         c->fmt_ctx.pb->seekable = 0;
2355         av_write_trailer(ctx);
2356         len = avio_close_dyn_buf(ctx->pb, &c->pb_buffer);
2357         c->buffer_ptr = c->pb_buffer;
2358         c->buffer_end = c->pb_buffer + len;
2359
2360         c->last_packet_sent = 1;
2361         break;
2362     }
2363     return 0;
2364 }
2365
2366 /* should convert the format at the same time */
2367 /* send data starting at c->buffer_ptr to the output connection
2368  * (either UDP or TCP) */
2369 static int http_send_data(HTTPContext *c)
2370 {
2371     int len, ret;
2372
2373     for(;;) {
2374         if (c->buffer_ptr >= c->buffer_end) {
2375             ret = http_prepare_data(c);
2376             if (ret < 0)
2377                 return -1;
2378             else if (ret)
2379                 /* state change requested */
2380                 break;
2381         } else {
2382             if (c->is_packetized) {
2383                 /* RTP data output */
2384                 len = c->buffer_end - c->buffer_ptr;
2385                 if (len < 4) {
2386                     /* fail safe - should never happen */
2387                 fail1:
2388                     c->buffer_ptr = c->buffer_end;
2389                     return 0;
2390                 }
2391                 len = (c->buffer_ptr[0] << 24) |
2392                     (c->buffer_ptr[1] << 16) |
2393                     (c->buffer_ptr[2] << 8) |
2394                     (c->buffer_ptr[3]);
2395                 if (len > (c->buffer_end - c->buffer_ptr))
2396                     goto fail1;
2397                 if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {
2398                     /* nothing to send yet: we can wait */
2399                     return 0;
2400                 }
2401
2402                 c->data_count += len;
2403                 update_datarate(&c->datarate, c->data_count);
2404                 if (c->stream)
2405                     c->stream->bytes_served += len;
2406
2407                 if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
2408                     /* RTP packets are sent inside the RTSP TCP connection */
2409                     AVIOContext *pb;
2410                     int interleaved_index, size;
2411                     uint8_t header[4];
2412                     HTTPContext *rtsp_c;
2413
2414                     rtsp_c = c->rtsp_c;
2415                     /* if no RTSP connection left, error */
2416                     if (!rtsp_c)
2417                         return -1;
2418                     /* if already sending something, then wait. */
2419                     if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)
2420                         break;
2421                     if (avio_open_dyn_buf(&pb) < 0)
2422                         goto fail1;
2423                     interleaved_index = c->packet_stream_index * 2;
2424                     /* RTCP packets are sent at odd indexes */
2425                     if (c->buffer_ptr[1] == 200)
2426                         interleaved_index++;
2427                     /* write RTSP TCP header */
2428                     header[0] = '$';
2429                     header[1] = interleaved_index;
2430                     header[2] = len >> 8;
2431                     header[3] = len;
2432                     avio_write(pb, header, 4);
2433                     /* write RTP packet data */
2434                     c->buffer_ptr += 4;
2435                     avio_write(pb, c->buffer_ptr, len);
2436                     size = avio_close_dyn_buf(pb, &c->packet_buffer);
2437                     /* prepare asynchronous TCP sending */
2438                     rtsp_c->packet_buffer_ptr = c->packet_buffer;
2439                     rtsp_c->packet_buffer_end = c->packet_buffer + size;
2440                     c->buffer_ptr += len;
2441
2442                     /* send everything we can NOW */
2443                     len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,
2444                                rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);
2445                     if (len > 0)
2446                         rtsp_c->packet_buffer_ptr += len;
2447                     if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
2448                         /* if we could not send all the data, we will
2449                            send it later, so a new state is needed to
2450                            "lock" the RTSP TCP connection */
2451                         rtsp_c->state = RTSPSTATE_SEND_PACKET;
2452                         break;
2453                     } else
2454                         /* all data has been sent */
2455                         av_freep(&c->packet_buffer);
2456                 } else {
2457                     /* send RTP packet directly in UDP */
2458                     c->buffer_ptr += 4;
2459                     ffurl_write(c->rtp_handles[c->packet_stream_index],
2460                                 c->buffer_ptr, len);
2461                     c->buffer_ptr += len;
2462                     /* here we continue as we can send several packets
2463                      * per 10 ms slot */
2464                 }
2465             } else {
2466                 /* TCP data output */
2467                 len = send(c->fd, c->buffer_ptr,
2468                            c->buffer_end - c->buffer_ptr, 0);
2469                 if (len < 0) {
2470                     if (ff_neterrno() != AVERROR(EAGAIN) &&
2471                         ff_neterrno() != AVERROR(EINTR))
2472                         /* error : close connection */
2473                         return -1;
2474                     else
2475                         return 0;
2476                 }
2477                 c->buffer_ptr += len;
2478
2479                 c->data_count += len;
2480                 update_datarate(&c->datarate, c->data_count);
2481                 if (c->stream)
2482                     c->stream->bytes_served += len;
2483                 break;
2484             }
2485         }
2486     } /* for(;;) */
2487     return 0;
2488 }
2489
2490 static int http_start_receive_data(HTTPContext *c)
2491 {
2492     int fd;
2493     int ret;
2494
2495     if (c->stream->feed_opened) {
2496         http_log("Stream feed '%s' was not opened\n",
2497                  c->stream->feed_filename);
2498         return AVERROR(EINVAL);
2499     }
2500
2501     /* Don't permit writing to this one */
2502     if (c->stream->readonly) {
2503         http_log("Cannot write to read-only file '%s'\n",
2504                  c->stream->feed_filename);
2505         return AVERROR(EINVAL);
2506     }
2507
2508     /* open feed */
2509     fd = open(c->stream->feed_filename, O_RDWR);
2510     if (fd < 0) {
2511         ret = AVERROR(errno);
2512         http_log("Could not open feed file '%s': %s\n",
2513                  c->stream->feed_filename, strerror(errno));
2514         return ret;
2515     }
2516     c->feed_fd = fd;
2517
2518     if (c->stream->truncate) {
2519         /* truncate feed file */
2520         ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE);
2521         http_log("Truncating feed file '%s'\n", c->stream->feed_filename);
2522         if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) {
2523             ret = AVERROR(errno);
2524             http_log("Error truncating feed file '%s': %s\n",
2525                      c->stream->feed_filename, strerror(errno));
2526             return ret;
2527         }
2528     } else {
2529         ret = ffm_read_write_index(fd);
2530         if (ret < 0) {
2531             http_log("Error reading write index from feed file '%s': %s\n",
2532                      c->stream->feed_filename, strerror(errno));
2533             return ret;
2534         } else {
2535             c->stream->feed_write_index = ret;
2536         }
2537     }
2538
2539     c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd),
2540                                         FFM_PACKET_SIZE);
2541     c->stream->feed_size = lseek(fd, 0, SEEK_END);
2542     lseek(fd, 0, SEEK_SET);
2543
2544     /* init buffer input */
2545     c->buffer_ptr = c->buffer;
2546     c->buffer_end = c->buffer + FFM_PACKET_SIZE;
2547     c->stream->feed_opened = 1;
2548     c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
2549     return 0;
2550 }
2551
2552 static int http_receive_data(HTTPContext *c)
2553 {
2554     HTTPContext *c1;
2555     int len, loop_run = 0;
2556
2557     while (c->chunked_encoding && !c->chunk_size &&
2558            c->buffer_end > c->buffer_ptr) {
2559         /* read chunk header, if present */
2560         len = recv(c->fd, c->buffer_ptr, 1, 0);
2561
2562         if (len < 0) {
2563             if (ff_neterrno() != AVERROR(EAGAIN) &&
2564                 ff_neterrno() != AVERROR(EINTR))
2565                 /* error : close connection */
2566                 goto fail;
2567             return 0;
2568         } else if (len == 0) {
2569             /* end of connection : close it */
2570             goto fail;
2571         } else if (c->buffer_ptr - c->buffer >= 2 &&
2572                    !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
2573             c->chunk_size = strtol(c->buffer, 0, 16);
2574             if (c->chunk_size == 0) // end of stream
2575                 goto fail;
2576             c->buffer_ptr = c->buffer;
2577             break;
2578         } else if (++loop_run > 10) {
2579             /* no chunk header, abort */
2580             goto fail;
2581         } else {
2582             c->buffer_ptr++;
2583         }
2584     }
2585
2586     if (c->buffer_end > c->buffer_ptr) {
2587         len = recv(c->fd, c->buffer_ptr,
2588                    FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
2589         if (len < 0) {
2590             if (ff_neterrno() != AVERROR(EAGAIN) &&
2591                 ff_neterrno() != AVERROR(EINTR))
2592                 /* error : close connection */
2593                 goto fail;
2594         } else if (len == 0)
2595             /* end of connection : close it */
2596             goto fail;
2597         else {
2598             c->chunk_size -= len;
2599             c->buffer_ptr += len;
2600             c->data_count += len;
2601             update_datarate(&c->datarate, c->data_count);
2602         }
2603     }
2604
2605     if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
2606         if (c->buffer[0] != 'f' ||
2607             c->buffer[1] != 'm') {
2608             http_log("Feed stream has become desynchronized -- disconnecting\n");
2609             goto fail;
2610         }
2611     }
2612
2613     if (c->buffer_ptr >= c->buffer_end) {
2614         FFServerStream *feed = c->stream;
2615         /* a packet has been received : write it in the store, except
2616            if header */
2617         if (c->data_count > FFM_PACKET_SIZE) {
2618             /* XXX: use llseek or url_seek
2619              * XXX: Should probably fail? */
2620             if (lseek(c->feed_fd, feed->feed_write_index, SEEK_SET) == -1)
2621                 http_log("Seek to %"PRId64" failed\n", feed->feed_write_index);
2622
2623             if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) {
2624                 http_log("Error writing to feed file: %s\n", strerror(errno));
2625                 goto fail;
2626             }
2627
2628             feed->feed_write_index += FFM_PACKET_SIZE;
2629             /* update file size */
2630             if (feed->feed_write_index > c->stream->feed_size)
2631                 feed->feed_size = feed->feed_write_index;
2632
2633             /* handle wrap around if max file size reached */
2634             if (c->stream->feed_max_size &&
2635                 feed->feed_write_index >= c->stream->feed_max_size)
2636                 feed->feed_write_index = FFM_PACKET_SIZE;
2637
2638             /* write index */
2639             if (ffm_write_write_index(c->feed_fd, feed->feed_write_index) < 0) {
2640                 http_log("Error writing index to feed file: %s\n",
2641                          strerror(errno));
2642                 goto fail;
2643             }
2644
2645             /* wake up any waiting connections */
2646             for(c1 = first_http_ctx; c1; c1 = c1->next) {
2647                 if (c1->state == HTTPSTATE_WAIT_FEED &&
2648                     c1->stream->feed == c->stream->feed)
2649                     c1->state = HTTPSTATE_SEND_DATA;
2650             }
2651         } else {
2652             /* We have a header in our hands that contains useful data */
2653             AVFormatContext *s = avformat_alloc_context();
2654             AVIOContext *pb;
2655             AVInputFormat *fmt_in;
2656             int i;
2657
2658             if (!s)
2659                 goto fail;
2660
2661             /* use feed output format name to find corresponding input format */
2662             fmt_in = av_find_input_format(feed->fmt->name);
2663             if (!fmt_in)
2664                 goto fail;
2665
2666             pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
2667                                     0, NULL, NULL, NULL, NULL);
2668             if (!pb)
2669                 goto fail;
2670
2671             pb->seekable = 0;
2672
2673             s->pb = pb;
2674             if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) {
2675                 av_freep(&pb);
2676                 goto fail;
2677             }
2678
2679             /* Now we have the actual streams */
2680             if (s->nb_streams != feed->nb_streams) {
2681                 avformat_close_input(&s);
2682                 av_freep(&pb);
2683                 http_log("Feed '%s' stream number does not match registered feed\n",
2684                          c->stream->feed_filename);
2685                 goto fail;
2686             }
2687
2688             for (i = 0; i < s->nb_streams; i++) {
2689                 AVStream *fst = feed->streams[i];
2690                 AVStream *st = s->streams[i];
2691                 avcodec_copy_context(fst->codec, st->codec);
2692             }
2693
2694             avformat_close_input(&s);
2695             av_freep(&pb);
2696         }
2697         c->buffer_ptr = c->buffer;
2698     }
2699
2700     return 0;
2701  fail:
2702     c->stream->feed_opened = 0;
2703     close(c->feed_fd);
2704     /* wake up any waiting connections to stop waiting for feed */
2705     for(c1 = first_http_ctx; c1; c1 = c1->next) {
2706         if (c1->state == HTTPSTATE_WAIT_FEED &&
2707             c1->stream->feed == c->stream->feed)
2708             c1->state = HTTPSTATE_SEND_DATA_TRAILER;
2709     }
2710     return -1;
2711 }
2712
2713 /********************************************************************/
2714 /* RTSP handling */
2715
2716 static void rtsp_reply_header(HTTPContext *c, enum RTSPStatusCode error_number)
2717 {
2718     const char *str;
2719     time_t ti;
2720     struct tm *tm;
2721     char buf2[32];
2722
2723     str = RTSP_STATUS_CODE2STRING(error_number);
2724     if (!str)
2725         str = "Unknown Error";
2726
2727     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
2728     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
2729
2730     /* output GMT time */
2731     ti = time(NULL);
2732     tm = gmtime(&ti);
2733     strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
2734     avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
2735 }
2736
2737 static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
2738 {
2739     rtsp_reply_header(c, error_number);
2740     avio_printf(c->pb, "\r\n");
2741 }
2742
2743 static int rtsp_parse_request(HTTPContext *c)
2744 {
2745     const char *p, *p1, *p2;
2746     char cmd[32];
2747     char url[1024];
2748     char protocol[32];
2749     char line[1024];
2750     int len;
2751     RTSPMessageHeader header1 = { 0 }, *header = &header1;
2752
2753     c->buffer_ptr[0] = '\0';
2754     p = c->buffer;
2755
2756     get_word(cmd, sizeof(cmd), &p);
2757     get_word(url, sizeof(url), &p);
2758     get_word(protocol, sizeof(protocol), &p);
2759
2760     av_strlcpy(c->method, cmd, sizeof(c->method));
2761     av_strlcpy(c->url, url, sizeof(c->url));
2762     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
2763
2764     if (avio_open_dyn_buf(&c->pb) < 0) {
2765         /* XXX: cannot do more */
2766         c->pb = NULL; /* safety */
2767         return -1;
2768     }
2769
2770     /* check version name */
2771     if (strcmp(protocol, "RTSP/1.0")) {
2772         rtsp_reply_error(c, RTSP_STATUS_VERSION);
2773         goto the_end;
2774     }
2775
2776     /* parse each header line */
2777     /* skip to next line */
2778     while (*p != '\n' && *p != '\0')
2779         p++;
2780     if (*p == '\n')
2781         p++;
2782     while (*p != '\0') {
2783         p1 = memchr(p, '\n', (char *)c->buffer_ptr - p);
2784         if (!p1)
2785             break;
2786         p2 = p1;
2787         if (p2 > p && p2[-1] == '\r')
2788             p2--;
2789         /* skip empty line */
2790         if (p2 == p)
2791             break;
2792         len = p2 - p;
2793         if (len > sizeof(line) - 1)
2794             len = sizeof(line) - 1;
2795         memcpy(line, p, len);
2796         line[len] = '\0';
2797         ff_rtsp_parse_line(header, line, NULL, NULL);
2798         p = p1 + 1;
2799     }
2800
2801     /* handle sequence number */
2802     c->seq = header->seq;
2803
2804     if (!strcmp(cmd, "DESCRIBE"))
2805         rtsp_cmd_describe(c, url);
2806     else if (!strcmp(cmd, "OPTIONS"))
2807         rtsp_cmd_options(c, url);
2808     else if (!strcmp(cmd, "SETUP"))
2809         rtsp_cmd_setup(c, url, header);
2810     else if (!strcmp(cmd, "PLAY"))
2811         rtsp_cmd_play(c, url, header);
2812     else if (!strcmp(cmd, "PAUSE"))
2813         rtsp_cmd_interrupt(c, url, header, 1);
2814     else if (!strcmp(cmd, "TEARDOWN"))
2815         rtsp_cmd_interrupt(c, url, header, 0);
2816     else
2817         rtsp_reply_error(c, RTSP_STATUS_METHOD);
2818
2819  the_end:
2820     len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
2821     c->pb = NULL; /* safety */
2822     if (len < 0) {
2823         /* XXX: cannot do more */
2824         return -1;
2825     }
2826     c->buffer_ptr = c->pb_buffer;
2827     c->buffer_end = c->pb_buffer + len;
2828     c->state = RTSPSTATE_SEND_REPLY;
2829     return 0;
2830 }
2831
2832 static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
2833                                    struct in_addr my_ip)
2834 {
2835     AVFormatContext *avc;
2836     AVStream *avs = NULL;
2837     AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);
2838     AVDictionaryEntry *entry = av_dict_get(stream->metadata, "title", NULL, 0);
2839     int i;
2840
2841     *pbuffer = NULL;
2842
2843     avc =  avformat_alloc_context();
2844     if (!avc || !rtp_format) {
2845         return -1;
2846     }
2847     avc->oformat = rtp_format;
2848     av_dict_set(&avc->metadata, "title",
2849                 entry ? entry->value : "No Title", 0);
2850     avc->nb_streams = stream->nb_streams;
2851     if (stream->is_multicast) {
2852         snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
2853                  inet_ntoa(stream->multicast_ip),
2854                  stream->multicast_port, stream->multicast_ttl);
2855     } else {
2856         snprintf(avc->filename, 1024, "rtp://0.0.0.0");
2857     }
2858
2859     avc->streams = av_malloc_array(avc->nb_streams, sizeof(*avc->streams));
2860     if (!avc->streams)
2861         goto sdp_done;
2862
2863     avs = av_malloc_array(avc->nb_streams, sizeof(*avs));
2864     if (!avs)
2865         goto sdp_done;
2866
2867     for(i = 0; i < stream->nb_streams; i++) {
2868         avc->streams[i] = &avs[i];
2869         avc->streams[i]->codec = stream->streams[i]->codec;
2870     }
2871     *pbuffer = av_mallocz(2048);
2872     if (!*pbuffer)
2873         goto sdp_done;
2874     av_sdp_create(&avc, 1, *pbuffer, 2048);
2875
2876  sdp_done:
2877     av_freep(&avc->streams);
2878     av_dict_free(&avc->metadata);
2879     av_free(avc);
2880     av_free(avs);
2881
2882     return *pbuffer ? strlen(*pbuffer) : AVERROR(ENOMEM);
2883 }
2884
2885 static void rtsp_cmd_options(HTTPContext *c, const char *url)
2886 {
2887 //    rtsp_reply_header(c, RTSP_STATUS_OK);
2888     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
2889     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
2890     avio_printf(c->pb, "Public: %s\r\n",
2891                 "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
2892     avio_printf(c->pb, "\r\n");
2893 }
2894
2895 static void rtsp_cmd_describe(HTTPContext *c, const char *url)
2896 {
2897     FFServerStream *stream;
2898     char path1[1024];
2899     const char *path;
2900     uint8_t *content;
2901     int content_length;
2902     socklen_t len;
2903     struct sockaddr_in my_addr;
2904
2905     /* find which URL is asked */
2906     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
2907     path = path1;
2908     if (*path == '/')
2909         path++;
2910
2911     for(stream = config.first_stream; stream; stream = stream->next) {
2912         if (!stream->is_feed &&
2913             stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
2914             !strcmp(path, stream->filename)) {
2915             goto found;
2916         }
2917     }
2918     /* no stream found */
2919     rtsp_reply_error(c, RTSP_STATUS_NOT_FOUND);
2920     return;
2921
2922  found:
2923     /* prepare the media description in SDP format */
2924
2925     /* get the host IP */
2926     len = sizeof(my_addr);
2927     getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
2928     content_length = prepare_sdp_description(stream, &content,
2929                                              my_addr.sin_addr);
2930     if (content_length < 0) {
2931         rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
2932         return;
2933     }
2934     rtsp_reply_header(c, RTSP_STATUS_OK);
2935     avio_printf(c->pb, "Content-Base: %s/\r\n", url);
2936     avio_printf(c->pb, "Content-Type: application/sdp\r\n");
2937     avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
2938     avio_printf(c->pb, "\r\n");
2939     avio_write(c->pb, content, content_length);
2940     av_free(content);
2941 }
2942
2943 static HTTPContext *find_rtp_session(const char *session_id)
2944 {
2945     HTTPContext *c;
2946
2947     if (session_id[0] == '\0')
2948         return NULL;
2949
2950     for(c = first_http_ctx; c; c = c->next) {
2951         if (!strcmp(c->session_id, session_id))
2952             return c;
2953     }
2954     return NULL;
2955 }
2956
2957 static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
2958 {
2959     RTSPTransportField *th;
2960     int i;
2961
2962     for(i=0;i<h->nb_transports;i++) {
2963         th = &h->transports[i];
2964         if (th->lower_transport == lower_transport)
2965             return th;
2966     }
2967     return NULL;
2968 }
2969
2970 static void rtsp_cmd_setup(HTTPContext *c, const char *url,
2971                            RTSPMessageHeader *h)
2972 {
2973     FFServerStream *stream;
2974     int stream_index, rtp_port, rtcp_port;
2975     char buf[1024];
2976     char path1[1024];
2977     const char *path;
2978     HTTPContext *rtp_c;
2979     RTSPTransportField *th;
2980     struct sockaddr_in dest_addr;
2981     RTSPActionServerSetup setup;
2982
2983     /* find which URL is asked */
2984     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
2985     path = path1;
2986     if (*path == '/')
2987         path++;
2988
2989     /* now check each stream */
2990     for(stream = config.first_stream; stream; stream = stream->next) {
2991         if (stream->is_feed || !stream->fmt ||
2992             strcmp(stream->fmt->name, "rtp")) {
2993             continue;
2994         }
2995         /* accept aggregate filenames only if single stream */
2996         if (!strcmp(path, stream->filename)) {
2997             if (stream->nb_streams != 1) {
2998                 rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);
2999                 return;
3000             }
3001             stream_index = 0;
3002             goto found;
3003         }
3004
3005         for(stream_index = 0; stream_index < stream->nb_streams;
3006             stream_index++) {
3007             snprintf(buf, sizeof(buf), "%s/streamid=%d",
3008                      stream->filename, stream_index);
3009             if (!strcmp(path, buf))
3010                 goto found;
3011         }
3012     }
3013     /* no stream found */
3014     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
3015     return;
3016  found:
3017
3018     /* generate session id if needed */
3019     if (h->session_id[0] == '\0') {
3020         unsigned random0 = av_lfg_get(&random_state);
3021         unsigned random1 = av_lfg_get(&random_state);
3022         snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
3023                  random0, random1);
3024     }
3025
3026     /* find RTP session, and create it if none found */
3027     rtp_c = find_rtp_session(h->session_id);
3028     if (!rtp_c) {
3029         /* always prefer UDP */
3030         th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
3031         if (!th) {
3032             th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
3033             if (!th) {
3034                 rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3035                 return;
3036             }
3037         }
3038
3039         rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
3040                                    th->lower_transport);
3041         if (!rtp_c) {
3042             rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
3043             return;
3044         }
3045
3046         /* open input stream */
3047         if (open_input_stream(rtp_c, "") < 0) {
3048             rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
3049             return;
3050         }
3051     }
3052
3053     /* test if stream is OK (test needed because several SETUP needs
3054        to be done for a given file) */
3055     if (rtp_c->stream != stream) {
3056         rtsp_reply_error(c, RTSP_STATUS_SERVICE);
3057         return;
3058     }
3059
3060     /* test if stream is already set up */
3061     if (rtp_c->rtp_ctx[stream_index]) {
3062         rtsp_reply_error(c, RTSP_STATUS_STATE);
3063         return;
3064     }
3065
3066     /* check transport */
3067     th = find_transport(h, rtp_c->rtp_protocol);
3068     if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
3069                 th->client_port_min <= 0)) {
3070         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3071         return;
3072     }
3073
3074     /* setup default options */
3075     setup.transport_option[0] = '\0';
3076     dest_addr = rtp_c->from_addr;
3077     dest_addr.sin_port = htons(th->client_port_min);
3078
3079     /* setup stream */
3080     if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
3081         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3082         return;
3083     }
3084
3085     /* now everything is OK, so we can send the connection parameters */
3086     rtsp_reply_header(c, RTSP_STATUS_OK);
3087     /* session ID */
3088     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3089
3090     switch(rtp_c->rtp_protocol) {
3091     case RTSP_LOWER_TRANSPORT_UDP:
3092         rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
3093         rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
3094         avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
3095                     "client_port=%d-%d;server_port=%d-%d",
3096                     th->client_port_min, th->client_port_max,
3097                     rtp_port, rtcp_port);
3098         break;
3099     case RTSP_LOWER_TRANSPORT_TCP:
3100         avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
3101                     stream_index * 2, stream_index * 2 + 1);
3102         break;
3103     default:
3104         break;
3105     }
3106     if (setup.transport_option[0] != '\0')
3107         avio_printf(c->pb, ";%s", setup.transport_option);
3108     avio_printf(c->pb, "\r\n");
3109
3110
3111     avio_printf(c->pb, "\r\n");
3112 }
3113
3114
3115 /* find an RTP connection by using the session ID. Check consistency
3116    with filename */
3117 static HTTPContext *find_rtp_session_with_url(const char *url,
3118                                               const char *session_id)
3119 {
3120     HTTPContext *rtp_c;
3121     char path1[1024];
3122     const char *path;
3123     char buf[1024];
3124     int s, len;
3125
3126     rtp_c = find_rtp_session(session_id);
3127     if (!rtp_c)
3128         return NULL;
3129
3130     /* find which URL is asked */
3131     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3132     path = path1;
3133     if (*path == '/')
3134         path++;
3135     if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
3136     for(s=0; s<rtp_c->stream->nb_streams; ++s) {
3137       snprintf(buf, sizeof(buf), "%s/streamid=%d",
3138         rtp_c->stream->filename, s);
3139       if(!strncmp(path, buf, sizeof(buf))) {
3140     // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
3141         return rtp_c;
3142       }
3143     }
3144     len = strlen(path);
3145     if (len > 0 && path[len - 1] == '/' &&
3146         !strncmp(path, rtp_c->stream->filename, len - 1))
3147         return rtp_c;
3148     return NULL;
3149 }
3150
3151 static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3152 {
3153     HTTPContext *rtp_c;
3154
3155     rtp_c = find_rtp_session_with_url(url, h->session_id);
3156     if (!rtp_c) {
3157         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3158         return;
3159     }
3160
3161     if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3162         rtp_c->state != HTTPSTATE_WAIT_FEED &&
3163         rtp_c->state != HTTPSTATE_READY) {
3164         rtsp_reply_error(c, RTSP_STATUS_STATE);
3165         return;
3166     }
3167
3168     rtp_c->state = HTTPSTATE_SEND_DATA;
3169
3170     /* now everything is OK, so we can send the connection parameters */
3171     rtsp_reply_header(c, RTSP_STATUS_OK);
3172     /* session ID */
3173     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3174     avio_printf(c->pb, "\r\n");
3175 }
3176
3177 static void rtsp_cmd_interrupt(HTTPContext *c, const char *url,
3178                                RTSPMessageHeader *h, int pause_only)
3179 {
3180     HTTPContext *rtp_c;
3181
3182     rtp_c = find_rtp_session_with_url(url, h->session_id);
3183     if (!rtp_c) {
3184         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3185         return;
3186     }
3187
3188     if (pause_only) {
3189         if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3190             rtp_c->state != HTTPSTATE_WAIT_FEED) {
3191             rtsp_reply_error(c, RTSP_STATUS_STATE);
3192             return;
3193         }
3194         rtp_c->state = HTTPSTATE_READY;
3195         rtp_c->first_pts = AV_NOPTS_VALUE;
3196     }
3197
3198     /* now everything is OK, so we can send the connection parameters */
3199     rtsp_reply_header(c, RTSP_STATUS_OK);
3200     /* session ID */
3201     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3202     avio_printf(c->pb, "\r\n");
3203
3204     if (!pause_only)
3205         close_connection(rtp_c);
3206 }
3207
3208 /********************************************************************/
3209 /* RTP handling */
3210
3211 static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
3212                                        FFServerStream *stream,
3213                                        const char *session_id,
3214                                        enum RTSPLowerTransport rtp_protocol)
3215 {
3216     HTTPContext *c = NULL;
3217     const char *proto_str;
3218
3219     /* XXX: should output a warning page when coming
3220        close to the connection limit */
3221     if (nb_connections >= config.nb_max_connections)
3222         goto fail;
3223
3224     /* add a new connection */
3225     c = av_mallocz(sizeof(HTTPContext));
3226     if (!c)
3227         goto fail;
3228
3229     c->fd = -1;
3230     c->poll_entry = NULL;
3231     c->from_addr = *from_addr;
3232     c->buffer_size = IOBUFFER_INIT_SIZE;
3233     c->buffer = av_malloc(c->buffer_size);
3234     if (!c->buffer)
3235         goto fail;
3236     nb_connections++;
3237     c->stream = stream;
3238     av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
3239     c->state = HTTPSTATE_READY;
3240     c->is_packetized = 1;
3241     c->rtp_protocol = rtp_protocol;
3242
3243     /* protocol is shown in statistics */
3244     switch(c->rtp_protocol) {
3245     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3246         proto_str = "MCAST";
3247         break;
3248     case RTSP_LOWER_TRANSPORT_UDP:
3249         proto_str = "UDP";
3250         break;
3251     case RTSP_LOWER_TRANSPORT_TCP:
3252         proto_str = "TCP";
3253         break;
3254     default:
3255         proto_str = "???";
3256         break;
3257     }
3258     av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
3259     av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
3260
3261     current_bandwidth += stream->bandwidth;
3262
3263     c->next = first_http_ctx;
3264     first_http_ctx = c;
3265     return c;
3266
3267  fail:
3268     if (c) {
3269         av_freep(&c->buffer);
3270         av_free(c);
3271     }
3272     return NULL;
3273 }
3274
3275 /* add a new RTP stream in an RTP connection (used in RTSP SETUP
3276    command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
3277    used. */
3278 static int rtp_new_av_stream(HTTPContext *c,
3279                              int stream_index, struct sockaddr_in *dest_addr,
3280                              HTTPContext *rtsp_c)
3281 {
3282     AVFormatContext *ctx;
3283     AVStream *st;
3284     char *ipaddr;
3285     URLContext *h = NULL;
3286     uint8_t *dummy_buf;
3287     int max_packet_size;
3288
3289     /* now we can open the relevant output stream */
3290     ctx = avformat_alloc_context();
3291     if (!ctx)
3292         return -1;
3293     ctx->oformat = av_guess_format("rtp", NULL, NULL);
3294
3295     st = av_mallocz(sizeof(AVStream));
3296     if (!st)
3297         goto fail;
3298     ctx->nb_streams = 1;
3299     ctx->streams = av_mallocz_array(ctx->nb_streams, sizeof(AVStream *));
3300     if (!ctx->streams)
3301       goto fail;
3302     ctx->streams[0] = st;
3303
3304     if (!c->stream->feed ||
3305         c->stream->feed == c->stream)
3306         memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
3307     else
3308         memcpy(st,
3309                c->stream->feed->streams[c->stream->feed_streams[stream_index]],
3310                sizeof(AVStream));
3311     st->priv_data = NULL;
3312
3313     /* build destination RTP address */
3314     ipaddr = inet_ntoa(dest_addr->sin_addr);
3315
3316     switch(c->rtp_protocol) {
3317     case RTSP_LOWER_TRANSPORT_UDP:
3318     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3319         /* RTP/UDP case */
3320
3321         /* XXX: also pass as parameter to function ? */
3322         if (c->stream->is_multicast) {
3323             int ttl;
3324             ttl = c->stream->multicast_ttl;
3325             if (!ttl)
3326                 ttl = 16;
3327             snprintf(ctx->filename, sizeof(ctx->filename),
3328                      "rtp://%s:%d?multicast=1&ttl=%d",
3329                      ipaddr, ntohs(dest_addr->sin_port), ttl);
3330         } else {
3331             snprintf(ctx->filename, sizeof(ctx->filename),
3332                      "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
3333         }
3334
3335         if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
3336             goto fail;
3337         c->rtp_handles[stream_index] = h;
3338         max_packet_size = h->max_packet_size;
3339         break;
3340     case RTSP_LOWER_TRANSPORT_TCP:
3341         /* RTP/TCP case */
3342         c->rtsp_c = rtsp_c;
3343         max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
3344         break;
3345     default:
3346         goto fail;
3347     }
3348
3349     http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
3350              ipaddr, ntohs(dest_addr->sin_port),
3351              c->stream->filename, stream_index, c->protocol);
3352
3353     /* normally, no packets should be output here, but the packet size may
3354      * be checked */
3355     if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
3356         /* XXX: close stream */
3357         goto fail;
3358     }
3359     if (avformat_write_header(ctx, NULL) < 0) {
3360     fail:
3361         if (h)
3362             ffurl_close(h);
3363         av_free(st);
3364         av_free(ctx);
3365         return -1;
3366     }
3367     avio_close_dyn_buf(ctx->pb, &dummy_buf);
3368     av_free(dummy_buf);
3369
3370     c->rtp_ctx[stream_index] = ctx;
3371     return 0;
3372 }
3373
3374 /********************************************************************/
3375 /* ffserver initialization */
3376
3377 static AVStream *add_av_stream1(FFServerStream *stream,
3378                                 AVCodecContext *codec, int copy)
3379 {
3380     AVStream *fst;
3381
3382     if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
3383         return NULL;
3384
3385     fst = av_mallocz(sizeof(AVStream));
3386     if (!fst)
3387         return NULL;
3388     if (copy) {
3389         fst->codec = avcodec_alloc_context3(codec->codec);
3390         if (!fst->codec) {
3391             av_free(fst);
3392             return NULL;
3393         }
3394         avcodec_copy_context(fst->codec, codec);
3395     } else {
3396         /* live streams must use the actual feed's codec since it may be
3397          * updated later to carry extradata needed by them.
3398          */
3399         fst->codec = codec;
3400     }
3401     fst->priv_data = av_mallocz(sizeof(FeedData));
3402     fst->index = stream->nb_streams;
3403     avpriv_set_pts_info(fst, 33, 1, 90000);
3404     fst->sample_aspect_ratio = codec->sample_aspect_ratio;
3405     stream->streams[stream->nb_streams++] = fst;
3406     return fst;
3407 }
3408
3409 /* return the stream number in the feed */
3410 static int add_av_stream(FFServerStream *feed, AVStream *st)
3411 {
3412     AVStream *fst;
3413     AVCodecContext *av, *av1;
3414     int i;
3415
3416     av = st->codec;
3417     for(i=0;i<feed->nb_streams;i++) {
3418         av1 = feed->streams[i]->codec;
3419         if (av1->codec_id == av->codec_id &&
3420             av1->codec_type == av->codec_type &&
3421             av1->bit_rate == av->bit_rate) {
3422
3423             switch(av->codec_type) {
3424             case AVMEDIA_TYPE_AUDIO:
3425                 if (av1->channels == av->channels &&
3426                     av1->sample_rate == av->sample_rate)
3427                     return i;
3428                 break;
3429             case AVMEDIA_TYPE_VIDEO:
3430                 if (av1->width == av->width &&
3431                     av1->height == av->height &&
3432                     av1->time_base.den == av->time_base.den &&
3433                     av1->time_base.num == av->time_base.num &&
3434                     av1->gop_size == av->gop_size)
3435                     return i;
3436                 break;
3437             default:
3438                 abort();
3439             }
3440         }
3441     }
3442
3443     fst = add_av_stream1(feed, av, 0);
3444     if (!fst)
3445         return -1;
3446     if (av_stream_get_recommended_encoder_configuration(st))
3447         av_stream_set_recommended_encoder_configuration(fst,
3448             av_strdup(av_stream_get_recommended_encoder_configuration(st)));
3449     return feed->nb_streams - 1;
3450 }
3451
3452 static void remove_stream(FFServerStream *stream)
3453 {
3454     FFServerStream **ps;
3455     ps = &config.first_stream;
3456     while (*ps) {
3457         if (*ps == stream)
3458             *ps = (*ps)->next;
3459         else
3460             ps = &(*ps)->next;
3461     }
3462 }
3463
3464 /* specific MPEG4 handling : we extract the raw parameters */
3465 static void extract_mpeg4_header(AVFormatContext *infile)
3466 {
3467     int mpeg4_count, i, size;
3468     AVPacket pkt;
3469     AVStream *st;
3470     const uint8_t *p;
3471
3472     infile->flags |= AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE;
3473
3474     mpeg4_count = 0;
3475     for(i=0;i<infile->nb_streams;i++) {
3476         st = infile->streams[i];
3477         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3478             st->codec->extradata_size == 0) {
3479             mpeg4_count++;
3480         }
3481     }
3482     if (!mpeg4_count)
3483         return;
3484
3485     printf("MPEG4 without extra data: trying to find header in %s\n",
3486            infile->filename);
3487     while (mpeg4_count > 0) {
3488         if (av_read_frame(infile, &pkt) < 0)
3489             break;
3490         st = infile->streams[pkt.stream_index];
3491         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3492             st->codec->extradata_size == 0) {
3493             av_freep(&st->codec->extradata);
3494             /* fill extradata with the header */
3495             /* XXX: we make hard suppositions here ! */
3496             p = pkt.data;
3497             while (p < pkt.data + pkt.size - 4) {
3498                 /* stop when vop header is found */
3499                 if (p[0] == 0x00 && p[1] == 0x00 &&
3500                     p[2] == 0x01 && p[3] == 0xb6) {
3501                     size = p - pkt.data;
3502                     st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
3503                     st->codec->extradata_size = size;
3504                     memcpy(st->codec->extradata, pkt.data, size);
3505                     break;
3506                 }
3507                 p++;
3508             }
3509             mpeg4_count--;
3510         }
3511         av_free_packet(&pkt);
3512     }
3513 }
3514
3515 /* compute the needed AVStream for each file */
3516 static void build_file_streams(void)
3517 {
3518     FFServerStream *stream, *stream_next;
3519     int i, ret;
3520
3521     /* gather all streams */
3522     for(stream = config.first_stream; stream; stream = stream_next) {
3523         AVFormatContext *infile = NULL;
3524         stream_next = stream->next;
3525         if (stream->stream_type == STREAM_TYPE_LIVE &&
3526             !stream->feed) {
3527             /* the stream comes from a file */
3528             /* try to open the file */
3529             /* open stream */
3530             if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
3531                 /* specific case : if transport stream output to RTP,
3532                    we use a raw transport stream reader */
3533                 av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
3534             }
3535
3536             if (!stream->feed_filename[0]) {
3537                 http_log("Unspecified feed file for stream '%s'\n",
3538                          stream->filename);
3539                 goto fail;
3540             }
3541
3542             http_log("Opening feed file '%s' for stream '%s'\n",
3543                      stream->feed_filename, stream->filename);
3544             ret = avformat_open_input(&infile, stream->feed_filename,
3545                                       stream->ifmt, &stream->in_opts);
3546             if (ret < 0) {
3547                 http_log("Could not open '%s': %s\n", stream->feed_filename,
3548                          av_err2str(ret));
3549                 /* remove stream (no need to spend more time on it) */
3550             fail:
3551                 remove_stream(stream);
3552             } else {
3553                 /* find all the AVStreams inside and reference them in
3554                    'stream' */
3555                 if (avformat_find_stream_info(infile, NULL) < 0) {
3556                     http_log("Could not find codec parameters from '%s'\n",
3557                              stream->feed_filename);
3558                     avformat_close_input(&infile);
3559                     goto fail;
3560                 }
3561                 extract_mpeg4_header(infile);
3562
3563                 for(i=0;i<infile->nb_streams;i++)
3564                     add_av_stream1(stream, infile->streams[i]->codec, 1);
3565
3566                 avformat_close_input(&infile);
3567             }
3568         }
3569     }
3570 }
3571
3572 /* compute the needed AVStream for each feed */
3573 static void build_feed_streams(void)
3574 {
3575     FFServerStream *stream, *feed;
3576     int i;
3577
3578     /* gather all streams */
3579     for(stream = config.first_stream; stream; stream = stream->next) {
3580         feed = stream->feed;
3581         if (feed) {
3582             if (stream->is_feed) {
3583                 for(i=0;i<stream->nb_streams;i++)
3584                     stream->feed_streams[i] = i;
3585             } else {
3586                 /* we handle a stream coming from a feed */
3587                 for(i=0;i<stream->nb_streams;i++)
3588                     stream->feed_streams[i] = add_av_stream(feed,
3589                                                             stream->streams[i]);
3590             }
3591         }
3592     }
3593
3594     /* create feed files if needed */
3595     for(feed = config.first_feed; feed; feed = feed->next_feed) {
3596         int fd;
3597
3598         if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
3599             /* See if it matches */
3600             AVFormatContext *s = NULL;
3601             int matches = 0;
3602
3603             if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
3604                 /* set buffer size */
3605                 int ret = ffio_set_buf_size(s->pb, FFM_PACKET_SIZE);
3606                 if (ret < 0) {
3607                     http_log("Failed to set buffer size\n");
3608                     exit(1);
3609                 }
3610
3611                 /* Now see if it matches */
3612                 if (s->nb_streams == feed->nb_streams) {
3613                     matches = 1;
3614                     for(i=0;i<s->nb_streams;i++) {
3615                         AVStream *sf, *ss;
3616                         sf = feed->streams[i];
3617                         ss = s->streams[i];
3618
3619                         if (sf->index != ss->index ||
3620                             sf->id != ss->id) {
3621                             http_log("Index & Id do not match for stream %d (%s)\n",
3622                                    i, feed->feed_filename);
3623                             matches = 0;
3624                         } else {
3625                             AVCodecContext *ccf, *ccs;
3626
3627                             ccf = sf->codec;
3628                             ccs = ss->codec;
3629 #define CHECK_CODEC(x)  (ccf->x != ccs->x)
3630
3631                             if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
3632                                 http_log("Codecs do not match for stream %d\n", i);
3633                                 matches = 0;
3634                             } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
3635                                 http_log("Codec bitrates do not match for stream %d\n", i);
3636                                 matches = 0;
3637                             } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {
3638                                 if (CHECK_CODEC(time_base.den) ||
3639                                     CHECK_CODEC(time_base.num) ||
3640                                     CHECK_CODEC(width) ||
3641                                     CHECK_CODEC(height)) {
3642                                     http_log("Codec width, height and framerate do not match for stream %d\n", i);
3643                                     matches = 0;
3644                                 }
3645                             } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {
3646                                 if (CHECK_CODEC(sample_rate) ||
3647                                     CHECK_CODEC(channels) ||
3648                                     CHECK_CODEC(frame_size)) {
3649                                     http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);
3650                                     matches = 0;
3651                                 }
3652                             } else {
3653                                 http_log("Unknown codec type\n");
3654                                 matches = 0;
3655                             }
3656                         }
3657                         if (!matches)
3658                             break;
3659                     }
3660                 } else
3661                     http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",
3662                         feed->feed_filename, s->nb_streams, feed->nb_streams);
3663
3664                 avformat_close_input(&s);
3665             } else
3666                 http_log("Deleting feed file '%s' as it appears to be corrupt\n",
3667