You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1643 lines
48KB

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