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