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