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