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