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