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