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