Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: patched-ffmpeg-mt/ffserver.c

Issue 789004: ffmpeg roll of source to mar 9 version... (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/ffmpeg/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Multiple format streaming server 2 * Multiple format streaming server
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4 * 4 *
5 * This file is part of FFmpeg. 5 * This file is part of FFmpeg.
6 * 6 *
7 * FFmpeg is free software; you can redistribute it and/or 7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version. 10 * version 2.1 of the License, or (at your option) any later version.
(...skipping 10 matching lines...) Expand all
21 21
22 #define _XOPEN_SOURCE 600 22 #define _XOPEN_SOURCE 600
23 23
24 #include "config.h" 24 #include "config.h"
25 #if !HAVE_CLOSESOCKET 25 #if !HAVE_CLOSESOCKET
26 #define closesocket close 26 #define closesocket close
27 #endif 27 #endif
28 #include <string.h> 28 #include <string.h>
29 #include <strings.h> 29 #include <strings.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 /* avformat.h defines LIBAVFORMAT_BUILD, include it before all the other libav* headers which use it */
32 #include "libavformat/avformat.h" 31 #include "libavformat/avformat.h"
33 #include "libavformat/network.h" 32 #include "libavformat/network.h"
34 #include "libavformat/os_support.h" 33 #include "libavformat/os_support.h"
35 #include "libavformat/rtpdec.h" 34 #include "libavformat/rtpdec.h"
36 #include "libavformat/rtsp.h" 35 #include "libavformat/rtsp.h"
37 #include "libavutil/avstring.h" 36 #include "libavutil/avstring.h"
38 #include "libavutil/lfg.h" 37 #include "libavutil/lfg.h"
39 #include "libavutil/random_seed.h" 38 #include "libavutil/random_seed.h"
40 #include "libavutil/intreadwrite.h"
41 #include "libavcodec/opt.h" 39 #include "libavcodec/opt.h"
42 #include <stdarg.h> 40 #include <stdarg.h>
43 #include <unistd.h> 41 #include <unistd.h>
44 #include <fcntl.h> 42 #include <fcntl.h>
45 #include <sys/ioctl.h> 43 #include <sys/ioctl.h>
46 #if HAVE_POLL_H 44 #if HAVE_POLL_H
47 #include <poll.h> 45 #include <poll.h>
48 #endif 46 #endif
49 #include <errno.h> 47 #include <errno.h>
50 #include <sys/time.h> 48 #include <sys/time.h>
51 #undef time //needed because HAVE_AV_CONFIG_H is defined on top
52 #include <time.h> 49 #include <time.h>
53 #include <sys/wait.h> 50 #include <sys/wait.h>
54 #include <signal.h> 51 #include <signal.h>
55 #if HAVE_DLFCN_H 52 #if HAVE_DLFCN_H
56 #include <dlfcn.h> 53 #include <dlfcn.h>
57 #endif 54 #endif
58 55
59 #include "cmdutils.h" 56 #include "cmdutils.h"
60 57
61 #undef exit
62
63 const char program_name[] = "FFserver"; 58 const char program_name[] = "FFserver";
64 const int program_birth_year = 2000; 59 const int program_birth_year = 2000;
65 60
66 static const OptionDef options[]; 61 static const OptionDef options[];
67 62
68 enum HTTPState { 63 enum HTTPState {
69 HTTPSTATE_WAIT_REQUEST, 64 HTTPSTATE_WAIT_REQUEST,
70 HTTPSTATE_SEND_HEADER, 65 HTTPSTATE_SEND_HEADER,
71 HTTPSTATE_SEND_DATA_HEADER, 66 HTTPSTATE_SEND_DATA_HEADER,
72 HTTPSTATE_SEND_DATA, /* sending TCP or UDP data */ 67 HTTPSTATE_SEND_DATA, /* sending TCP or UDP data */
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 /* context associated with one connection */ 112 /* context associated with one connection */
118 typedef struct HTTPContext { 113 typedef struct HTTPContext {
119 enum HTTPState state; 114 enum HTTPState state;
120 int fd; /* socket file descriptor */ 115 int fd; /* socket file descriptor */
121 struct sockaddr_in from_addr; /* origin */ 116 struct sockaddr_in from_addr; /* origin */
122 struct pollfd *poll_entry; /* used when polling */ 117 struct pollfd *poll_entry; /* used when polling */
123 int64_t timeout; 118 int64_t timeout;
124 uint8_t *buffer_ptr, *buffer_end; 119 uint8_t *buffer_ptr, *buffer_end;
125 int http_error; 120 int http_error;
126 int post; 121 int post;
122 int chunked_encoding;
123 int chunk_size; /* 0 if it needs to be read */
127 struct HTTPContext *next; 124 struct HTTPContext *next;
128 int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */ 125 int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
129 int64_t data_count; 126 int64_t data_count;
130 /* feed input */ 127 /* feed input */
131 int feed_fd; 128 int feed_fd;
132 /* input format handling */ 129 /* input format handling */
133 AVFormatContext *fmt_in; 130 AVFormatContext *fmt_in;
134 int64_t start_time; /* In milliseconds - this wraps fairly often */ 131 int64_t start_time; /* In milliseconds - this wraps fairly often */
135 int64_t first_pts; /* initial pts value */ 132 int64_t first_pts; /* initial pts value */
136 int64_t cur_pts; /* current pts value from the stream in us */ 133 int64_t cur_pts; /* current pts value from the stream in us */
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 305
309 static uint64_t max_bandwidth = 1000; 306 static uint64_t max_bandwidth = 1000;
310 static uint64_t current_bandwidth; 307 static uint64_t current_bandwidth;
311 308
312 static int64_t cur_time; // Making this global saves on passing it aro und everywhere 309 static int64_t cur_time; // Making this global saves on passing it aro und everywhere
313 310
314 static AVLFG random_state; 311 static AVLFG random_state;
315 312
316 static FILE *logfile = NULL; 313 static FILE *logfile = NULL;
317 314
315 /* FIXME: make ffserver work with IPv6 */
316 /* resolve host with also IP address parsing */
317 static int resolve_host(struct in_addr *sin_addr, const char *hostname)
318 {
319
320 if (!ff_inet_aton(hostname, sin_addr)) {
321 #if HAVE_GETADDRINFO
322 struct addrinfo *ai, *cur;
323 struct addrinfo hints;
324 memset(&hints, 0, sizeof(hints));
325 hints.ai_family = AF_INET;
326 if (getaddrinfo(hostname, NULL, &hints, &ai))
327 return -1;
328 /* getaddrinfo returns a linked list of addrinfo structs.
329 * Even if we set ai_family = AF_INET above, make sure
330 * that the returned one actually is of the correct type. */
331 for (cur = ai; cur; cur = cur->ai_next) {
332 if (cur->ai_family == AF_INET) {
333 *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr;
334 freeaddrinfo(ai);
335 return 0;
336 }
337 }
338 freeaddrinfo(ai);
339 return -1;
340 #else
341 struct hostent *hp;
342 hp = gethostbyname(hostname);
343 if (!hp)
344 return -1;
345 memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
346 #endif
347 }
348 return 0;
349 }
350
318 static char *ctime1(char *buf2) 351 static char *ctime1(char *buf2)
319 { 352 {
320 time_t ti; 353 time_t ti;
321 char *p; 354 char *p;
322 355
323 ti = time(NULL); 356 ti = time(NULL);
324 p = ctime(&ti); 357 p = ctime(&ti);
325 strcpy(buf2, p); 358 strcpy(buf2, p);
326 p = buf2 + strlen(p) - 1; 359 p = buf2 + strlen(p) - 1;
327 if (*p == '\n') 360 if (*p == '\n')
(...skipping 2105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2433 } 2466 }
2434 2467
2435 c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZ E); 2468 c->stream->feed_write_index = FFMAX(ffm_read_write_index(fd), FFM_PACKET_SIZ E);
2436 c->stream->feed_size = lseek(fd, 0, SEEK_END); 2469 c->stream->feed_size = lseek(fd, 0, SEEK_END);
2437 lseek(fd, 0, SEEK_SET); 2470 lseek(fd, 0, SEEK_SET);
2438 2471
2439 /* init buffer input */ 2472 /* init buffer input */
2440 c->buffer_ptr = c->buffer; 2473 c->buffer_ptr = c->buffer;
2441 c->buffer_end = c->buffer + FFM_PACKET_SIZE; 2474 c->buffer_end = c->buffer + FFM_PACKET_SIZE;
2442 c->stream->feed_opened = 1; 2475 c->stream->feed_opened = 1;
2476 c->chunked_encoding = !!av_stristr(c->buffer, "Transfer-Encoding: chunked");
2443 return 0; 2477 return 0;
2444 } 2478 }
2445 2479
2446 static int http_receive_data(HTTPContext *c) 2480 static int http_receive_data(HTTPContext *c)
2447 { 2481 {
2448 HTTPContext *c1; 2482 HTTPContext *c1;
2483 int len, loop_run = 0;
2484
2485 while (c->chunked_encoding && !c->chunk_size &&
2486 c->buffer_end > c->buffer_ptr) {
2487 /* read chunk header, if present */
2488 len = recv(c->fd, c->buffer_ptr, 1, 0);
2489
2490 if (len < 0) {
2491 if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
2492 ff_neterrno() != FF_NETERROR(EINTR))
2493 /* error : close connection */
2494 goto fail;
2495 } else if (len == 0) {
2496 /* end of connection : close it */
2497 goto fail;
2498 } else if (c->buffer_ptr - c->buffer >= 2 &&
2499 !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
2500 c->chunk_size = strtol(c->buffer, 0, 16);
2501 if (c->chunk_size == 0) // end of stream
2502 goto fail;
2503 c->buffer_ptr = c->buffer;
2504 break;
2505 } else if (++loop_run > 10) {
2506 /* no chunk header, abort */
2507 goto fail;
2508 } else {
2509 c->buffer_ptr++;
2510 }
2511 }
2449 2512
2450 if (c->buffer_end > c->buffer_ptr) { 2513 if (c->buffer_end > c->buffer_ptr) {
2451 int len; 2514 len = recv(c->fd, c->buffer_ptr,
2452 2515 FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
2453 len = recv(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
2454 if (len < 0) { 2516 if (len < 0) {
2455 if (ff_neterrno() != FF_NETERROR(EAGAIN) && 2517 if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
2456 ff_neterrno() != FF_NETERROR(EINTR)) 2518 ff_neterrno() != FF_NETERROR(EINTR))
2457 /* error : close connection */ 2519 /* error : close connection */
2458 goto fail; 2520 goto fail;
2459 } else if (len == 0) 2521 } else if (len == 0)
2460 /* end of connection : close it */ 2522 /* end of connection : close it */
2461 goto fail; 2523 goto fail;
2462 else { 2524 else {
2525 c->chunk_size -= len;
2463 c->buffer_ptr += len; 2526 c->buffer_ptr += len;
2464 c->data_count += len; 2527 c->data_count += len;
2465 update_datarate(&c->datarate, c->data_count); 2528 update_datarate(&c->datarate, c->data_count);
2466 } 2529 }
2467 } 2530 }
2468 2531
2469 if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) { 2532 if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
2470 if (c->buffer[0] != 'f' || 2533 if (c->buffer[0] != 'f' ||
2471 c->buffer[1] != 'm') { 2534 c->buffer[1] != 'm') {
2472 http_log("Feed stream has become desynchronized -- disconnecting\n") ; 2535 http_log("Feed stream has become desynchronized -- disconnecting\n") ;
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
2686 if (p2 > p && p2[-1] == '\r') 2749 if (p2 > p && p2[-1] == '\r')
2687 p2--; 2750 p2--;
2688 /* skip empty line */ 2751 /* skip empty line */
2689 if (p2 == p) 2752 if (p2 == p)
2690 break; 2753 break;
2691 len = p2 - p; 2754 len = p2 - p;
2692 if (len > sizeof(line) - 1) 2755 if (len > sizeof(line) - 1)
2693 len = sizeof(line) - 1; 2756 len = sizeof(line) - 1;
2694 memcpy(line, p, len); 2757 memcpy(line, p, len);
2695 line[len] = '\0'; 2758 line[len] = '\0';
2696 rtsp_parse_line(header, line); 2759 ff_rtsp_parse_line(header, line);
2697 p = p1 + 1; 2760 p = p1 + 1;
2698 } 2761 }
2699 2762
2700 /* handle sequence number */ 2763 /* handle sequence number */
2701 c->seq = header->seq; 2764 c->seq = header->seq;
2702 2765
2703 if (!strcmp(cmd, "DESCRIBE")) 2766 if (!strcmp(cmd, "DESCRIBE"))
2704 rtsp_cmd_describe(c, url); 2767 rtsp_cmd_describe(c, url);
2705 else if (!strcmp(cmd, "OPTIONS")) 2768 else if (!strcmp(cmd, "OPTIONS"))
2706 rtsp_cmd_options(c, url); 2769 rtsp_cmd_options(c, url);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2771 static void rtsp_cmd_describe(HTTPContext *c, const char *url) 2834 static void rtsp_cmd_describe(HTTPContext *c, const char *url)
2772 { 2835 {
2773 FFStream *stream; 2836 FFStream *stream;
2774 char path1[1024]; 2837 char path1[1024];
2775 const char *path; 2838 const char *path;
2776 uint8_t *content; 2839 uint8_t *content;
2777 int content_length, len; 2840 int content_length, len;
2778 struct sockaddr_in my_addr; 2841 struct sockaddr_in my_addr;
2779 2842
2780 /* find which url is asked */ 2843 /* find which url is asked */
2781 url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url); 2844 ff_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
2782 path = path1; 2845 path = path1;
2783 if (*path == '/') 2846 if (*path == '/')
2784 path++; 2847 path++;
2785 2848
2786 for(stream = first_stream; stream != NULL; stream = stream->next) { 2849 for(stream = first_stream; stream != NULL; stream = stream->next) {
2787 if (!stream->is_feed && 2850 if (!stream->is_feed &&
2788 stream->fmt && !strcmp(stream->fmt->name, "rtp") && 2851 stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
2789 !strcmp(path, stream->filename)) { 2852 !strcmp(path, stream->filename)) {
2790 goto found; 2853 goto found;
2791 } 2854 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2846 int stream_index, port; 2909 int stream_index, port;
2847 char buf[1024]; 2910 char buf[1024];
2848 char path1[1024]; 2911 char path1[1024];
2849 const char *path; 2912 const char *path;
2850 HTTPContext *rtp_c; 2913 HTTPContext *rtp_c;
2851 RTSPTransportField *th; 2914 RTSPTransportField *th;
2852 struct sockaddr_in dest_addr; 2915 struct sockaddr_in dest_addr;
2853 RTSPActionServerSetup setup; 2916 RTSPActionServerSetup setup;
2854 2917
2855 /* find which url is asked */ 2918 /* find which url is asked */
2856 url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url); 2919 ff_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
2857 path = path1; 2920 path = path1;
2858 if (*path == '/') 2921 if (*path == '/')
2859 path++; 2922 path++;
2860 2923
2861 /* now check each stream */ 2924 /* now check each stream */
2862 for(stream = first_stream; stream != NULL; stream = stream->next) { 2925 for(stream = first_stream; stream != NULL; stream = stream->next) {
2863 if (!stream->is_feed && 2926 if (!stream->is_feed &&
2864 stream->fmt && !strcmp(stream->fmt->name, "rtp")) { 2927 stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
2865 /* accept aggregate filenames only if single stream */ 2928 /* accept aggregate filenames only if single stream */
2866 if (!strcmp(path, stream->filename)) { 2929 if (!strcmp(path, stream->filename)) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2988 char path1[1024]; 3051 char path1[1024];
2989 const char *path; 3052 const char *path;
2990 char buf[1024]; 3053 char buf[1024];
2991 int s; 3054 int s;
2992 3055
2993 rtp_c = find_rtp_session(session_id); 3056 rtp_c = find_rtp_session(session_id);
2994 if (!rtp_c) 3057 if (!rtp_c)
2995 return NULL; 3058 return NULL;
2996 3059
2997 /* find which url is asked */ 3060 /* find which url is asked */
2998 url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url); 3061 ff_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
2999 path = path1; 3062 path = path1;
3000 if (*path == '/') 3063 if (*path == '/')
3001 path++; 3064 path++;
3002 if(!strcmp(path, rtp_c->stream->filename)) return rtp_c; 3065 if(!strcmp(path, rtp_c->stream->filename)) return rtp_c;
3003 for(s=0; s<rtp_c->stream->nb_streams; ++s) { 3066 for(s=0; s<rtp_c->stream->nb_streams; ++s) {
3004 snprintf(buf, sizeof(buf), "%s/streamid=%d", 3067 snprintf(buf, sizeof(buf), "%s/streamid=%d",
3005 rtp_c->stream->filename, s); 3068 rtp_c->stream->filename, s);
3006 if(!strncmp(path, buf, sizeof(buf))) { 3069 if(!strncmp(path, buf, sizeof(buf))) {
3007 // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1? 3070 // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
3008 return rtp_c; 3071 return rtp_c;
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after
4216 avctx = &audio_enc; 4279 avctx = &audio_enc;
4217 type = AV_OPT_FLAG_AUDIO_PARAM; 4280 type = AV_OPT_FLAG_AUDIO_PARAM;
4218 } 4281 }
4219 if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING _PARAM)) { 4282 if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING _PARAM)) {
4220 fprintf(stderr, "AVOption error: %s %s\n", arg, arg2); 4283 fprintf(stderr, "AVOption error: %s %s\n", arg, arg2);
4221 errors++; 4284 errors++;
4222 } 4285 }
4223 } else if (!strcasecmp(cmd, "VideoTag")) { 4286 } else if (!strcasecmp(cmd, "VideoTag")) {
4224 get_arg(arg, sizeof(arg), &p); 4287 get_arg(arg, sizeof(arg), &p);
4225 if ((strlen(arg) == 4) && stream) 4288 if ((strlen(arg) == 4) && stream)
4226 video_enc.codec_tag = AV_RL32(arg); 4289 video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
4227 } else if (!strcasecmp(cmd, "BitExact")) { 4290 } else if (!strcasecmp(cmd, "BitExact")) {
4228 if (stream) 4291 if (stream)
4229 video_enc.flags |= CODEC_FLAG_BITEXACT; 4292 video_enc.flags |= CODEC_FLAG_BITEXACT;
4230 } else if (!strcasecmp(cmd, "DctFastint")) { 4293 } else if (!strcasecmp(cmd, "DctFastint")) {
4231 if (stream) 4294 if (stream)
4232 video_enc.dct_algo = FF_DCT_FASTINT; 4295 video_enc.dct_algo = FF_DCT_FASTINT;
4233 } else if (!strcasecmp(cmd, "IdctSimple")) { 4296 } else if (!strcasecmp(cmd, "IdctSimple")) {
4234 if (stream) 4297 if (stream)
4235 video_enc.idct_algo = FF_IDCT_SIMPLE; 4298 video_enc.idct_algo = FF_IDCT_SIMPLE;
4236 } else if (!strcasecmp(cmd, "Qscale")) { 4299 } else if (!strcasecmp(cmd, "Qscale")) {
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
4574 if (ffserver_daemon) 4637 if (ffserver_daemon)
4575 chdir("/"); 4638 chdir("/");
4576 4639
4577 if (http_server() < 0) { 4640 if (http_server() < 0) {
4578 http_log("Could not start server\n"); 4641 http_log("Could not start server\n");
4579 exit(1); 4642 exit(1);
4580 } 4643 }
4581 4644
4582 return 0; 4645 return 0;
4583 } 4646 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698