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