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