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