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