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