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