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