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