ffserver.c
上传用户:jxp0626
上传日期:2007-01-08
资源大小:102k
文件大小:49k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Unix_Linux

  1. /*
  2.  * Multiple format streaming server
  3.  * Copyright (c) 2000,2001 Gerard Lantau.
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19. #include <stdarg.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <netinet/in.h>
  24. #include <linux/videodev.h>
  25. #include <linux/soundcard.h>
  26. #include <unistd.h>
  27. #include <fcntl.h>
  28. #include <sys/ioctl.h>
  29. #include <sys/mman.h>
  30. #include <sys/poll.h>
  31. #include <errno.h>
  32. #include <sys/time.h>
  33. #include <getopt.h>
  34. #include <sys/socket.h>
  35. #include <arpa/inet.h>
  36. #include <netdb.h>
  37. #include <ctype.h>
  38. #include <pthread.h>
  39. #include <signal.h>
  40. #include "mpegenc.h"
  41. /* maximum number of simultaneous HTTP connections */
  42. #define HTTP_MAX_CONNECTIONS 2000
  43. enum HTTPState {
  44.     HTTPSTATE_WAIT_REQUEST,
  45.     HTTPSTATE_SEND_HEADER,
  46.     HTTPSTATE_SEND_DATA_HEADER,
  47.     HTTPSTATE_SEND_DATA,
  48.     HTTPSTATE_SEND_DATA_TRAILER,
  49. };
  50. enum MasterState {
  51.     MASTERSTATE_RECEIVE_HEADER,
  52.     MASTERSTATE_RECEIVE_DATA,
  53. };
  54.     
  55. #define IOBUFFER_MAX_SIZE 16384
  56. #define FIFO_MAX_SIZE (1024*1024)
  57. /* coef for exponential mean for bitrate estimation in statistics */
  58. #define AVG_COEF 0.9
  59. /* timeouts are in ms */
  60. #define REQUEST_TIMEOUT (15 * 1000)
  61. #define SYNC_TIMEOUT (10 * 1000)
  62. #define MASTER_CONNECT_TIMEOUT (10 * 1000)
  63. typedef struct HTTPContext {
  64.     enum HTTPState state;
  65.     int fd; /* socket file descriptor */
  66.     struct sockaddr_in from_addr; /* origin */
  67.     struct pollfd *poll_entry; /* used when polling */
  68.     long timeout;
  69.     UINT8 buffer[IOBUFFER_MAX_SIZE];
  70.     UINT8 *buffer_ptr, *buffer_end;
  71.     int http_error;
  72.     struct HTTPContext *next;
  73.     UINT8 *rptr; /* read pointer in the fifo */
  74.     int got_key_frame[2]; /* for each type */
  75.     long long data_count;
  76.     long long last_http_fifo_write_count; /* used to monitor overflow in the fifo */
  77.     /* format handling */
  78.     struct FFStream *stream;
  79.     AVFormatContext fmt_ctx;
  80.     int last_packet_sent; /* true if last data packet was sent */
  81. } HTTPContext;
  82. /* each generated stream is described here */
  83. enum StreamType {
  84.     STREAM_TYPE_LIVE,
  85.     STREAM_TYPE_MASTER,
  86.     STREAM_TYPE_STATUS,
  87. };
  88. typedef struct FFStream {
  89.     enum StreamType stream_type;
  90.     char filename[1024];
  91.     AVFormat *fmt;
  92.     AVEncodeContext *audio_enc;
  93.     AVEncodeContext *video_enc;
  94.     struct FFStream *next;
  95. } FFStream;
  96. typedef struct FifoBuffer {
  97.     UINT8 *buffer;
  98.     UINT8 *rptr, *wptr, *end;
  99. } FifoBuffer;
  100. /* each codec is here */
  101. typedef struct FFCodec {
  102.     struct FFCodec *next;
  103.     FifoBuffer fifo;     /* for compression: one audio fifo per codec */
  104.     ReSampleContext resample; /* for audio resampling */
  105.     long long data_count;
  106.     float avg_frame_size;   /* frame size averraged over last frames with exponential mean */
  107.     AVEncodeContext enc;
  108. } FFCodec;
  109. /* packet header */
  110. typedef struct {
  111.     UINT8 codec_type;
  112.     UINT8 codec_id;
  113.     UINT8 data[4];
  114.     UINT16 bit_rate;
  115.     UINT16 payload_size;
  116. } PacketHeader;
  117. struct sockaddr_in my_addr;
  118. char logfilename[1024];
  119. HTTPContext *first_http_ctx;
  120. FFStream *first_stream;
  121. FFCodec *first_codec;
  122. /* master state */
  123. char master_url[1024];
  124. enum MasterState master_state;
  125. UINT8 *master_wptr;
  126. int master_count;
  127. long long http_fifo_write_count;
  128. static FifoBuffer http_fifo;
  129. static int handle_http(HTTPContext *c, long cur_time);
  130. static int http_parse_request(HTTPContext *c);
  131. static int http_send_data(HTTPContext *c);
  132. static int master_receive(int fd);
  133. static void compute_stats(HTTPContext *c);
  134. int nb_max_connections;
  135. int nb_connections;
  136. /* fifo handling */
  137. int fifo_init(FifoBuffer *f, int size)
  138. {
  139.     f->buffer = malloc(size);
  140.     if (!f->buffer)
  141.         return -1;
  142.     f->end = f->buffer + size;
  143.     f->wptr = f->rptr = f->buffer;
  144.     return 0;
  145. }
  146. static int fifo_size(FifoBuffer *f, UINT8 *rptr)
  147. {
  148.     int size;
  149.     if (f->wptr >= rptr) {
  150.         size = f->wptr - rptr;
  151.     } else {
  152.         size = (f->end - rptr) + (f->wptr - f->buffer);
  153.     }
  154.     return size;
  155. }
  156. /* get data from the fifo (return -1 if not enough data) */
  157. static int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr)
  158. {
  159.     UINT8 *rptr = *rptr_ptr;
  160.     int size, len;
  161.     if (f->wptr >= rptr) {
  162.         size = f->wptr - rptr;
  163.     } else {
  164.         size = (f->end - rptr) + (f->wptr - f->buffer);
  165.     }
  166.     
  167.     if (size < buf_size)
  168.         return -1;
  169.     while (buf_size > 0) {
  170.         len = f->end - rptr;
  171.         if (len > buf_size)
  172.             len = buf_size;
  173.         memcpy(buf, rptr, len);
  174.         buf += len;
  175.         rptr += len;
  176.         if (rptr >= f->end)
  177.             rptr = f->buffer;
  178.         buf_size -= len;
  179.     }
  180.     *rptr_ptr = rptr;
  181.     return 0;
  182. }
  183. static void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
  184. {
  185.     int len;
  186.     UINT8 *wptr;
  187.     wptr = *wptr_ptr;
  188.     while (size > 0) {
  189.         len = f->end - wptr;
  190.         if (len > size)
  191.             len = size;
  192.         memcpy(wptr, buf, len);
  193.         wptr += len;
  194.         if (wptr >= f->end)
  195.             wptr = f->buffer;
  196.         buf += len;
  197.         size -= len;
  198.     }
  199.     *wptr_ptr = wptr;
  200. }
  201. static long gettime_ms(void)
  202. {
  203.     struct timeval tv;
  204.     gettimeofday(&tv,NULL);
  205.     return (long long)tv.tv_sec * 1000 + (tv.tv_usec / 1000);
  206. }
  207. static FILE *logfile = NULL;
  208. static void http_log(char *fmt, ...)
  209. {
  210.     va_list ap;
  211.     va_start(ap, fmt);
  212.     
  213.     if (logfile)
  214.         vfprintf(logfile, fmt, ap);
  215.     va_end(ap);
  216. }
  217. /* connect to url 'url' and return the connected socket ready to read data */
  218. static int url_get(const char *url)
  219. {
  220.     struct sockaddr_in dest_addr;
  221.     struct hostent *h;
  222.     int s, port, size, line_size, len;
  223.     char hostname[1024], *q;
  224.     const char *p, *path;
  225.     char req[1024];
  226.     unsigned char ch;
  227.     if (!strstart(url, "http://", &p))
  228.         return -1;
  229.     q = hostname;
  230.     while (*p != ':' && *p != '' && *p != '/') {
  231.         if ((q - hostname) < (sizeof(hostname) - 1))
  232.             *q++ = *p;
  233.         p++;
  234.     }
  235.     port = 80;
  236.     if (*p == ':') {
  237.         p++;
  238.         port = strtol(p, (char **)&p, 10);
  239.     }
  240.     path = p;
  241.         
  242.     dest_addr.sin_family = AF_INET;
  243.     dest_addr.sin_port = htons(port);
  244.     if (!inet_aton(hostname, &dest_addr.sin_addr)) {
  245. if ((h = gethostbyname(hostname)) == NULL)
  246.     return -1;
  247. memcpy(&dest_addr.sin_addr, h->h_addr, sizeof(dest_addr.sin_addr));
  248.     }
  249.     s=socket(AF_INET, SOCK_STREAM, 0);
  250.     if (s < 0) 
  251.         return -1;
  252.     if (connect(s, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) < 0) {
  253.     fail:
  254. close(s);
  255. return -1;
  256.     }
  257.     
  258.     /* send http request */
  259.     snprintf(req, sizeof(req), "GET %s HTTP/1.0rnrn", path);
  260.     p = req;
  261.     size = strlen(req);
  262.     while (size > 0) {
  263.         len = write(s, p, size);
  264.         if (len == -1) {
  265.             if (errno != EAGAIN && errno != EINTR)
  266.                 goto fail;
  267.         } else {
  268.             size -= len;
  269.             p += len;
  270.         }
  271.     }
  272.     
  273.     /* receive answer */
  274.     line_size = 0;
  275.     for(;;) {
  276.         len = read(s, &ch, 1);
  277.         if (len == -1) {
  278.             if (errno != EAGAIN && errno != EINTR)
  279.                 goto fail;
  280.         } else if (len == 0) {
  281.             goto fail;
  282.         } else {
  283.             if (ch == 'n') {
  284.                 if (line_size == 0)
  285.                     break;
  286.                 line_size = 0;
  287.             } else if (ch != 'r') {
  288.                 line_size++;
  289.             }
  290.         }
  291.     }
  292.     return s;
  293. }
  294. /* Each request is served by reading the input FIFO and by adding the
  295.    right format headers */
  296. static int http_server(struct sockaddr_in my_addr)
  297. {
  298.     int server_fd, tmp, ret;
  299.     struct sockaddr_in from_addr;
  300.     struct pollfd poll_table[HTTP_MAX_CONNECTIONS + 1], *poll_entry;
  301.     HTTPContext *c, **cp;
  302.     long cur_time;
  303.     int master_fd, master_timeout;
  304.     /* will try to connect to master as soon as possible */
  305.     master_fd = -1;
  306.     master_timeout = gettime_ms();
  307.     server_fd = socket(AF_INET,SOCK_STREAM,0);
  308.     if (server_fd < 0) {
  309.         perror ("socket");
  310.         return -1;
  311.     }
  312.         
  313.     tmp = 1;
  314.     setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
  315.     if (bind (server_fd, (struct sockaddr *) &my_addr, sizeof (my_addr)) < 0) {
  316.         perror ("bind");
  317.         close(server_fd);
  318.         return -1;
  319.     }
  320.   
  321.     if (listen (server_fd, 5) < 0) {
  322.         perror ("listen");
  323.         close(server_fd);
  324.         return -1;
  325.     }
  326.     http_log("ffserver started.n");
  327.     fcntl(server_fd, F_SETFL, O_NONBLOCK);
  328.     first_http_ctx = NULL;
  329.     nb_connections = 0;
  330.     first_http_ctx = NULL;
  331.     for(;;) {
  332.         poll_entry = poll_table;
  333.         poll_entry->fd = server_fd;
  334.         poll_entry->events = POLLIN;
  335.         poll_entry++;
  336.         if (master_fd >= 0) {
  337.             poll_entry->fd = master_fd;
  338.             poll_entry->events = POLLIN;
  339.             poll_entry++;
  340.         }
  341.         /* wait for events on each HTTP handle */
  342.         c = first_http_ctx;
  343.         while (c != NULL) {
  344.             int fd;
  345.             fd = c->fd;
  346.             switch(c->state) {
  347.             case HTTPSTATE_WAIT_REQUEST:
  348.                 c->poll_entry = poll_entry;
  349.                 poll_entry->fd = fd;
  350.                 poll_entry->events = POLLIN;
  351.                 poll_entry++;
  352.                 break;
  353.             case HTTPSTATE_SEND_HEADER:
  354.             case HTTPSTATE_SEND_DATA_HEADER:
  355.             case HTTPSTATE_SEND_DATA:
  356.             case HTTPSTATE_SEND_DATA_TRAILER:
  357.                 c->poll_entry = poll_entry;
  358.                 poll_entry->fd = fd;
  359.                 poll_entry->events = POLLOUT;
  360.                 poll_entry++;
  361.                 break;
  362.             default:
  363.                 c->poll_entry = NULL;
  364.                 break;
  365.             }
  366.             c = c->next;
  367.         }
  368.         /* wait for an event on one connection. We poll at least every
  369.            second to handle timeouts */
  370.         do {
  371.             ret = poll(poll_table, poll_entry - poll_table, 1000);
  372.         } while (ret == -1);
  373.         
  374.         cur_time = gettime_ms();
  375.         /* now handle the events */
  376.         cp = &first_http_ctx;
  377.         while ((*cp) != NULL) {
  378.             c = *cp;
  379.             if (handle_http (c, cur_time) < 0) {
  380.                 /* close and free the connection */
  381.                 close(c->fd);
  382.                 *cp = c->next;
  383.                 free(c);
  384.                 nb_connections--;
  385.             } else {
  386.                 cp = &c->next;
  387.             }
  388.         }
  389.         /* new connection request ? */
  390.         poll_entry = poll_table;
  391.         if (poll_entry->revents & POLLIN) {
  392.             int fd, len;
  393.             len = sizeof(from_addr);
  394.             fd = accept(server_fd, &from_addr, &len);
  395.             if (fd >= 0) {
  396.                 fcntl(fd, F_SETFL, O_NONBLOCK);
  397.                 /* XXX: should output a warning page when comming
  398.                    close to the connection limit */
  399.                 if (nb_connections >= nb_max_connections) {
  400.                     close(fd);
  401.                 } else {
  402.                     /* add a new connection */
  403.                     c = malloc(sizeof(HTTPContext));
  404.                     memset(c, 0, sizeof(*c));
  405.                     c->next = first_http_ctx;
  406.                     first_http_ctx = c;
  407.                     c->fd = fd;
  408.                     c->poll_entry = NULL;
  409.                     c->from_addr = from_addr;
  410.                     c->state = HTTPSTATE_WAIT_REQUEST;
  411.                     c->buffer_ptr = c->buffer;
  412.                     c->buffer_end = c->buffer + IOBUFFER_MAX_SIZE;
  413.                     c->timeout = cur_time + REQUEST_TIMEOUT;
  414.                     nb_connections++;
  415.                 }
  416.             }
  417.         }
  418.         poll_entry++;
  419.         /* master events */
  420.         if (poll_entry->revents & POLLIN) {
  421.             if (master_receive(master_fd) < 0) {
  422.                 close(master_fd);
  423.                 master_fd = -1;
  424.             }
  425.         }
  426.         /* master (re)connection handling */
  427.         if (master_url[0] != '' && 
  428.             master_fd < 0 && (master_timeout - cur_time) <= 0) {
  429.             master_fd = url_get(master_url);
  430.             if (master_fd < 0) {
  431.                 master_timeout = gettime_ms() + MASTER_CONNECT_TIMEOUT;
  432.                 http_log("Connection to master: '%s' failedn", master_url);
  433.             } else {
  434.                 fcntl(master_fd, F_SETFL, O_NONBLOCK);
  435.                 master_state = MASTERSTATE_RECEIVE_HEADER;
  436.                 master_count = sizeof(PacketHeader);
  437.                 master_wptr = http_fifo.wptr;
  438.             }
  439.         }
  440.     }
  441. }
  442. static int handle_http(HTTPContext *c, long cur_time)
  443. {
  444.     int len;
  445.     
  446.     switch(c->state) {
  447.     case HTTPSTATE_WAIT_REQUEST:
  448.         /* timeout ? */
  449.         if ((c->timeout - cur_time) < 0)
  450.             return -1;
  451.         if (c->poll_entry->revents & (POLLERR | POLLHUP))
  452.             return -1;
  453.         /* no need to read if no events */
  454.         if (!(c->poll_entry->revents & POLLIN))
  455.             return 0;
  456.         /* read the data */
  457.         len = read(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr);
  458.         if (len < 0) {
  459.             if (errno != EAGAIN && errno != EINTR)
  460.                 return -1;
  461.         } else if (len == 0) {
  462.             return -1;
  463.         } else {
  464.             /* search for end of request. XXX: not fully correct since garbage could come after the end */
  465.             UINT8 *ptr;
  466.             c->buffer_ptr += len;
  467.             ptr = c->buffer_ptr;
  468.             if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "nn", 2)) ||
  469.                 (ptr >= c->buffer + 4 && !memcmp(ptr-4, "rnrn", 4))) {
  470.                 /* request found : parse it and reply */
  471.                 if (http_parse_request(c) < 0)
  472.                     return -1;
  473.             } else if (ptr >= c->buffer_end) {
  474.                 /* request too long: cannot do anything */
  475.                 return -1;
  476.             }
  477.         }
  478.         break;
  479.     case HTTPSTATE_SEND_HEADER:
  480.         if (c->poll_entry->revents & (POLLERR | POLLHUP))
  481.             return -1;
  482.         /* no need to read if no events */
  483.         if (!(c->poll_entry->revents & POLLOUT))
  484.             return 0;
  485.         len = write(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr);
  486.         if (len < 0) {
  487.             if (errno != EAGAIN && errno != EINTR) {
  488.                 /* error : close connection */
  489.                 return -1;
  490.             }
  491.         } else {
  492.             c->buffer_ptr += len;
  493.             if (c->buffer_ptr >= c->buffer_end) {
  494.                 /* if error, exit */
  495.                 if (c->http_error)
  496.                     return -1;
  497.                 /* all the buffer was send : synchronize to the incoming stream */
  498.                 c->state = HTTPSTATE_SEND_DATA_HEADER;
  499.                 c->buffer_ptr = c->buffer_end = c->buffer;
  500.             }
  501.         }
  502.         break;
  503.     case HTTPSTATE_SEND_DATA:
  504.     case HTTPSTATE_SEND_DATA_HEADER:
  505.     case HTTPSTATE_SEND_DATA_TRAILER:
  506.         /* no need to read if no events */
  507.         if (c->poll_entry->revents & (POLLERR | POLLHUP))
  508.             return -1;
  509.         
  510.         if (!(c->poll_entry->revents & POLLOUT))
  511.             return 0;
  512.         if (http_send_data(c) < 0)
  513.             return -1;
  514.         break;
  515.     default:
  516.         return -1;
  517.     }
  518.     return 0;
  519. }
  520. /* parse http request and prepare header */
  521. static int http_parse_request(HTTPContext *c)
  522. {
  523.     const char *p;
  524.     char cmd[32];
  525.     char url[1024], *q;
  526.     char protocol[32];
  527.     char msg[1024];
  528.     char *mime_type;
  529.     FFStream *stream;
  530.     p = c->buffer;
  531.     q = cmd;
  532.     while (!isspace(*p) && *p != '') {
  533.         if ((q - cmd) < sizeof(cmd) - 1)
  534.             *q++ = *p;
  535.         p++;
  536.     }
  537.     *q = '';
  538.     if (strcmp(cmd, "GET"))
  539.         return -1;
  540.     while (isspace(*p)) p++;
  541.     q = url;
  542.     while (!isspace(*p) && *p != '') {
  543.         if ((q - url) < sizeof(url) - 1)
  544.             *q++ = *p;
  545.         p++;
  546.     }
  547.     *q = '';
  548.     while (isspace(*p)) p++;
  549.     q = protocol;
  550.     while (!isspace(*p) && *p != '') {
  551.         if ((q - protocol) < sizeof(protocol) - 1)
  552.             *q++ = *p;
  553.         p++;
  554.     }
  555.     *q = '';
  556.     if (strcmp(protocol, "HTTP/1.0") && strcmp(protocol, "HTTP/1.1"))
  557.         return -1;
  558.     
  559.     /* find the filename in the request */
  560.     p = url;
  561.     if (*p == '/')
  562.         p++;
  563.     stream = first_stream;
  564.     while (stream != NULL) {
  565.         if (!strcmp(stream->filename, p))
  566.             break;
  567.         stream = stream->next;
  568.     }
  569.     if (stream == NULL) {
  570.         sprintf(msg, "File '%s' not found", url);
  571.         goto send_error;
  572.     }
  573.     c->stream = stream;
  574.     
  575.     /* should do it after so that the size can be computed */
  576.     {
  577.         char buf1[32], buf2[32], *p;
  578.         time_t ti;
  579.         /* XXX: reentrant function ? */
  580.         p = inet_ntoa(c->from_addr.sin_addr);
  581.         strcpy(buf1, p);
  582.         ti = time(NULL);
  583.         p = ctime(&ti);
  584.         strcpy(buf2, p);
  585.         p = buf2 + strlen(p) - 1;
  586.         if (*p == 'n')
  587.             *p = '';
  588.         http_log("%s - - [%s] "%s %s %s" %d %dn", 
  589.                  buf1, buf2, cmd, url, protocol, 200, 1024);
  590.     }
  591.     if (c->stream->stream_type == STREAM_TYPE_STATUS)
  592.         goto send_stats;
  593.     /* prepare http header */
  594.     q = c->buffer;
  595.     q += sprintf(q, "HTTP/1.0 200 OKrn");
  596.     mime_type = c->stream->fmt->mime_type;
  597.     if (!mime_type)
  598.         mime_type = "application/x-octet_stream";
  599.     q += sprintf(q, "Content-type: %srn", mime_type);
  600.     q += sprintf(q, "Pragma: no-cachern");
  601.     /* for asf, we need extra headers */
  602.     if (!strcmp(c->stream->fmt->name,"asf")) {
  603.         q += sprintf(q, "Pragma: features=broadcastrn");
  604.     }
  605.     q += sprintf(q, "rn");
  606.     /* prepare output buffer */
  607.     c->http_error = 0;
  608.     c->buffer_ptr = c->buffer;
  609.     c->buffer_end = q;
  610.     c->state = HTTPSTATE_SEND_HEADER;
  611.     return 0;
  612.  send_error:
  613.     c->http_error = 404;
  614.     q = c->buffer;
  615.     q += sprintf(q, "HTTP/1.0 404 Not Foundrn");
  616.     q += sprintf(q, "Content-type: %srn", "text/html");
  617.     q += sprintf(q, "rn");
  618.     q += sprintf(q, "<HTML>n");
  619.     q += sprintf(q, "<HEAD><TITLE>404 Not Found</TITLE></HEAD>n");
  620.     q += sprintf(q, "<BODY>%s</BODY>n", msg);
  621.     q += sprintf(q, "</HTML>n");
  622.     /* prepare output buffer */
  623.     c->buffer_ptr = c->buffer;
  624.     c->buffer_end = q;
  625.     c->state = HTTPSTATE_SEND_HEADER;
  626.     return 0;
  627.  send_stats:
  628.     compute_stats(c);
  629.     c->http_error = 200; /* horrible : we use this value to avoid
  630.                             going to the send data state */
  631.     c->state = HTTPSTATE_SEND_HEADER;
  632.     return 0;
  633. }
  634. static void compute_stats(HTTPContext *c)
  635. {
  636.     AVEncodeContext *enc;
  637.     HTTPContext *c1;
  638.     FFCodec *ffenc;
  639.     FFStream *stream;
  640.     float avg;
  641.     char buf[1024], *q, *p;
  642.     time_t ti;
  643.     int i;
  644.     q = c->buffer;
  645.     q += sprintf(q, "HTTP/1.0 200 OKrn");
  646.     q += sprintf(q, "Content-type: %srn", "text/html");
  647.     q += sprintf(q, "Pragma: no-cachern");
  648.     q += sprintf(q, "rn");
  649.     
  650.     q += sprintf(q, "<HEAD><TITLE>FFServer Status</TITLE></HEAD>n<BODY>");
  651.     q += sprintf(q, "<H1>FFServer Status</H1>n");
  652.     /* format status */
  653.     q += sprintf(q, "<H1>Available Streams</H1>n");
  654.     q += sprintf(q, "<TABLE>n");
  655.     q += sprintf(q, "<TR><TD>Path<TD>Format<TD>Bit rate (kbits/s)<TD>Video<TD>Audion");
  656.     stream = first_stream;
  657.     while (stream != NULL) {
  658.         q += sprintf(q, "<TR><TD><A HREF="/%s">%s</A> ", 
  659.                      stream->filename, stream->filename);
  660.         switch(stream->stream_type) {
  661.         case STREAM_TYPE_LIVE:
  662.             {
  663.                 int audio_bit_rate = 0;
  664.                 int video_bit_rate = 0;
  665.                 if (stream->audio_enc)
  666.                     audio_bit_rate = stream->audio_enc->bit_rate;
  667.                 if (stream->video_enc)
  668.                     video_bit_rate = stream->video_enc->bit_rate;
  669.                 
  670.                 q += sprintf(q, "<TD> %s <TD> %d <TD> %d <TD> %dn", 
  671.                              stream->fmt->name,
  672.                              (audio_bit_rate + video_bit_rate) / 1000,
  673.                              video_bit_rate / 1000, audio_bit_rate / 1000);
  674.             }
  675.             break;
  676.         case STREAM_TYPE_MASTER:
  677.             q += sprintf(q, "<TD> %s <TD> - <TD> - <TD> -n",
  678.                          "master");
  679.             break;
  680.         default:
  681.             q += sprintf(q, "<TD> - <TD> - <TD> - <TD> -n");
  682.             break;
  683.         }
  684.         stream = stream->next;
  685.     }
  686.     q += sprintf(q, "</TABLE>n");
  687.     
  688.     /* codec status */
  689.     q += sprintf(q, "<H1>Codec Status</H1>n");
  690.     q += sprintf(q, "<TABLE>n");
  691.     q += sprintf(q, "<TR><TD>Parameters<TD>Frame count<TD>Size<TD>Avg bitrate (kbits/s)n");
  692.     ffenc = first_codec;
  693.     while (ffenc != NULL) {
  694.         enc = &ffenc->enc;
  695.         avencoder_string(buf, sizeof(buf), enc);
  696.         avg = ffenc->avg_frame_size * (float)enc->rate * 8.0;
  697.         if (enc->codec->type == CODEC_TYPE_AUDIO && enc->frame_size > 0)
  698.             avg /= enc->frame_size;
  699.         q += sprintf(q, "<TR><TD>%s <TD> %d <TD> %Ld <TD> %0.1fn", 
  700.                      buf, enc->frame_number, ffenc->data_count, avg / 1000.0);
  701.         ffenc = ffenc->next;
  702.     }
  703.     q += sprintf(q, "</TABLE>n");
  704.     /* exclude the stat connection */
  705.     q += sprintf(q, "Number of connections: %d / %d<BR>n",
  706.                  nb_connections, nb_max_connections);
  707.     /* connection status */
  708.     q += sprintf(q, "<H1>Connection Status</H1>n");
  709.     q += sprintf(q, "<TABLE>n");
  710.     q += sprintf(q, "<TR><TD>#<TD>File<TD>IP<TD>Sizen");
  711.     c1 = first_http_ctx;
  712.     i = 0;
  713.     while (c1 != NULL) {
  714.         i++;
  715.         p = inet_ntoa(c1->from_addr.sin_addr);
  716.         q += sprintf(q, "<TR><TD><B>%d</B><TD>%s <TD> %s <TD> %Ldn", 
  717.                      i, c1->stream->filename, p, c1->data_count);
  718.         c1 = c1->next;
  719.     }
  720.     q += sprintf(q, "</TABLE>n");
  721.     
  722.     /* date */
  723.     ti = time(NULL);
  724.     p = ctime(&ti);
  725.     q += sprintf(q, "<HR>Generated at %s", p);
  726.     q += sprintf(q, "</BODY>n</HTML>n");
  727.     c->buffer_ptr = c->buffer;
  728.     c->buffer_end = q;
  729. }
  730. static void http_write_packet(void *opaque, 
  731.                               unsigned char *buf, int size)
  732. {
  733.     HTTPContext *c = opaque;
  734.     if (size > IOBUFFER_MAX_SIZE)
  735.         abort();
  736.     memcpy(c->buffer, buf, size);
  737.     c->buffer_ptr = c->buffer;
  738.     c->buffer_end = c->buffer + size;
  739. }
  740. /* this headers are used to identify a packet for a given codec */
  741. void mk_header(PacketHeader *h, AVEncodeContext *c, int payload_size)
  742. {
  743.     h->codec_type = c->codec->type;
  744.     h->codec_id = c->codec->id;
  745.     h->bit_rate = htons(c->bit_rate / 1000);
  746.     switch(c->codec->type) {
  747.     case CODEC_TYPE_VIDEO:
  748.         h->data[0] = c->rate;
  749.         h->data[1] = c->width / 16;
  750.         h->data[2] = c->height / 16;
  751.         break;
  752.     case CODEC_TYPE_AUDIO:
  753.         h->data[0] = c->rate / 1000;
  754.         h->data[1] = c->channels;
  755.         h->data[2] = 0;
  756.         break;
  757.     }
  758.     h->data[3] = c->key_frame;
  759.     h->payload_size = htons(payload_size);
  760. }
  761. int test_header(PacketHeader *h, AVEncodeContext *c)
  762. {
  763.     if (!c)
  764.         return 0;
  765.     if (h->codec_type == c->codec->type &&
  766.         h->codec_id == c->codec->id &&
  767.         h->bit_rate == htons(c->bit_rate / 1000)) {
  768.         switch(c->codec->type) {
  769.         case CODEC_TYPE_VIDEO:
  770.             if (h->data[0] == c->rate &&
  771.                 h->data[1] == (c->width / 16) &&
  772.                 h->data[2] == (c->height / 16))
  773.                 goto found;
  774.             break;
  775.         case CODEC_TYPE_AUDIO:
  776.             if (h->data[0] == (c->rate / 1000) &&
  777.                 (h->data[1] == c->channels))
  778.                 goto found;
  779.             break;
  780.         }
  781.     }
  782.     return 0;
  783.  found:
  784.     c->frame_number++;
  785.     c->key_frame = h->data[3];
  786.     return 1;
  787. }
  788. static int http_prepare_data(HTTPContext *c)
  789. {
  790.     PacketHeader hdr;
  791.     UINT8 *start_rptr, *payload;
  792.     int payload_size, ret;
  793.     long long fifo_total_size;
  794.     switch(c->state) {
  795.     case HTTPSTATE_SEND_DATA_HEADER:
  796.         if (c->stream->stream_type != STREAM_TYPE_MASTER) {            
  797.             memset(&c->fmt_ctx, 0, sizeof(c->fmt_ctx));
  798.             c->fmt_ctx.format = c->stream->fmt;
  799.             if (c->fmt_ctx.format->audio_codec != CODEC_ID_NONE) {
  800.                 /* create a fake new codec instance */
  801.                 c->fmt_ctx.audio_enc = malloc(sizeof(AVEncodeContext));
  802.                 memcpy(c->fmt_ctx.audio_enc, c->stream->audio_enc, 
  803.                        sizeof(AVEncodeContext));
  804.                 c->fmt_ctx.audio_enc->frame_number = 0;
  805.             }
  806.             if (c->fmt_ctx.format->video_codec != CODEC_ID_NONE) {
  807.                 c->fmt_ctx.video_enc = malloc(sizeof(AVEncodeContext));
  808.                 memcpy(c->fmt_ctx.video_enc, c->stream->video_enc, 
  809.                        sizeof(AVEncodeContext));
  810.                 c->fmt_ctx.video_enc->frame_number = 0;
  811.             }
  812.             init_put_byte(&c->fmt_ctx.pb, c->buffer, IOBUFFER_MAX_SIZE,
  813.                           c, http_write_packet, NULL);
  814.             c->fmt_ctx.is_streamed = 1;
  815.             c->got_key_frame[0] = 0;
  816.             c->got_key_frame[1] = 0;
  817.             /* prepare header */
  818.             c->fmt_ctx.format->write_header(&c->fmt_ctx);
  819.         }
  820.         c->state = HTTPSTATE_SEND_DATA;
  821.         c->last_packet_sent = 0;
  822.         c->rptr = http_fifo.wptr;
  823.         c->last_http_fifo_write_count = http_fifo_write_count;
  824.         break;
  825.     case HTTPSTATE_SEND_DATA:
  826.         /* find a new packet */
  827.         fifo_total_size = http_fifo_write_count - c->last_http_fifo_write_count;
  828.         if (fifo_total_size >= ((3 * FIFO_MAX_SIZE) / 4)) {
  829.             /* overflow : resync. We suppose that wptr is at this
  830.                point a pointer to a valid packet */
  831.             c->rptr = http_fifo.wptr;
  832.             c->got_key_frame[0] = 0;
  833.             c->got_key_frame[1] = 0;
  834.         }
  835.         
  836.         start_rptr = c->rptr;
  837.         if (fifo_read(&http_fifo, (UINT8 *)&hdr, sizeof(hdr), &c->rptr) < 0)
  838.             return 0;
  839.         payload_size = ntohs(hdr.payload_size);
  840.         payload = malloc(payload_size);
  841.         if (fifo_read(&http_fifo, payload, payload_size, &c->rptr) < 0) {
  842.             /* cannot read all the payload */
  843.             free(payload);
  844.             c->rptr = start_rptr;
  845.             return 0;
  846.         }
  847.         
  848.         c->last_http_fifo_write_count = http_fifo_write_count - 
  849.             fifo_size(&http_fifo, c->rptr);
  850.         
  851.         if (c->stream->stream_type != STREAM_TYPE_MASTER) {
  852.             /* test if the packet can be handled by this format */
  853.             ret = 0;
  854.             if (test_header(&hdr, c->fmt_ctx.audio_enc)) {
  855.                 /* only begin sending when got a key frame */
  856.                 if (c->fmt_ctx.audio_enc->key_frame)
  857.                     c->got_key_frame[1] = 1;
  858.                 if (c->got_key_frame[1]) {
  859.                     ret = c->fmt_ctx.format->write_audio_frame(&c->fmt_ctx, 
  860.                                                                payload, payload_size);
  861.                 }
  862.             } else if (test_header(&hdr, c->fmt_ctx.video_enc)) {
  863.                 if (c->fmt_ctx.video_enc->key_frame)
  864.                     c->got_key_frame[0] = 1;
  865.                 if (c->got_key_frame[0]) {
  866.                     ret = c->fmt_ctx.format->write_video_picture(&c->fmt_ctx, 
  867.                                                                  payload, payload_size);
  868.                 }
  869.             }
  870.             if (ret) {
  871.                 /* must send trailer now */
  872.                 c->state = HTTPSTATE_SEND_DATA_TRAILER;
  873.             }
  874.         } else {
  875.             /* master case : send everything */
  876.             char *q;
  877.             q = c->buffer;
  878.             memcpy(q, &hdr, sizeof(hdr));
  879.             q += sizeof(hdr);
  880.             memcpy(q, payload, payload_size);
  881.             q += payload_size;
  882.             c->buffer_ptr = c->buffer;
  883.             c->buffer_end = q;
  884.         }
  885.         free(payload);
  886.         break;
  887.     default:
  888.     case HTTPSTATE_SEND_DATA_TRAILER:
  889.         /* last packet test ? */
  890.         if (c->last_packet_sent)
  891.             return -1;
  892.         /* prepare header */
  893.         c->fmt_ctx.format->write_trailer(&c->fmt_ctx);
  894.         c->last_packet_sent = 1;
  895.         break;
  896.     }
  897.     return 0;
  898. }
  899. /* should convert the format at the same time */
  900. static int http_send_data(HTTPContext *c)
  901. {
  902.     int len;
  903.     while (c->buffer_ptr >= c->buffer_end) {
  904.         if (http_prepare_data(c) < 0)
  905.             return -1;
  906.     }
  907.     len = write(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr);
  908.     if (len < 0) {
  909.         if (errno != EAGAIN && errno != EINTR) {
  910.             /* error : close connection */
  911.             return -1;
  912.         }
  913.     } else {
  914.         c->buffer_ptr += len;
  915.         c->data_count += len;
  916.     }
  917.     return 0;
  918. }
  919. static int master_receive(int fd)
  920. {
  921.     int len, size;
  922.     FifoBuffer *f = &http_fifo;
  923.     UINT8 *rptr;
  924.     size = f->end - f->wptr;
  925.     if (size > master_count)
  926.         size = master_count;
  927.     len = read(fd, f->wptr, size);
  928.     if (len == -1) {
  929.         if (errno != EAGAIN && errno != EINTR) 
  930.             return -1;
  931.     } else if (len == 0) {
  932.         return -1;
  933.     } else {
  934.         master_wptr += len;
  935.         if (master_wptr >= f->end)
  936.             master_wptr = f->buffer;
  937.         master_count -= len;
  938.         if (master_count == 0) {
  939.             if (master_state == MASTERSTATE_RECEIVE_HEADER) {
  940.                 /* XXX: use generic fifo read to extract packet header */
  941.                 rptr = master_wptr;
  942.                 if (rptr == f->buffer)
  943.                     rptr = f->end - 1;
  944.                 else
  945.                     rptr--;
  946.                 master_count = *rptr;
  947.                 if (rptr == f->buffer)
  948.                     rptr = f->end - 1;
  949.                 else
  950.                     rptr--;
  951.                 master_count |= *rptr << 8;
  952.                 master_state = MASTERSTATE_RECEIVE_DATA;
  953.             } else {
  954.                 /* update fifo wptr */
  955.                 f->wptr = master_wptr;
  956.                 master_state = MASTERSTATE_RECEIVE_HEADER;
  957.             }
  958.         }
  959.     }
  960.     return 0;
  961. }
  962. static void get_arg(char *buf, int buf_size, const char **pp)
  963. {
  964.     const char *p;
  965.     char *q;
  966.     p = *pp;
  967.     while (isspace(*p)) p++;
  968.     q = buf;
  969.     while (!isspace(*p) && *p != '') {
  970.         if ((q - buf) < buf_size - 1)
  971.             *q++ = *p;
  972.         p++;
  973.     }
  974.     *q = '';
  975.     *pp = p;
  976. }
  977. /* add a codec and check if it does not already exists */
  978. AVEncodeContext *add_codec(int codec_id,
  979.                            AVEncodeContext *av)
  980. {
  981.     AVEncoder *codec;
  982.     FFCodec *ctx, **pctx;
  983.     AVEncodeContext *av1;
  984.     codec = avencoder_find(codec_id);
  985.     if (!codec)
  986.         return NULL;
  987.     /* compute default parameters */
  988.     av->codec = codec;
  989.     switch(codec->type) {
  990.     case CODEC_TYPE_AUDIO:
  991.         if (av->bit_rate == 0)
  992.             av->bit_rate = 64000;
  993.         if (av->rate == 0)
  994.             av->rate = 22050;
  995.         if (av->channels == 0)
  996.             av->channels = 1;
  997.         break;
  998.     case CODEC_TYPE_VIDEO:
  999.         if (av->bit_rate == 0)
  1000.             av->bit_rate = 64000;
  1001.         if (av->rate == 0)
  1002.             av->rate = 5;
  1003.         if (av->width == 0 || av->height == 0) {
  1004.             av->width = 160;
  1005.             av->height = 128;
  1006.         }
  1007.         break;
  1008.     }
  1009.     /* find if the codec already exists */
  1010.     pctx = &first_codec;
  1011.     while (*pctx != NULL) {
  1012.         av1 = &(*pctx)->enc;
  1013.         if (av1->codec == av->codec &&
  1014.             av1->bit_rate == av->bit_rate &&
  1015.             av1->rate == av->rate) {
  1016.             switch(av->codec->type) {
  1017.             case CODEC_TYPE_AUDIO:
  1018.                 if (av1->channels == av->channels)
  1019.                     goto found;
  1020.                 break;
  1021.             case CODEC_TYPE_VIDEO:
  1022.                 if (av1->width == av->width &&
  1023.                     av1->height == av->height &&
  1024.                     av1->gop_size == av->gop_size)
  1025.                     goto found;
  1026.                 break;
  1027.             }
  1028.         }
  1029.         pctx = &(*pctx)->next;
  1030.     }
  1031.     ctx = malloc(sizeof(FFCodec));
  1032.     if (!ctx)
  1033.         return NULL;
  1034.     memset(ctx, 0, sizeof(FFCodec));
  1035.     *pctx = ctx;
  1036.     
  1037.     memcpy(&ctx->enc, av, sizeof(AVEncodeContext));
  1038.     return &ctx->enc;
  1039.  found:
  1040.     ctx = *pctx;
  1041.     return &ctx->enc;
  1042. }
  1043. int parse_ffconfig(const char *filename)
  1044. {
  1045.     FILE *f;
  1046.     char line[1024];
  1047.     char cmd[64];
  1048.     char arg[1024];
  1049.     const char *p;
  1050.     int val, errors, line_num;
  1051.     FFStream **last_stream, *stream;
  1052.     AVEncodeContext audio_enc, video_enc;
  1053.     f = fopen(filename, "r");
  1054.     if (!f) {
  1055.         perror(filename);
  1056.         return -1;
  1057.     }
  1058.     
  1059.     errors = 0;
  1060.     line_num = 0;
  1061.     first_stream = NULL;
  1062.     first_codec = NULL;
  1063.     last_stream = &first_stream;
  1064.     stream = NULL;
  1065.     for(;;) {
  1066.         if (fgets(line, sizeof(line), f) == NULL)
  1067.             break;
  1068.         line_num++;
  1069.         p = line;
  1070.         while (isspace(*p)) 
  1071.             p++;
  1072.         if (*p == '' || *p == '#')
  1073.             continue;
  1074.         get_arg(cmd, sizeof(cmd), &p);
  1075.         
  1076.         if (!strcasecmp(cmd, "Port")) {
  1077.             get_arg(arg, sizeof(arg), &p);
  1078.             my_addr.sin_port = htons (atoi(arg));
  1079.         } else if (!strcasecmp(cmd, "BindAddress")) {
  1080.             get_arg(arg, sizeof(arg), &p);
  1081.             if (!inet_aton(arg, &my_addr.sin_addr)) {
  1082.                 fprintf(stderr, "%s:%d: Invalid IP address: %sn", 
  1083.                         filename, line_num, arg);
  1084.                 errors++;
  1085.             }
  1086.         } else if (!strcasecmp(cmd, "MasterServer")) {
  1087.             get_arg(master_url, sizeof(master_url), &p);
  1088.             if (!strstart(master_url, "http://", NULL)) {
  1089.                 fprintf(stderr, "%s:%d: Invalid URL for master server: %sn", 
  1090.                         filename, line_num, master_url);
  1091.                 errors++;
  1092.             }
  1093.         } else if (!strcasecmp(cmd, "AudioDevice")) {
  1094.             get_arg(arg, sizeof(arg), &p);
  1095.             audio_device = strdup(arg);
  1096.         } else if (!strcasecmp(cmd, "VideoDevice")) {
  1097.             get_arg(arg, sizeof(arg), &p);
  1098.             v4l_device = strdup(arg);
  1099.         } else if (!strcasecmp(cmd, "MaxClients")) {
  1100.             get_arg(arg, sizeof(arg), &p);
  1101.             val = atoi(arg);
  1102.             if (val < 1 || val > HTTP_MAX_CONNECTIONS) {
  1103.                 fprintf(stderr, "%s:%d: Invalid MaxClients: %sn", 
  1104.                         filename, line_num, arg);
  1105.                 errors++;
  1106.             } else {
  1107.                 nb_max_connections = val;
  1108.             }
  1109.         } else if (!strcasecmp(cmd, "CustomLog")) {
  1110.             get_arg(logfilename, sizeof(logfilename), &p);
  1111.         } else if (!strcasecmp(cmd, "<Stream")) {
  1112.             char *q;
  1113.             if (stream) {
  1114.                 fprintf(stderr, "%s:%d: Already in a stream tagn",
  1115.                         filename, line_num);
  1116.             } else {
  1117.                 stream = malloc(sizeof(FFStream));
  1118.                 memset(stream, 0, sizeof(FFStream));
  1119.                 *last_stream = stream;
  1120.                 last_stream = &stream->next;
  1121.                 get_arg(stream->filename, sizeof(stream->filename), &p);
  1122.                 q = strrchr(stream->filename, '>');
  1123.                 if (*q)
  1124.                     *q = '';
  1125.                 stream->fmt = guess_format(NULL, stream->filename, NULL);
  1126.                 memset(&audio_enc, 0, sizeof(AVEncodeContext));
  1127.                 memset(&video_enc, 0, sizeof(AVEncodeContext));
  1128.             }
  1129.         } else if (!strcasecmp(cmd, "Format")) {
  1130.             get_arg(arg, sizeof(arg), &p);
  1131.             if (!strcmp(arg, "master")) {
  1132.                 stream->stream_type = STREAM_TYPE_MASTER;
  1133.                 stream->fmt = NULL;
  1134.             } else if (!strcmp(arg, "status")) {
  1135.                 stream->stream_type = STREAM_TYPE_STATUS;
  1136.                 stream->fmt = NULL;
  1137.             } else {
  1138.                 stream->stream_type = STREAM_TYPE_LIVE;
  1139.                 stream->fmt = guess_format(arg, NULL, NULL);
  1140.                 if (!stream->fmt) {
  1141.                     fprintf(stderr, "%s:%d: Unknown Format: %sn", 
  1142.                             filename, line_num, arg);
  1143.                     errors++;
  1144.                 }
  1145.             }
  1146.         } else if (!strcasecmp(cmd, "AudioBitRate")) {
  1147.             get_arg(arg, sizeof(arg), &p);
  1148.             if (stream) {
  1149.                 audio_enc.bit_rate = atoi(arg) * 1000;
  1150.             }
  1151.         } else if (!strcasecmp(cmd, "AudioChannels")) {
  1152.             get_arg(arg, sizeof(arg), &p);
  1153.             if (stream) {
  1154.                 audio_enc.channels = atoi(arg);
  1155.             }
  1156.         } else if (!strcasecmp(cmd, "AudioSampleRate")) {
  1157.             get_arg(arg, sizeof(arg), &p);
  1158.             if (stream) {
  1159.                 audio_enc.rate = atoi(arg);
  1160.             }
  1161.         } else if (!strcasecmp(cmd, "VideoBitRate")) {
  1162.             get_arg(arg, sizeof(arg), &p);
  1163.             if (stream) {
  1164.                 video_enc.bit_rate = atoi(arg) * 1000;
  1165.             }
  1166.         } else if (!strcasecmp(cmd, "VideoFrameRate")) {
  1167.             get_arg(arg, sizeof(arg), &p);
  1168.             if (stream) {
  1169.                 video_enc.rate = atoi(arg);
  1170.             }
  1171.         } else if (!strcasecmp(cmd, "VideoGopSize")) {
  1172.             get_arg(arg, sizeof(arg), &p);
  1173.             if (stream) {
  1174.                 video_enc.gop_size = atoi(arg);
  1175.             }
  1176.         } else if (!strcasecmp(cmd, "VideoIntraOnly")) {
  1177.             if (stream) {
  1178.                 video_enc.gop_size = 1;
  1179.             }
  1180.         } else if (!strcasecmp(cmd, "</Stream>")) {
  1181.             if (!stream) {
  1182.                 fprintf(stderr, "%s:%d: No corresponding <Stream> for </Stream>n",
  1183.                         filename, line_num);
  1184.                 errors++;
  1185.             }
  1186.             if (stream->fmt) {
  1187.                 if (stream->fmt->audio_codec != CODEC_ID_NONE) {
  1188.                     stream->audio_enc = add_codec(stream->fmt->audio_codec,
  1189.                                                   &audio_enc);
  1190.                 }
  1191.                 
  1192.                 if (stream->fmt->video_codec != CODEC_ID_NONE)
  1193.                     stream->video_enc = add_codec(stream->fmt->video_codec,
  1194.                                                   &video_enc);
  1195.             }
  1196.             stream = NULL;
  1197.         } else {
  1198.             fprintf(stderr, "%s:%d: Incorrect keyword: '%s'n", 
  1199.                     filename, line_num, cmd);
  1200.             errors++;
  1201.         }
  1202.     }
  1203.     fclose(f);
  1204.     if (errors)
  1205.         return -1;
  1206.     else
  1207.         return 0;
  1208. }
  1209. void *http_server_thread(void *arg)
  1210. {
  1211.     http_server(my_addr);
  1212.     return NULL;
  1213. }
  1214. static void write_packet(FFCodec *ffenc,
  1215.                          UINT8 *buf, int size)
  1216. {
  1217.     PacketHeader hdr;
  1218.     AVEncodeContext *enc = &ffenc->enc;
  1219.     UINT8 *wptr;
  1220.     mk_header(&hdr, enc, size);
  1221.     wptr = http_fifo.wptr;
  1222.     fifo_write(&http_fifo, (UINT8 *)&hdr, sizeof(hdr), &wptr);
  1223.     fifo_write(&http_fifo, buf, size, &wptr);
  1224.     /* atomic modification of wptr */
  1225.     http_fifo.wptr = wptr;
  1226.     ffenc->data_count += size;
  1227.     ffenc->avg_frame_size = ffenc->avg_frame_size * AVG_COEF + size * (1.0 - AVG_COEF);
  1228. }
  1229. #define AUDIO_FIFO_SIZE 8192
  1230. int av_grab(void)
  1231. {
  1232.     UINT8 audio_buf[AUDIO_FIFO_SIZE/2];
  1233.     UINT8 audio_buf1[AUDIO_FIFO_SIZE/2];
  1234.     UINT8 audio_out[AUDIO_FIFO_SIZE/2];
  1235.     UINT8 video_buffer[128*1024];
  1236.     char buf[256];
  1237.     short *samples;
  1238.     int ret;
  1239.     int audio_fd;
  1240.     FFCodec *ffenc;
  1241.     AVEncodeContext *enc;
  1242.     int frame_size, frame_bytes;
  1243.     int use_audio, use_video;
  1244.     int frame_rate, sample_rate, channels;
  1245.     int width, height, frame_number;
  1246.     UINT8 *picture[3];
  1247.     use_audio = 0;
  1248.     use_video = 0;
  1249.     frame_rate = 0;
  1250.     sample_rate = 0;
  1251.     frame_size = 0;
  1252.     channels = 1;
  1253.     width = 0;
  1254.     height = 0;
  1255.     frame_number = 0;
  1256.     ffenc = first_codec;
  1257.     while (ffenc != NULL) {
  1258.         enc = &ffenc->enc;
  1259.         avencoder_string(buf, sizeof(buf), enc);
  1260.         fprintf(stderr, "  %sn", buf);
  1261.         if (avencoder_open(enc, enc->codec) < 0) {
  1262.             fprintf(stderr, "Incorrect encode parametersn");
  1263.             return -1;
  1264.         }
  1265.         switch(enc->codec->type) {
  1266.         case CODEC_TYPE_AUDIO:
  1267.             use_audio = 1;
  1268.             if (enc->rate > sample_rate)
  1269.                 sample_rate = enc->rate;
  1270.             if (enc->frame_size > frame_size)
  1271.                 frame_size = enc->frame_size;
  1272.             if (enc->channels > channels)
  1273.                 channels = enc->channels;
  1274.             fifo_init(&ffenc->fifo, AUDIO_FIFO_SIZE);
  1275.             break;
  1276.         case CODEC_TYPE_VIDEO:
  1277.             use_video = 1;
  1278.             if (enc->rate > frame_rate)
  1279.                 frame_rate = enc->rate;
  1280.             if (enc->width > width)
  1281.                 width = enc->width;
  1282.             if (enc->height > height)
  1283.                 height = enc->height;
  1284.             break;
  1285.         }
  1286.         ffenc = ffenc->next;
  1287.     }
  1288.     /* audio */
  1289.     samples = NULL;
  1290.     audio_fd = -1;
  1291.     if (use_audio) {
  1292.         printf("Audio sampling: %d Hz, %sn", 
  1293.                sample_rate, channels == 2 ? "stereo" : "mono");
  1294.         audio_fd = audio_open(sample_rate, channels);
  1295.         if (audio_fd < 0) {
  1296.             fprintf(stderr, "Could not open audio devicen");
  1297.             exit(1);
  1298.         }
  1299.     }
  1300.     
  1301.     ffenc = first_codec;
  1302.     while (ffenc != NULL) {
  1303.         enc = &ffenc->enc;
  1304.         if (enc->codec->type == CODEC_TYPE_AUDIO &&
  1305.             (enc->channels != channels ||
  1306.              enc->rate != sample_rate)) {
  1307.             audio_resample_init(&ffenc->resample, enc->channels, channels,
  1308.                                 enc->rate, sample_rate);
  1309.         }
  1310.         ffenc = ffenc->next;
  1311.     }
  1312.     /* video */
  1313.     if (use_video) {
  1314.         printf("Video sampling: %dx%d, %d fpsn", 
  1315.                width, height, frame_rate);
  1316.         ret = v4l_init(frame_rate, width, height);
  1317.         if (ret < 0) {
  1318.             fprintf(stderr,"Could not init video 4 linux capturen");
  1319.             exit(1);
  1320.         }
  1321.     }
  1322.     for(;;) {
  1323.         /* read & compress audio frames */
  1324.         if (use_audio) {
  1325.             int ret, nb_samples, nb_samples_out;
  1326.             UINT8 *buftmp;
  1327.             for(;;) {
  1328.                 ret = read(audio_fd, audio_buf, AUDIO_FIFO_SIZE/2);
  1329.                 if (ret <= 0)
  1330.                     break;
  1331.                 /* fill each codec fifo by doing the right sample
  1332.                    rate conversion. This is not optimal because we
  1333.                    do too much work, but it is easy to do */
  1334.                 nb_samples = ret / (channels * 2);
  1335.                 ffenc = first_codec;
  1336.                 while (ffenc != NULL) {
  1337.                     enc = &ffenc->enc;
  1338.                     if (enc->codec->type == CODEC_TYPE_AUDIO) {
  1339.                         /* rate & stereo convertion */
  1340.                         if (enc->channels == channels &&
  1341.                             enc->rate == sample_rate) {
  1342.                             buftmp = audio_buf;
  1343.                             nb_samples_out = nb_samples;
  1344.                         } else {
  1345.                             buftmp = audio_buf1;
  1346.                             nb_samples_out = audio_resample(&ffenc->resample, 
  1347.                                                             (short *)buftmp, (short *)audio_buf,
  1348.                                                             nb_samples);
  1349.                             
  1350.                         }
  1351.                         fifo_write(&ffenc->fifo, buftmp, nb_samples_out * enc->channels * 2, 
  1352.                                    &ffenc->fifo.wptr);
  1353.                     }
  1354.                     ffenc = ffenc->next;
  1355.                 }
  1356.                 
  1357.                 /* compress as many frame as possible with each audio codec */
  1358.                 ffenc = first_codec;
  1359.                 while (ffenc != NULL) {
  1360.                     enc = &ffenc->enc;
  1361.                     if (enc->codec->type == CODEC_TYPE_AUDIO) {
  1362.                         frame_bytes = enc->frame_size * 2 * enc->channels;
  1363.                         
  1364.                         while (fifo_read(&ffenc->fifo, audio_buf, frame_bytes, &ffenc->fifo.rptr) == 0) {
  1365.                             ret = avencoder_encode(enc,
  1366.                                                    audio_out, sizeof(audio_out), audio_buf);
  1367.                             write_packet(ffenc, audio_out, ret);
  1368.                         }
  1369.                     }
  1370.                     ffenc = ffenc->next;
  1371.                 }
  1372.             }
  1373.         }
  1374.         if (use_video) {
  1375.             ret = v4l_read_picture (picture, width, height, 
  1376.                                     frame_number);
  1377.             if (ret < 0)
  1378.                 break;
  1379.             ffenc = first_codec;
  1380.             while (ffenc != NULL) {
  1381.                 enc = &ffenc->enc;
  1382.                 if (enc->codec->type == CODEC_TYPE_VIDEO) {
  1383.                     int n1, n2;
  1384.                     /* feed each codec with its requested frame rate */
  1385.                     n1 = (frame_number * enc->rate) / frame_rate;
  1386.                     n2 = ((frame_number + 1) * enc->rate) / frame_rate;
  1387.                     if (n2 > n1) {
  1388.                         ret = avencoder_encode(enc, video_buffer, sizeof(video_buffer), picture);
  1389.                         write_packet(ffenc, video_buffer, ret);
  1390.                     }
  1391.                 }
  1392.                 ffenc = ffenc->next;
  1393.             }
  1394.             frame_number++;
  1395.         }
  1396.     }
  1397.     
  1398.     ffenc = first_codec;
  1399.     while (ffenc != NULL) {
  1400.         enc = &ffenc->enc;
  1401.         avencoder_close(enc);
  1402.         ffenc = ffenc->next;
  1403.     }
  1404.     close(audio_fd);
  1405.     return 0;
  1406. }
  1407. void help(void)
  1408. {
  1409.     printf("ffserver version " FFMPEG_VERSION ", Copyright (c) 2000,2001 Gerard Lantaun"
  1410.            "usage: ffserver [-L] [-h] [-f configfile]n"
  1411.            "Hyper fast multi format Audio/Video streaming servern"
  1412.            "n"
  1413.            "-L            : print the LICENCEn"
  1414.            "-h            : this helpn"
  1415.            "-f configfile : use configfile instead of /etc/ffserver.confn"
  1416.            );
  1417. }
  1418. void licence(void)
  1419. {
  1420.     printf(
  1421.     "ffserver version " FFMPEG_VERSION "n"
  1422.     "Copyright (c) 2000,2001 Gerard Lantaun"
  1423.     "This program is free software; you can redistribute it and/or modifyn"
  1424.     "it under the terms of the GNU General Public License as published byn"
  1425.     "the Free Software Foundation; either version 2 of the License, orn"
  1426.     "(at your option) any later version.n"
  1427.     "n"
  1428.     "This program is distributed in the hope that it will be useful,n"
  1429.     "but WITHOUT ANY WARRANTY; without even the implied warranty ofn"
  1430.     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See then"
  1431.     "GNU General Public License for more details.n"
  1432.     "n"
  1433.     "You should have received a copy of the GNU General Public Licensen"
  1434.     "along with this program; if not, write to the Free Softwaren"
  1435.     "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.n"
  1436.     );
  1437. }
  1438. int main(int argc, char **argv)
  1439. {
  1440.     pthread_t http_server_tid;
  1441.     const char *config_filename;
  1442.     int c;
  1443.     /* codecs */
  1444.     register_avencoder(&ac3_encoder);
  1445.     register_avencoder(&mp2_encoder);
  1446.     register_avencoder(&mpeg1video_encoder);
  1447.     register_avencoder(&h263_encoder);
  1448.     register_avencoder(&rv10_encoder);
  1449.     register_avencoder(&mjpeg_encoder);
  1450.     register_avencoder(&divx_encoder);
  1451.     /* audio video formats */
  1452.     register_avformat(&mp2_format);
  1453.     register_avformat(&ac3_format);
  1454.     register_avformat(&mpeg_mux_format);
  1455.     register_avformat(&mpeg1video_format);
  1456.     register_avformat(&h263_format);
  1457.     register_avformat(&rm_format);
  1458.     register_avformat(&ra_format);
  1459.     register_avformat(&asf_format);
  1460.     register_avformat(&avi_format);
  1461.     register_avformat(&mpjpeg_format);
  1462.     register_avformat(&jpeg_format);
  1463.     register_avformat(&swf_format);
  1464.     config_filename = "/etc/ffserver.conf";
  1465.     for(;;) {
  1466.         c = getopt_long_only(argc, argv, "Lh?f:", NULL, NULL);
  1467.         if (c == -1)
  1468.             break;
  1469.         switch(c) {
  1470.         case 'L':
  1471.             licence();
  1472.             exit(1);
  1473.         case '?':
  1474.         case 'h':
  1475.             help();
  1476.             exit(1);
  1477.         case 'f':
  1478.             config_filename = optarg;
  1479.             break;
  1480.         default:
  1481.             exit(2);
  1482.         }
  1483.     }
  1484.     /* address on which the server will handle connections */
  1485.     my_addr.sin_family = AF_INET;
  1486.     my_addr.sin_port = htons (8080);
  1487.     my_addr.sin_addr.s_addr = htonl (INADDR_ANY);
  1488.     nb_max_connections = 5;
  1489.     first_stream = NULL;
  1490.     logfilename[0] = '';
  1491.     if (parse_ffconfig(config_filename) < 0) {
  1492.         fprintf(stderr, "Incorrect config file - exiting.n");
  1493.         exit(1);
  1494.     }
  1495.     /* signal init */
  1496.     signal(SIGPIPE, SIG_IGN);
  1497.     /* open log file if needed */
  1498.     if (logfilename[0] != '') {
  1499.         if (!strcmp(logfilename, "-"))
  1500.             logfile = stdout;
  1501.         else
  1502.             logfile = fopen(logfilename, "w");
  1503.     }
  1504.     /* init fifo */
  1505.     http_fifo_write_count = 0;
  1506.     if (fifo_init(&http_fifo, FIFO_MAX_SIZE) < 0) {
  1507.         fprintf(stderr, "Could not allow receive fifon");
  1508.         exit(1);
  1509.     }
  1510.     if (master_url[0] == '') {
  1511.         /* no master server: we grab ourself */
  1512.         /* launch server thread */
  1513.         if (pthread_create(&http_server_tid, NULL, 
  1514.                            http_server_thread, NULL) != 0) {
  1515.             fprintf(stderr, "Could not create http server threadn");
  1516.             exit(1);
  1517.         }
  1518.         /* launch the audio / video grab */
  1519.         if (av_grab() < 0) {
  1520.             fprintf(stderr, "Could not start audio/video grabn");
  1521.             exit(1);
  1522.         }
  1523.     } else {
  1524.         /* master server : no thread are needed */
  1525.         if (http_server(my_addr) < 0) {
  1526.             fprintf(stderr, "Could start http servern");
  1527.             exit(1);
  1528.         }
  1529.     }
  1530.     return 0;
  1531. }