]> git.sesse.net Git - ffmpeg/blob - ffserver.c
Merge commit '1d8aa23794cc63e9517d5055a2d48040b843b1cf'
[ffmpeg] / ffserver.c
1 /*
2  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * multiple format streaming server based on the FFmpeg libraries
24  */
25
26 #include "config.h"
27 #if !HAVE_CLOSESOCKET
28 #define closesocket close
29 #endif
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include "libavformat/avformat.h"
34 // FIXME those are internal headers, ffserver _really_ shouldn't use them
35 #include "libavformat/ffm.h"
36 #include "libavformat/network.h"
37 #include "libavformat/os_support.h"
38 #include "libavformat/rtpdec.h"
39 #include "libavformat/rtpproto.h"
40 #include "libavformat/rtsp.h"
41 #include "libavformat/rtspcodes.h"
42 #include "libavformat/avio_internal.h"
43 #include "libavformat/internal.h"
44 #include "libavformat/url.h"
45
46 #include "libavutil/avassert.h"
47 #include "libavutil/avstring.h"
48 #include "libavutil/lfg.h"
49 #include "libavutil/dict.h"
50 #include "libavutil/intreadwrite.h"
51 #include "libavutil/mathematics.h"
52 #include "libavutil/random_seed.h"
53 #include "libavutil/parseutils.h"
54 #include "libavutil/opt.h"
55 #include "libavutil/time.h"
56
57 #include <stdarg.h>
58 #if HAVE_UNISTD_H
59 #include <unistd.h>
60 #endif
61 #include <fcntl.h>
62 #include <sys/ioctl.h>
63 #if HAVE_POLL_H
64 #include <poll.h>
65 #endif
66 #include <errno.h>
67 #include <time.h>
68 #include <sys/wait.h>
69 #include <signal.h>
70
71 #include "cmdutils.h"
72 #include "ffserver_config.h"
73
74 const char program_name[] = "ffserver";
75 const int program_birth_year = 2000;
76
77 static const OptionDef options[];
78
79 enum HTTPState {
80     HTTPSTATE_WAIT_REQUEST,
81     HTTPSTATE_SEND_HEADER,
82     HTTPSTATE_SEND_DATA_HEADER,
83     HTTPSTATE_SEND_DATA,          /* sending TCP or UDP data */
84     HTTPSTATE_SEND_DATA_TRAILER,
85     HTTPSTATE_RECEIVE_DATA,
86     HTTPSTATE_WAIT_FEED,          /* wait for data from the feed */
87     HTTPSTATE_READY,
88
89     RTSPSTATE_WAIT_REQUEST,
90     RTSPSTATE_SEND_REPLY,
91     RTSPSTATE_SEND_PACKET,
92 };
93
94 static const char * const http_state[] = {
95     "HTTP_WAIT_REQUEST",
96     "HTTP_SEND_HEADER",
97
98     "SEND_DATA_HEADER",
99     "SEND_DATA",
100     "SEND_DATA_TRAILER",
101     "RECEIVE_DATA",
102     "WAIT_FEED",
103     "READY",
104
105     "RTSP_WAIT_REQUEST",
106     "RTSP_SEND_REPLY",
107     "RTSP_SEND_PACKET",
108 };
109
110 #define IOBUFFER_INIT_SIZE 8192
111
112 /* timeouts are in ms */
113 #define HTTP_REQUEST_TIMEOUT (15 * 1000)
114 #define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000)
115
116 #define SYNC_TIMEOUT (10 * 1000)
117
118 typedef struct RTSPActionServerSetup {
119     uint32_t ipaddr;
120     char transport_option[512];
121 } RTSPActionServerSetup;
122
123 typedef struct {
124     int64_t count1, count2;
125     int64_t time1, time2;
126 } DataRateData;
127
128 /* context associated with one connection */
129 typedef struct HTTPContext {
130     enum HTTPState state;
131     int fd; /* socket file descriptor */
132     struct sockaddr_in from_addr; /* origin */
133     struct pollfd *poll_entry; /* used when polling */
134     int64_t timeout;
135     uint8_t *buffer_ptr, *buffer_end;
136     int http_error;
137     int post;
138     int chunked_encoding;
139     int chunk_size;               /* 0 if it needs to be read */
140     struct HTTPContext *next;
141     int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
142     int64_t data_count;
143     /* feed input */
144     int feed_fd;
145     /* input format handling */
146     AVFormatContext *fmt_in;
147     int64_t start_time;            /* In milliseconds - this wraps fairly often */
148     int64_t first_pts;            /* initial pts value */
149     int64_t cur_pts;             /* current pts value from the stream in us */
150     int64_t cur_frame_duration;  /* duration of the current frame in us */
151     int cur_frame_bytes;       /* output frame size, needed to compute
152                                   the time at which we send each
153                                   packet */
154     int pts_stream_index;        /* stream we choose as clock reference */
155     int64_t cur_clock;           /* current clock reference value in us */
156     /* output format handling */
157     struct FFServerStream *stream;
158     /* -1 is invalid stream */
159     int feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
160     int switch_feed_streams[FFSERVER_MAX_STREAMS]; /* index of streams in the feed */
161     int switch_pending;
162     AVFormatContext fmt_ctx; /* instance of FFServerStream for one user */
163     int last_packet_sent; /* true if last data packet was sent */
164     int suppress_log;
165     DataRateData datarate;
166     int wmp_client_id;
167     char protocol[16];
168     char method[16];
169     char url[128];
170     int buffer_size;
171     uint8_t *buffer;
172     int is_packetized; /* if true, the stream is packetized */
173     int packet_stream_index; /* current stream for output in state machine */
174
175     /* RTSP state specific */
176     uint8_t *pb_buffer; /* XXX: use that in all the code */
177     AVIOContext *pb;
178     int seq; /* RTSP sequence number */
179
180     /* RTP state specific */
181     enum RTSPLowerTransport rtp_protocol;
182     char session_id[32]; /* session id */
183     AVFormatContext *rtp_ctx[FFSERVER_MAX_STREAMS];
184
185     /* RTP/UDP specific */
186     URLContext *rtp_handles[FFSERVER_MAX_STREAMS];
187
188     /* RTP/TCP specific */
189     struct HTTPContext *rtsp_c;
190     uint8_t *packet_buffer, *packet_buffer_ptr, *packet_buffer_end;
191 } HTTPContext;
192
193 typedef struct FeedData {
194     long long data_count;
195     float avg_frame_size;   /* frame size averaged over last frames with exponential mean */
196 } FeedData;
197
198 static HTTPContext *first_http_ctx;
199
200 static FFServerConfig config = {
201     .nb_max_http_connections = 2000,
202     .nb_max_connections = 5,
203     .max_bandwidth = 1000,
204     .use_defaults = 1,
205 };
206
207 static void new_connection(int server_fd, int is_rtsp);
208 static void close_connection(HTTPContext *c);
209
210 /* HTTP handling */
211 static int handle_connection(HTTPContext *c);
212 static int http_parse_request(HTTPContext *c);
213 static int http_send_data(HTTPContext *c);
214 static void compute_status(HTTPContext *c);
215 static int open_input_stream(HTTPContext *c, const char *info);
216 static int http_start_receive_data(HTTPContext *c);
217 static int http_receive_data(HTTPContext *c);
218
219 /* RTSP handling */
220 static int rtsp_parse_request(HTTPContext *c);
221 static void rtsp_cmd_describe(HTTPContext *c, const char *url);
222 static void rtsp_cmd_options(HTTPContext *c, const char *url);
223 static void rtsp_cmd_setup(HTTPContext *c, const char *url,
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                 }
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->streams = av_malloc_array(avc->nb_streams, sizeof(*avc->streams))))
2814         goto sdp_done;
2815     if (!(avs = av_malloc_array(avc->nb_streams, sizeof(*avs))))
2816         goto sdp_done;
2817
2818     for(i = 0; i < stream->nb_streams; i++) {
2819         avc->streams[i] = &avs[i];
2820         avc->streams[i]->codec = stream->streams[i]->codec;
2821     }
2822     *pbuffer = av_mallocz(2048);
2823     av_sdp_create(&avc, 1, *pbuffer, 2048);
2824
2825  sdp_done:
2826     av_freep(&avc->streams);
2827     av_dict_free(&avc->metadata);
2828     av_free(avc);
2829     av_free(avs);
2830
2831     return *pbuffer ? strlen(*pbuffer) : AVERROR(ENOMEM);
2832 }
2833
2834 static void rtsp_cmd_options(HTTPContext *c, const char *url)
2835 {
2836 //    rtsp_reply_header(c, RTSP_STATUS_OK);
2837     avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
2838     avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
2839     avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
2840     avio_printf(c->pb, "\r\n");
2841 }
2842
2843 static void rtsp_cmd_describe(HTTPContext *c, const char *url)
2844 {
2845     FFServerStream *stream;
2846     char path1[1024];
2847     const char *path;
2848     uint8_t *content;
2849     int content_length;
2850     socklen_t len;
2851     struct sockaddr_in my_addr;
2852
2853     /* find which URL is asked */
2854     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
2855     path = path1;
2856     if (*path == '/')
2857         path++;
2858
2859     for(stream = config.first_stream; stream; stream = stream->next) {
2860         if (!stream->is_feed &&
2861             stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
2862             !strcmp(path, stream->filename)) {
2863             goto found;
2864         }
2865     }
2866     /* no stream found */
2867     rtsp_reply_error(c, RTSP_STATUS_NOT_FOUND);
2868     return;
2869
2870  found:
2871     /* prepare the media description in SDP format */
2872
2873     /* get the host IP */
2874     len = sizeof(my_addr);
2875     getsockname(c->fd, (struct sockaddr *)&my_addr, &len);
2876     content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);
2877     if (content_length < 0) {
2878         rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
2879         return;
2880     }
2881     rtsp_reply_header(c, RTSP_STATUS_OK);
2882     avio_printf(c->pb, "Content-Base: %s/\r\n", url);
2883     avio_printf(c->pb, "Content-Type: application/sdp\r\n");
2884     avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
2885     avio_printf(c->pb, "\r\n");
2886     avio_write(c->pb, content, content_length);
2887     av_free(content);
2888 }
2889
2890 static HTTPContext *find_rtp_session(const char *session_id)
2891 {
2892     HTTPContext *c;
2893
2894     if (session_id[0] == '\0')
2895         return NULL;
2896
2897     for(c = first_http_ctx; c; c = c->next) {
2898         if (!strcmp(c->session_id, session_id))
2899             return c;
2900     }
2901     return NULL;
2902 }
2903
2904 static RTSPTransportField *find_transport(RTSPMessageHeader *h, enum RTSPLowerTransport lower_transport)
2905 {
2906     RTSPTransportField *th;
2907     int i;
2908
2909     for(i=0;i<h->nb_transports;i++) {
2910         th = &h->transports[i];
2911         if (th->lower_transport == lower_transport)
2912             return th;
2913     }
2914     return NULL;
2915 }
2916
2917 static void rtsp_cmd_setup(HTTPContext *c, const char *url,
2918                            RTSPMessageHeader *h)
2919 {
2920     FFServerStream *stream;
2921     int stream_index, rtp_port, rtcp_port;
2922     char buf[1024];
2923     char path1[1024];
2924     const char *path;
2925     HTTPContext *rtp_c;
2926     RTSPTransportField *th;
2927     struct sockaddr_in dest_addr;
2928     RTSPActionServerSetup setup;
2929
2930     /* find which URL is asked */
2931     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
2932     path = path1;
2933     if (*path == '/')
2934         path++;
2935
2936     /* now check each stream */
2937     for(stream = config.first_stream; stream; stream = stream->next) {
2938         if (stream->is_feed || !stream->fmt ||
2939             strcmp(stream->fmt->name, "rtp")) {
2940             continue;
2941         }
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     /* no stream found */
2961     rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */
2962     return;
2963  found:
2964
2965     /* generate session id if needed */
2966     if (h->session_id[0] == '\0') {
2967         unsigned random0 = av_lfg_get(&random_state);
2968         unsigned random1 = av_lfg_get(&random_state);
2969         snprintf(h->session_id, sizeof(h->session_id), "%08x%08x",
2970                  random0, random1);
2971     }
2972
2973     /* find RTP session, and create it if none found */
2974     rtp_c = find_rtp_session(h->session_id);
2975     if (!rtp_c) {
2976         /* always prefer UDP */
2977         th = find_transport(h, RTSP_LOWER_TRANSPORT_UDP);
2978         if (!th) {
2979             th = find_transport(h, RTSP_LOWER_TRANSPORT_TCP);
2980             if (!th) {
2981                 rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
2982                 return;
2983             }
2984         }
2985
2986         rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,
2987                                    th->lower_transport);
2988         if (!rtp_c) {
2989             rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);
2990             return;
2991         }
2992
2993         /* open input stream */
2994         if (open_input_stream(rtp_c, "") < 0) {
2995             rtsp_reply_error(c, RTSP_STATUS_INTERNAL);
2996             return;
2997         }
2998     }
2999
3000     /* test if stream is OK (test needed because several SETUP needs
3001        to be done for a given file) */
3002     if (rtp_c->stream != stream) {
3003         rtsp_reply_error(c, RTSP_STATUS_SERVICE);
3004         return;
3005     }
3006
3007     /* test if stream is already set up */
3008     if (rtp_c->rtp_ctx[stream_index]) {
3009         rtsp_reply_error(c, RTSP_STATUS_STATE);
3010         return;
3011     }
3012
3013     /* check transport */
3014     th = find_transport(h, rtp_c->rtp_protocol);
3015     if (!th || (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
3016                 th->client_port_min <= 0)) {
3017         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3018         return;
3019     }
3020
3021     /* setup default options */
3022     setup.transport_option[0] = '\0';
3023     dest_addr = rtp_c->from_addr;
3024     dest_addr.sin_port = htons(th->client_port_min);
3025
3026     /* setup stream */
3027     if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {
3028         rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);
3029         return;
3030     }
3031
3032     /* now everything is OK, so we can send the connection parameters */
3033     rtsp_reply_header(c, RTSP_STATUS_OK);
3034     /* session ID */
3035     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3036
3037     switch(rtp_c->rtp_protocol) {
3038     case RTSP_LOWER_TRANSPORT_UDP:
3039         rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
3040         rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
3041         avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
3042                     "client_port=%d-%d;server_port=%d-%d",
3043                     th->client_port_min, th->client_port_max,
3044                     rtp_port, rtcp_port);
3045         break;
3046     case RTSP_LOWER_TRANSPORT_TCP:
3047         avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
3048                     stream_index * 2, stream_index * 2 + 1);
3049         break;
3050     default:
3051         break;
3052     }
3053     if (setup.transport_option[0] != '\0')
3054         avio_printf(c->pb, ";%s", setup.transport_option);
3055     avio_printf(c->pb, "\r\n");
3056
3057
3058     avio_printf(c->pb, "\r\n");
3059 }
3060
3061
3062 /* find an RTP connection by using the session ID. Check consistency
3063    with filename */
3064 static HTTPContext *find_rtp_session_with_url(const char *url,
3065                                               const char *session_id)
3066 {
3067     HTTPContext *rtp_c;
3068     char path1[1024];
3069     const char *path;
3070     char buf[1024];
3071     int s, len;
3072
3073     rtp_c = find_rtp_session(session_id);
3074     if (!rtp_c)
3075         return NULL;
3076
3077     /* find which URL is asked */
3078     av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
3079     path = path1;
3080     if (*path == '/')
3081         path++;
3082     if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
3083     for(s=0; s<rtp_c->stream->nb_streams; ++s) {
3084       snprintf(buf, sizeof(buf), "%s/streamid=%d",
3085         rtp_c->stream->filename, s);
3086       if(!strncmp(path, buf, sizeof(buf))) {
3087     // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
3088         return rtp_c;
3089       }
3090     }
3091     len = strlen(path);
3092     if (len > 0 && path[len - 1] == '/' &&
3093         !strncmp(path, rtp_c->stream->filename, len - 1))
3094         return rtp_c;
3095     return NULL;
3096 }
3097
3098 static void rtsp_cmd_play(HTTPContext *c, const char *url, RTSPMessageHeader *h)
3099 {
3100     HTTPContext *rtp_c;
3101
3102     rtp_c = find_rtp_session_with_url(url, h->session_id);
3103     if (!rtp_c) {
3104         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3105         return;
3106     }
3107
3108     if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3109         rtp_c->state != HTTPSTATE_WAIT_FEED &&
3110         rtp_c->state != HTTPSTATE_READY) {
3111         rtsp_reply_error(c, RTSP_STATUS_STATE);
3112         return;
3113     }
3114
3115     rtp_c->state = HTTPSTATE_SEND_DATA;
3116
3117     /* now everything is OK, so we can send the connection parameters */
3118     rtsp_reply_header(c, RTSP_STATUS_OK);
3119     /* session ID */
3120     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3121     avio_printf(c->pb, "\r\n");
3122 }
3123
3124 static void rtsp_cmd_interrupt(HTTPContext *c, const char *url, RTSPMessageHeader *h, int pause_only)
3125 {
3126     HTTPContext *rtp_c;
3127
3128     rtp_c = find_rtp_session_with_url(url, h->session_id);
3129     if (!rtp_c) {
3130         rtsp_reply_error(c, RTSP_STATUS_SESSION);
3131         return;
3132     }
3133
3134     if (pause_only) {
3135         if (rtp_c->state != HTTPSTATE_SEND_DATA &&
3136             rtp_c->state != HTTPSTATE_WAIT_FEED) {
3137             rtsp_reply_error(c, RTSP_STATUS_STATE);
3138             return;
3139         }
3140         rtp_c->state = HTTPSTATE_READY;
3141         rtp_c->first_pts = AV_NOPTS_VALUE;
3142     }
3143
3144     /* now everything is OK, so we can send the connection parameters */
3145     rtsp_reply_header(c, RTSP_STATUS_OK);
3146     /* session ID */
3147     avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
3148     avio_printf(c->pb, "\r\n");
3149
3150     if (!pause_only)
3151         close_connection(rtp_c);
3152 }
3153
3154 /********************************************************************/
3155 /* RTP handling */
3156
3157 static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
3158                                        FFServerStream *stream, const char *session_id,
3159                                        enum RTSPLowerTransport rtp_protocol)
3160 {
3161     HTTPContext *c = NULL;
3162     const char *proto_str;
3163
3164     /* XXX: should output a warning page when coming
3165        close to the connection limit */
3166     if (nb_connections >= config.nb_max_connections)
3167         goto fail;
3168
3169     /* add a new connection */
3170     c = av_mallocz(sizeof(HTTPContext));
3171     if (!c)
3172         goto fail;
3173
3174     c->fd = -1;
3175     c->poll_entry = NULL;
3176     c->from_addr = *from_addr;
3177     c->buffer_size = IOBUFFER_INIT_SIZE;
3178     c->buffer = av_malloc(c->buffer_size);
3179     if (!c->buffer)
3180         goto fail;
3181     nb_connections++;
3182     c->stream = stream;
3183     av_strlcpy(c->session_id, session_id, sizeof(c->session_id));
3184     c->state = HTTPSTATE_READY;
3185     c->is_packetized = 1;
3186     c->rtp_protocol = rtp_protocol;
3187
3188     /* protocol is shown in statistics */
3189     switch(c->rtp_protocol) {
3190     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3191         proto_str = "MCAST";
3192         break;
3193     case RTSP_LOWER_TRANSPORT_UDP:
3194         proto_str = "UDP";
3195         break;
3196     case RTSP_LOWER_TRANSPORT_TCP:
3197         proto_str = "TCP";
3198         break;
3199     default:
3200         proto_str = "???";
3201         break;
3202     }
3203     av_strlcpy(c->protocol, "RTP/", sizeof(c->protocol));
3204     av_strlcat(c->protocol, proto_str, sizeof(c->protocol));
3205
3206     current_bandwidth += stream->bandwidth;
3207
3208     c->next = first_http_ctx;
3209     first_http_ctx = c;
3210     return c;
3211
3212  fail:
3213     if (c) {
3214         av_freep(&c->buffer);
3215         av_free(c);
3216     }
3217     return NULL;
3218 }
3219
3220 /* add a new RTP stream in an RTP connection (used in RTSP SETUP
3221    command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
3222    used. */
3223 static int rtp_new_av_stream(HTTPContext *c,
3224                              int stream_index, struct sockaddr_in *dest_addr,
3225                              HTTPContext *rtsp_c)
3226 {
3227     AVFormatContext *ctx;
3228     AVStream *st;
3229     char *ipaddr;
3230     URLContext *h = NULL;
3231     uint8_t *dummy_buf;
3232     int max_packet_size;
3233
3234     /* now we can open the relevant output stream */
3235     ctx = avformat_alloc_context();
3236     if (!ctx)
3237         return -1;
3238     ctx->oformat = av_guess_format("rtp", NULL, NULL);
3239
3240     st = av_mallocz(sizeof(AVStream));
3241     if (!st)
3242         goto fail;
3243     ctx->nb_streams = 1;
3244     ctx->streams = av_mallocz_array(ctx->nb_streams, sizeof(AVStream *));
3245     if (!ctx->streams)
3246       goto fail;
3247     ctx->streams[0] = st;
3248
3249     if (!c->stream->feed ||
3250         c->stream->feed == c->stream)
3251         memcpy(st, c->stream->streams[stream_index], sizeof(AVStream));
3252     else
3253         memcpy(st,
3254                c->stream->feed->streams[c->stream->feed_streams[stream_index]],
3255                sizeof(AVStream));
3256     st->priv_data = NULL;
3257
3258     /* build destination RTP address */
3259     ipaddr = inet_ntoa(dest_addr->sin_addr);
3260
3261     switch(c->rtp_protocol) {
3262     case RTSP_LOWER_TRANSPORT_UDP:
3263     case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
3264         /* RTP/UDP case */
3265
3266         /* XXX: also pass as parameter to function ? */
3267         if (c->stream->is_multicast) {
3268             int ttl;
3269             ttl = c->stream->multicast_ttl;
3270             if (!ttl)
3271                 ttl = 16;
3272             snprintf(ctx->filename, sizeof(ctx->filename),
3273                      "rtp://%s:%d?multicast=1&ttl=%d",
3274                      ipaddr, ntohs(dest_addr->sin_port), ttl);
3275         } else {
3276             snprintf(ctx->filename, sizeof(ctx->filename),
3277                      "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
3278         }
3279
3280         if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
3281             goto fail;
3282         c->rtp_handles[stream_index] = h;
3283         max_packet_size = h->max_packet_size;
3284         break;
3285     case RTSP_LOWER_TRANSPORT_TCP:
3286         /* RTP/TCP case */
3287         c->rtsp_c = rtsp_c;
3288         max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
3289         break;
3290     default:
3291         goto fail;
3292     }
3293
3294     http_log("%s:%d - - \"PLAY %s/streamid=%d %s\"\n",
3295              ipaddr, ntohs(dest_addr->sin_port),
3296              c->stream->filename, stream_index, c->protocol);
3297
3298     /* normally, no packets should be output here, but the packet size may
3299      * be checked */
3300     if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
3301         /* XXX: close stream */
3302         goto fail;
3303     }
3304     if (avformat_write_header(ctx, NULL) < 0) {
3305     fail:
3306         if (h)
3307             ffurl_close(h);
3308         av_free(st);
3309         av_free(ctx);
3310         return -1;
3311     }
3312     avio_close_dyn_buf(ctx->pb, &dummy_buf);
3313     av_free(dummy_buf);
3314
3315     c->rtp_ctx[stream_index] = ctx;
3316     return 0;
3317 }
3318
3319 /********************************************************************/
3320 /* ffserver initialization */
3321
3322 static AVStream *add_av_stream1(FFServerStream *stream, AVCodecContext *codec, int copy)
3323 {
3324     AVStream *fst;
3325
3326     if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams))
3327         return NULL;
3328
3329     fst = av_mallocz(sizeof(AVStream));
3330     if (!fst)
3331         return NULL;
3332     if (copy) {
3333         fst->codec = avcodec_alloc_context3(codec->codec);
3334         avcodec_copy_context(fst->codec, codec);
3335     } else {
3336         /* live streams must use the actual feed's codec since it may be
3337          * updated later to carry extradata needed by them.
3338          */
3339         fst->codec = codec;
3340     }
3341     fst->priv_data = av_mallocz(sizeof(FeedData));
3342     fst->index = stream->nb_streams;
3343     avpriv_set_pts_info(fst, 33, 1, 90000);
3344     fst->sample_aspect_ratio = codec->sample_aspect_ratio;
3345     stream->streams[stream->nb_streams++] = fst;
3346     return fst;
3347 }
3348
3349 /* return the stream number in the feed */
3350 static int add_av_stream(FFServerStream *feed, AVStream *st)
3351 {
3352     AVStream *fst;
3353     AVCodecContext *av, *av1;
3354     int i;
3355
3356     av = st->codec;
3357     for(i=0;i<feed->nb_streams;i++) {
3358         av1 = feed->streams[i]->codec;
3359         if (av1->codec_id == av->codec_id &&
3360             av1->codec_type == av->codec_type &&
3361             av1->bit_rate == av->bit_rate) {
3362
3363             switch(av->codec_type) {
3364             case AVMEDIA_TYPE_AUDIO:
3365                 if (av1->channels == av->channels &&
3366                     av1->sample_rate == av->sample_rate)
3367                     return i;
3368                 break;
3369             case AVMEDIA_TYPE_VIDEO:
3370                 if (av1->width == av->width &&
3371                     av1->height == av->height &&
3372                     av1->time_base.den == av->time_base.den &&
3373                     av1->time_base.num == av->time_base.num &&
3374                     av1->gop_size == av->gop_size)
3375                     return i;
3376                 break;
3377             default:
3378                 abort();
3379             }
3380         }
3381     }
3382
3383     fst = add_av_stream1(feed, av, 0);
3384     if (!fst)
3385         return -1;
3386     if (av_stream_get_recommended_encoder_configuration(st))
3387         av_stream_set_recommended_encoder_configuration(fst,
3388             av_strdup(av_stream_get_recommended_encoder_configuration(st)));
3389     return feed->nb_streams - 1;
3390 }
3391
3392 static void remove_stream(FFServerStream *stream)
3393 {
3394     FFServerStream **ps;
3395     ps = &config.first_stream;
3396     while (*ps) {
3397         if (*ps == stream)
3398             *ps = (*ps)->next;
3399         else
3400             ps = &(*ps)->next;
3401     }
3402 }
3403
3404 /* specific MPEG4 handling : we extract the raw parameters */
3405 static void extract_mpeg4_header(AVFormatContext *infile)
3406 {
3407     int mpeg4_count, i, size;
3408     AVPacket pkt;
3409     AVStream *st;
3410     const uint8_t *p;
3411
3412     infile->flags |= AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE;
3413
3414     mpeg4_count = 0;
3415     for(i=0;i<infile->nb_streams;i++) {
3416         st = infile->streams[i];
3417         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3418             st->codec->extradata_size == 0) {
3419             mpeg4_count++;
3420         }
3421     }
3422     if (!mpeg4_count)
3423         return;
3424
3425     printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename);
3426     while (mpeg4_count > 0) {
3427         if (av_read_frame(infile, &pkt) < 0)
3428             break;
3429         st = infile->streams[pkt.stream_index];
3430         if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
3431             st->codec->extradata_size == 0) {
3432             av_freep(&st->codec->extradata);
3433             /* fill extradata with the header */
3434             /* XXX: we make hard suppositions here ! */
3435             p = pkt.data;
3436             while (p < pkt.data + pkt.size - 4) {
3437                 /* stop when vop header is found */
3438                 if (p[0] == 0x00 && p[1] == 0x00 &&
3439                     p[2] == 0x01 && p[3] == 0xb6) {
3440                     size = p - pkt.data;
3441                     //                    av_hex_dump_log(infile, AV_LOG_DEBUG, pkt.data, size);
3442                     st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
3443                     st->codec->extradata_size = size;
3444                     memcpy(st->codec->extradata, pkt.data, size);
3445                     break;
3446                 }
3447                 p++;
3448             }
3449             mpeg4_count--;
3450         }
3451         av_free_packet(&pkt);
3452     }
3453 }
3454
3455 /* compute the needed AVStream for each file */
3456 static void build_file_streams(void)
3457 {
3458     FFServerStream *stream, *stream_next;
3459     int i, ret;
3460
3461     /* gather all streams */
3462     for(stream = config.first_stream; stream; stream = stream_next) {
3463         AVFormatContext *infile = NULL;
3464         stream_next = stream->next;
3465         if (stream->stream_type == STREAM_TYPE_LIVE &&
3466             !stream->feed) {
3467             /* the stream comes from a file */
3468             /* try to open the file */
3469             /* open stream */
3470             if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
3471                 /* specific case : if transport stream output to RTP,
3472                    we use a raw transport stream reader */
3473                 av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
3474             }
3475
3476             if (!stream->feed_filename[0]) {
3477                 http_log("Unspecified feed file for stream '%s'\n", stream->filename);
3478                 goto fail;
3479             }
3480
3481             http_log("Opening feed file '%s' for stream '%s'\n", stream->feed_filename, stream->filename);
3482             if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {
3483                 http_log("Could not open '%s': %s\n", stream->feed_filename, av_err2str(ret));
3484                 /* remove stream (no need to spend more time on it) */
3485             fail:
3486                 remove_stream(stream);
3487             } else {
3488                 /* find all the AVStreams inside and reference them in
3489                    'stream' */
3490                 if (avformat_find_stream_info(infile, NULL) < 0) {
3491                     http_log("Could not find codec parameters from '%s'\n",
3492                              stream->feed_filename);
3493                     avformat_close_input(&infile);
3494                     goto fail;
3495                 }
3496                 extract_mpeg4_header(infile);
3497
3498                 for(i=0;i<infile->nb_streams;i++)
3499                     add_av_stream1(stream, infile->streams[i]->codec, 1);
3500
3501                 avformat_close_input(&infile);
3502             }
3503         }
3504     }
3505 }
3506
3507 /* compute the needed AVStream for each feed */
3508 static void build_feed_streams(void)
3509 {
3510     FFServerStream *stream, *feed;
3511     int i;
3512
3513     /* gather all streams */
3514     for(stream = config.first_stream; stream; stream = stream->next) {
3515         feed = stream->feed;
3516         if (feed) {
3517             if (stream->is_feed) {
3518                 for(i=0;i<stream->nb_streams;i++)
3519                     stream->feed_streams[i] = i;
3520             } else {
3521                 /* we handle a stream coming from a feed */
3522                 for(i=0;i<stream->nb_streams;i++)
3523                     stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]);
3524             }
3525         }
3526     }
3527
3528     /* create feed files if needed */
3529     for(feed = config.first_feed; feed; feed = feed->next_feed) {
3530         int fd;
3531
3532         if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) {
3533             /* See if it matches */
3534             AVFormatContext *s = NULL;
3535             int matches = 0;
3536
3537             if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
3538                 /* set buffer size */
3539                 ffio_set_buf_size(s->pb, FFM_PACKET_SIZE);
3540                 /* Now see if it matches */
3541                 if (s->nb_streams == feed->nb_streams) {
3542                     matches = 1;
3543                     for(i=0;i<s->nb_streams;i++) {
3544                         AVStream *sf, *ss;
3545                         sf = feed->streams[i];
3546                         ss = s->streams[i];
3547
3548                         if (sf->index != ss->index ||
3549                             sf->id != ss->id) {
3550                             http_log("Index & Id do not match for stream %d (%s)\n",
3551                                    i, feed->feed_filename);
3552                             matches = 0;
3553                         } else {
3554                             AVCodecContext *ccf, *ccs;
3555
3556                             ccf = sf->codec;
3557                             ccs = ss->codec;
3558 #define CHECK_CODEC(x)  (ccf->x != ccs->x)
3559
3560                             if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
3561                                 http_log("Codecs do not match for stream %d\n", i);
3562                                 matches = 0;
3563                             } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
3564                                 http_log("Codec bitrates do not match for stream %d\n", i);
3565                                 matches = 0;
3566                             } else if (ccf->codec_type == AVMEDIA_TYPE_VIDEO) {
3567                                 if (CHECK_CODEC(time_base.den) ||
3568                                     CHECK_CODEC(time_base.num) ||
3569                                     CHECK_CODEC(width) ||
3570                                     CHECK_CODEC(height)) {
3571                                     http_log("Codec width, height and framerate do not match for stream %d\n", i);
3572                                     matches = 0;
3573                                 }
3574                             } else if (ccf->codec_type == AVMEDIA_TYPE_AUDIO) {
3575                                 if (CHECK_CODEC(sample_rate) ||
3576                                     CHECK_CODEC(channels) ||
3577                                     CHECK_CODEC(frame_size)) {
3578                                     http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);
3579                                     matches = 0;
3580                                 }
3581                             } else {
3582                                 http_log("Unknown codec type\n");
3583                                 matches = 0;
3584                             }
3585                         }
3586                         if (!matches)
3587                             break;
3588                     }
3589                 } else
3590                     http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",
3591                         feed->feed_filename, s->nb_streams, feed->nb_streams);
3592
3593                 avformat_close_input(&s);
3594             } else
3595                 http_log("Deleting feed file '%s' as it appears to be corrupt\n",
3596                         feed->feed_filename);
3597
3598             if (!matches) {
3599                 if (feed->readonly) {
3600                     http_log("Unable to delete feed file '%s' as it is marked readonly\n",
3601                         feed->feed_filename);
3602                     exit(1);
3603                 }
3604                 unlink(feed->feed_filename);
3605             }
3606         }
3607         if (avio_check(feed->feed_filename, AVIO_FLAG_WRITE) <= 0) {
3608             AVFormatContext *s = avformat_alloc_context();
3609
3610             if (feed->readonly) {
3611                 http_log("Unable to create feed file '%s' as it is marked readonly\n",
3612                     feed->feed_filename);
3613                 exit(1);
3614             }
3615
3616             /* only write the header of the ffm file */
3617             if (avio_open(&s->pb, feed->feed_filename, AVIO_FLAG_WRITE) < 0) {
3618                 http_log("Could not open output feed file '%s'\n",
3619                          feed->feed_filename);
3620                 exit(1);
3621             }
3622             s->oformat = feed->fmt;
3623             s->nb_streams = feed->nb_streams;
3624             s->streams = feed->streams;
3625             if (avformat_write_header(s, NULL) < 0) {
3626                 http_log("Container doesn't support the required parameters\n");
3627                 exit(1);
3628             }
3629             /* XXX: need better API */
3630             av_freep(&s->priv_data);
3631             avio_closep(&s->pb);
3632             s->streams = NULL;
3633             s->nb_streams = 0;
3634             avformat_free_context(s);
3635         }
3636         /* get feed size and write index */
3637         fd = open(feed->feed_filename, O_RDONLY);
3638         if (fd < 0) {
3639             http_log("Could not open output feed file '%s'\n",
3640                     feed->feed_filename);
3641             exit(1);
3642         }
3643
3644         feed->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZE);
3645         feed->feed_size = lseek(fd, 0, SEEK_END);
3646         /* ensure that we do not wrap before the end of file */
3647         if (feed->feed_max_size && feed->feed_max_size < feed->feed_size)
3648             feed->feed_max_size = feed->feed_size;
3649
3650         close(fd);
3651     }
3652 }
3653
3654 /* compute the bandwidth used by each stream */
3655 static void compute_bandwidth(void)
3656 {
3657     unsigned bandwidth;
3658     int i;
3659     FFServerStream *stream;
3660
3661     for(stream = config.first_stream; stream; stream = stream->next) {
3662         bandwidth = 0;
3663         for(i=0;i<stream->nb_streams;i++) {
3664             AVStream *st = stream->streams[i];
3665             switch(st->codec->codec_type) {
3666             case AVMEDIA_TYPE_AUDIO:
3667             case AVMEDIA_TYPE_VIDEO:
3668                 bandwidth += st->codec->bit_rate;
3669                 break;
3670             default:
3671                 break;
3672             }
3673         }
3674         stream->bandwidth = (bandwidth + 999) / 1000;
3675     }
3676 }
3677
3678 static void handle_child_exit(int sig)
3679 {
3680     pid_t pid;
3681     int status;
3682
3683     while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
3684         FFServerStream *feed;
3685
3686         for (feed = config.first_feed; feed; feed = feed->next) {
3687             if (feed->pid == pid) {
3688                 int uptime = time(0) - feed->pid_start;
3689
3690                 feed->pid = 0;
3691                 fprintf(stderr, "%s: Pid %d exited with status %d after %d seconds\n", feed->filename, pid, status, uptime);
3692
3693                 if (uptime < 30)
3694                     /* Turn off any more restarts */
3695                     ffserver_free_child_args(&feed->child_argv);
3696             }
3697         }
3698     }
3699
3700     need_to_start_children = 1;
3701 }
3702
3703 static void opt_debug(void)
3704 {
3705     config.debug = 1;
3706     snprintf(config.logfilename, sizeof(config.logfilename), "-");
3707 }
3708
3709 void show_help_default(const char *opt, const char *arg)
3710 {
3711     printf("usage: ffserver [options]\n"
3712            "Hyper fast multi format Audio/Video streaming server\n");
3713     printf("\n");
3714     show_help_options(options, "Main options:", 0, 0, 0);
3715 }
3716
3717 static const OptionDef options[] = {
3718 #include "cmdutils_common_opts.h"
3719     { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" },
3720     { "d", 0, {(void*)opt_debug}, "enable debug mode" },
3721     { "f", HAS_ARG | OPT_STRING, {(void*)&config.filename }, "use configfile instead of /etc/ffserver.conf", "configfile" },
3722     { NULL },
3723 };
3724
3725 int main(int argc, char **argv)
3726 {
3727     struct sigaction sigact = { { 0 } };
3728     int ret = 0;
3729
3730     config.filename = av_strdup("/etc/ffserver.conf");
3731
3732     parse_loglevel(argc, argv, options);
3733     av_register_all();
3734     avformat_network_init();
3735
3736     show_banner(argc, argv, options);
3737
3738     my_program_name = argv[0];
3739
3740     parse_options(NULL, argc, argv, options, NULL);
3741
3742     unsetenv("http_proxy");             /* Kill the http_proxy */
3743
3744     av_lfg_init(&random_state, av_get_random_seed());
3745
3746     sigact.sa_handler = handle_child_exit;
3747     sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART;
3748     sigaction(SIGCHLD, &sigact, 0);
3749
3750     if ((ret = ffserver_parse_ffconfig(config.filename, &config)) < 0) {
3751         fprintf(stderr, "Error reading configuration file '%s': %s\n",
3752                 config.filename, av_err2str(ret));
3753         exit(1);
3754     }
3755     av_freep(&config.filename);
3756
3757     /* open log file if needed */
3758     if (config.logfilename[0] != '\0') {
3759         if (!strcmp(config.logfilename, "-"))
3760             logfile = stdout;
3761         else
3762             logfile = fopen(config.logfilename, "a");
3763         av_log_set_callback(http_av_log);
3764     }
3765
3766     build_file_streams();
3767
3768     build_feed_streams();
3769
3770     compute_bandwidth();
3771
3772     /* signal init */
3773     signal(SIGPIPE, SIG_IGN);
3774
3775     if (http_server() < 0) {
3776         http_log("Could not start server\n");
3777         exit(1);
3778     }
3779
3780     return 0;
3781 }