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