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