diff options
author | FlyingRat <flyingrat@outlook.com> | 2013-04-07 16:36:04 +0200 |
---|---|---|
committer | FlyingRat <flyingrat@outlook.com> | 2013-04-07 16:36:04 +0200 |
commit | 0e63a815aa6af63a21848e04b683d3f506dd41b1 (patch) | |
tree | 002f61d8a5b1d294d99fd4ba5b6982d76a612f0c /lib/ffmpeg/ffserver.c | |
parent | 71862137c5337fc678681a23bfbc65f4db7a7b2f (diff) |
[FFmpeg] version bump to n1.2 (rev e820e3a) - lib/ffmpeg
This commit now contains the original patches sub directory:
patches - Org dir that contains applied xbmc custom patches.
patches/README-patches - New README file with info about xbmc patches.
patches/obsolete-patches - New dir with obsolete xbmc patches.
Diffstat (limited to 'lib/ffmpeg/ffserver.c')
-rw-r--r-- | lib/ffmpeg/ffserver.c | 307 |
1 files changed, 166 insertions, 141 deletions
diff --git a/lib/ffmpeg/ffserver.c b/lib/ffmpeg/ffserver.c index 79463c0e64..eee83e5695 100644 --- a/lib/ffmpeg/ffserver.c +++ b/lib/ffmpeg/ffserver.c @@ -29,8 +29,9 @@ #endif #include <string.h> #include <stdlib.h> +#include <stdio.h> #include "libavformat/avformat.h" -// FIXME those are internal headers, avserver _really_ shouldn't use them +// FIXME those are internal headers, ffserver _really_ shouldn't use them #include "libavformat/ffm.h" #include "libavformat/network.h" #include "libavformat/os_support.h" @@ -40,13 +41,17 @@ #include "libavformat/internal.h" #include "libavformat/url.h" +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/lfg.h" #include "libavutil/dict.h" +#include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" #include "libavutil/random_seed.h" #include "libavutil/parseutils.h" #include "libavutil/opt.h" +#include "libavutil/time.h" + #include <stdarg.h> #include <unistd.h> #include <fcntl.h> @@ -55,7 +60,6 @@ #include <poll.h> #endif #include <errno.h> -#include <sys/time.h> #include <time.h> #include <sys/wait.h> #include <signal.h> @@ -303,12 +307,10 @@ static int rtp_new_av_stream(HTTPContext *c, HTTPContext *rtsp_c); static const char *my_program_name; -static const char *my_program_dir; static const char *config_filename = "/etc/ffserver.conf"; static int ffserver_debug; -static int ffserver_daemon; static int no_launch; static int need_to_start_children; @@ -326,12 +328,40 @@ static AVLFG random_state; static FILE *logfile = NULL; -/* FIXME: make ffserver work with IPv6 */ -void av_noreturn exit_program(int ret) +static int64_t ffm_read_write_index(int fd) +{ + uint8_t buf[8]; + + if (lseek(fd, 8, SEEK_SET) < 0) + return AVERROR(EIO); + if (read(fd, buf, 8) != 8) + return AVERROR(EIO); + return AV_RB64(buf); +} + +static int ffm_write_write_index(int fd, int64_t pos) { - exit(ret); + uint8_t buf[8]; + int i; + + for(i=0;i<8;i++) + buf[i] = (pos >> (56 - i * 8)) & 0xff; + if (lseek(fd, 8, SEEK_SET) < 0) + return AVERROR(EIO); + if (write(fd, buf, 8) != 8) + return AVERROR(EIO); + return 8; +} + +static void ffm_set_write_index(AVFormatContext *s, int64_t pos, + int64_t file_size) +{ + FFMContext *ffm = s->priv_data; + ffm->write_index = pos; + ffm->file_size = file_size; } +/* FIXME: make ffserver work with IPv6 */ /* resolve host with also IP address parsing */ static int resolve_host(struct in_addr *sin_addr, const char *hostname) { @@ -339,8 +369,7 @@ static int resolve_host(struct in_addr *sin_addr, const char *hostname) if (!ff_inet_aton(hostname, sin_addr)) { #if HAVE_GETADDRINFO struct addrinfo *ai, *cur; - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); + struct addrinfo hints = { 0 }; hints.ai_family = AF_INET; if (getaddrinfo(hostname, NULL, &hints, &ai)) return -1; @@ -492,19 +521,12 @@ static void start_children(FFStream *feed) close(i); if (!ffserver_debug) { - i = open("/dev/null", O_RDWR); - if (i != -1) { - dup2(i, 0); - dup2(i, 1); - dup2(i, 2); - close(i); - } - } - - /* This is needed to make relative pathnames work */ - if (chdir(my_program_dir) < 0) { - http_log("chdir failed\n"); - exit(1); + if (!freopen("/dev/null", "r", stdin)) + http_log("failed to redirect STDIN to /dev/null\n;"); + if (!freopen("/dev/null", "w", stdout)) + http_log("failed to redirect STDOUT to /dev/null\n;"); + if (!freopen("/dev/null", "w", stderr)) + http_log("failed to redirect STDERR to /dev/null\n;"); } signal(SIGPIPE, SIG_DFL); @@ -556,15 +578,17 @@ static void start_multicast(void) FFStream *stream; char session_id[32]; HTTPContext *rtp_c; - struct sockaddr_in dest_addr; + struct sockaddr_in dest_addr = {0}; int default_port, stream_index; default_port = 6000; for(stream = first_stream; stream != NULL; stream = stream->next) { if (stream->is_multicast) { + unsigned random0 = av_lfg_get(&random_state); + unsigned random1 = av_lfg_get(&random_state); /* open the RTP connection */ snprintf(session_id, sizeof(session_id), "%08x%08x", - av_lfg_get(&random_state), av_lfg_get(&random_state)); + random0, random1); /* choose a port if none given */ if (stream->multicast_port == 0) { @@ -762,16 +786,17 @@ static void start_wait_request(HTTPContext *c, int is_rtsp) static void http_send_too_busy_reply(int fd) { - char buffer[300]; + char buffer[400]; int len = snprintf(buffer, sizeof(buffer), "HTTP/1.0 503 Server too busy\r\n" "Content-type: text/html\r\n" "\r\n" "<html><head><title>Too busy</title></head><body>\r\n" "<p>The server is too busy to serve your request at this time.</p>\r\n" - "<p>The number of current connections is %d, and this exceeds the limit of %d.</p>\r\n" + "<p>The number of current connections is %u, and this exceeds the limit of %u.</p>\r\n" "</body></html>\r\n", nb_connections, nb_max_connections); + av_assert0(len < sizeof(buffer)); send(fd, buffer, len, 0); } @@ -779,7 +804,8 @@ static void http_send_too_busy_reply(int fd) static void new_connection(int server_fd, int is_rtsp) { struct sockaddr_in from_addr; - int fd, len; + socklen_t len; + int fd; HTTPContext *c = NULL; len = sizeof(from_addr); @@ -895,6 +921,8 @@ static void close_connection(HTTPContext *c) for(i=0; i<ctx->nb_streams; i++) av_free(ctx->streams[i]); + av_freep(&ctx->streams); + av_freep(&ctx->priv_data); if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE) current_bandwidth -= c->stream->bandwidth; @@ -1097,7 +1125,7 @@ static int extract_rates(char *rates, int ratelen, const char *request) if (av_strncasecmp(p, "Pragma:", 7) == 0) { const char *q = p + 7; - while (*q && *q != '\n' && isspace(*q)) + while (*q && *q != '\n' && av_isspace(*q)) q++; if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) { @@ -1119,7 +1147,7 @@ static int extract_rates(char *rates, int ratelen, const char *request) if (stream_no < ratelen && stream_no >= 0) rates[stream_no] = rate_no; - while (*q && *q != '\n' && !isspace(*q)) + while (*q && *q != '\n' && !av_isspace(*q)) q++; } @@ -1230,7 +1258,7 @@ static void get_word(char *buf, int buf_size, const char **pp) p = *pp; skip_spaces(&p); q = buf; - while (!isspace(*p) && *p != '\0') { + while (!av_isspace(*p) && *p != '\0') { if ((q - buf) < buf_size - 1) *q++ = *p; p++; @@ -1247,7 +1275,7 @@ static void get_arg(char *buf, int buf_size, const char **pp) int quote; p = *pp; - while (isspace(*p)) p++; + while (av_isspace(*p)) p++; q = buf; quote = 0; if (*p == '\"' || *p == '\'') @@ -1257,7 +1285,7 @@ static void get_arg(char *buf, int buf_size, const char **pp) if (*p == quote) break; } else { - if (isspace(*p)) + if (av_isspace(*p)) break; } if (*p == '\0') @@ -1361,7 +1389,7 @@ static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c) break; line_num++; p = line; - while (isspace(*p)) + while (av_isspace(*p)) p++; if (*p == '\0' || *p == '#') continue; @@ -1462,7 +1490,8 @@ enum RedirType { /* parse http request and prepare header */ static int http_parse_request(HTTPContext *c) { - char *p; + const char *p; + char *p1; enum RedirType redir_type; char cmd[32]; char info[1024], filename[1024]; @@ -1473,10 +1502,10 @@ static int http_parse_request(HTTPContext *c) FFStream *stream; int i; char ratebuf[32]; - char *useragent = 0; + const char *useragent = 0; p = c->buffer; - get_word(cmd, sizeof(cmd), (const char **)&p); + get_word(cmd, sizeof(cmd), &p); av_strlcpy(c->method, cmd, sizeof(c->method)); if (!strcmp(cmd, "GET")) @@ -1486,7 +1515,7 @@ static int http_parse_request(HTTPContext *c) else return -1; - get_word(url, sizeof(url), (const char **)&p); + get_word(url, sizeof(url), &p); av_strlcpy(c->url, url, sizeof(c->url)); get_word(protocol, sizeof(protocol), (const char **)&p); @@ -1499,10 +1528,10 @@ static int http_parse_request(HTTPContext *c) http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url); /* find the filename and the optional info string in the request */ - p = strchr(url, '?'); - if (p) { - av_strlcpy(info, p, sizeof(info)); - *p = '\0'; + p1 = strchr(url, '?'); + if (p1) { + av_strlcpy(info, p1, sizeof(info)); + *p1 = '\0'; } else info[0] = '\0'; @@ -1511,7 +1540,7 @@ static int http_parse_request(HTTPContext *c) for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { if (av_strncasecmp(p, "User-Agent:", 11) == 0) { useragent = p + 11; - if (*useragent && *useragent != '\n' && isspace(*useragent)) + if (*useragent && *useragent != '\n' && av_isspace(*useragent)) useragent++; break; } @@ -1564,7 +1593,7 @@ static int http_parse_request(HTTPContext *c) if (stream->stream_type == STREAM_TYPE_REDIRECT) { c->http_error = 301; q = c->buffer; - q += snprintf(q, c->buffer_size, + snprintf(q, c->buffer_size, "HTTP/1.0 301 Moved\r\n" "Location: %s\r\n" "Content-type: text/html\r\n" @@ -1572,6 +1601,7 @@ static int http_parse_request(HTTPContext *c) "<html><head><title>Moved</title></head><body>\r\n" "You should be <a href=\"%s\">redirected</a>.\r\n" "</body></html>\r\n", stream->feed_filename, stream->feed_filename); + q += strlen(q); /* prepare output buffer */ c->buffer_ptr = c->buffer; c->buffer_end = q; @@ -1602,7 +1632,7 @@ static int http_parse_request(HTTPContext *c) if (c->post == 0 && max_bandwidth < current_bandwidth) { c->http_error = 503; q = c->buffer; - q += snprintf(q, c->buffer_size, + snprintf(q, c->buffer_size, "HTTP/1.0 503 Server too busy\r\n" "Content-type: text/html\r\n" "\r\n" @@ -1611,6 +1641,7 @@ static int http_parse_request(HTTPContext *c) "<p>The bandwidth being served (including your stream) is %"PRIu64"kbit/sec, " "and this exceeds the limit of %"PRIu64"kbit/sec.</p>\r\n" "</body></html>\r\n", current_bandwidth, max_bandwidth); + q += strlen(q); /* prepare output buffer */ c->buffer_ptr = c->buffer; c->buffer_end = q; @@ -1619,7 +1650,7 @@ static int http_parse_request(HTTPContext *c) } if (redir_type != REDIR_NONE) { - char *hostinfo = 0; + const char *hostinfo = 0; for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { if (av_strncasecmp(p, "Host:", 5) == 0) { @@ -1637,7 +1668,7 @@ static int http_parse_request(HTTPContext *c) char *eoh; char hostbuf[260]; - while (isspace(*hostinfo)) + while (av_isspace(*hostinfo)) hostinfo++; eoh = strchr(hostinfo, '\n'); @@ -1653,7 +1684,7 @@ static int http_parse_request(HTTPContext *c) q = c->buffer; switch(redir_type) { case REDIR_ASX: - q += snprintf(q, c->buffer_size, + snprintf(q, c->buffer_size, "HTTP/1.0 200 ASX Follows\r\n" "Content-type: video/x-ms-asf\r\n" "\r\n" @@ -1661,22 +1692,25 @@ static int http_parse_request(HTTPContext *c) //"<!-- Autogenerated by ffserver -->\r\n" "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n" "</ASX>\r\n", hostbuf, filename, info); + q += strlen(q); break; case REDIR_RAM: - q += snprintf(q, c->buffer_size, + snprintf(q, c->buffer_size, "HTTP/1.0 200 RAM Follows\r\n" "Content-type: audio/x-pn-realaudio\r\n" "\r\n" "# Autogenerated by ffserver\r\n" "http://%s/%s%s\r\n", hostbuf, filename, info); + q += strlen(q); break; case REDIR_ASF: - q += snprintf(q, c->buffer_size, + snprintf(q, c->buffer_size, "HTTP/1.0 200 ASF Redirect follows\r\n" "Content-type: video/x-ms-asf\r\n" "\r\n" "[Reference]\r\n" "Ref1=http://%s/%s%s\r\n", hostbuf, filename, info); + q += strlen(q); break; case REDIR_RTSP: { @@ -1686,24 +1720,27 @@ static int http_parse_request(HTTPContext *c) p = strrchr(hostname, ':'); if (p) *p = '\0'; - q += snprintf(q, c->buffer_size, + snprintf(q, c->buffer_size, "HTTP/1.0 200 RTSP Redirect follows\r\n" /* XXX: incorrect mime type ? */ "Content-type: application/x-rtsp\r\n" "\r\n" "rtsp://%s:%d/%s\r\n", hostname, ntohs(my_rtsp_addr.sin_port), filename); + q += strlen(q); } break; case REDIR_SDP: { uint8_t *sdp_data; - int sdp_data_size, len; + int sdp_data_size; + socklen_t len; struct sockaddr_in my_addr; - q += snprintf(q, c->buffer_size, + snprintf(q, c->buffer_size, "HTTP/1.0 200 OK\r\n" "Content-type: application/sdp\r\n" "\r\n"); + q += strlen(q); len = sizeof(my_addr); getsockname(c->fd, (struct sockaddr *)&my_addr, &len); @@ -1747,7 +1784,7 @@ static int http_parse_request(HTTPContext *c) if (!stream->is_feed) { /* However it might be a status report from WMP! Let us log the * data as it might come in handy one day. */ - char *logline = 0; + const char *logline = 0; int client_id = 0; for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { @@ -1822,12 +1859,12 @@ static int http_parse_request(HTTPContext *c) } /* prepare http header */ - q = c->buffer; - q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "HTTP/1.0 200 OK\r\n"); + c->buffer[0] = 0; + av_strlcatf(c->buffer, c->buffer_size, "HTTP/1.0 200 OK\r\n"); mime_type = c->stream->fmt->mime_type; if (!mime_type) mime_type = "application/x-octet-stream"; - q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Pragma: no-cache\r\n"); + av_strlcatf(c->buffer, c->buffer_size, "Pragma: no-cache\r\n"); /* for asf, we need extra headers */ if (!strcmp(c->stream->fmt->name,"asf_stream")) { @@ -1835,10 +1872,11 @@ static int http_parse_request(HTTPContext *c) c->wmp_client_id = av_lfg_get(&random_state); - q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id); + av_strlcatf(c->buffer, c->buffer_size, "Server: Cougar 4.1.0.3923\r\nCache-Control: no-cache\r\nPragma: client-id=%d\r\nPragma: features=\"broadcast\"\r\n", c->wmp_client_id); } - q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "Content-Type: %s\r\n", mime_type); - q += snprintf(q, q - (char *) c->buffer + c->buffer_size, "\r\n"); + av_strlcatf(c->buffer, c->buffer_size, "Content-Type: %s\r\n", mime_type); + av_strlcatf(c->buffer, c->buffer_size, "\r\n"); + q = c->buffer + strlen(c->buffer); /* prepare output buffer */ c->http_error = 0; @@ -1849,7 +1887,7 @@ static int http_parse_request(HTTPContext *c) send_error: c->http_error = 404; q = c->buffer; - q += snprintf(q, c->buffer_size, + snprintf(q, c->buffer_size, "HTTP/1.0 404 Not Found\r\n" "Content-type: text/html\r\n" "\r\n" @@ -1857,6 +1895,7 @@ static int http_parse_request(HTTPContext *c) "<head><title>404 Not Found</title></head>\n" "<body>%s</body>\n" "</html>\n", msg); + q += strlen(q); /* prepare output buffer */ c->buffer_ptr = c->buffer; c->buffer_end = q; @@ -1872,7 +1911,7 @@ static int http_parse_request(HTTPContext *c) static void fmt_bytecount(AVIOContext *pb, int64_t count) { - static const char *suffix = " kMGTP"; + static const char suffix[] = " kMGTP"; const char *s; for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++); @@ -2006,7 +2045,7 @@ static void compute_status(HTTPContext *c) if (stream->pid) { avio_printf(pb, "Running as pid %d.\n", stream->pid); -#if defined(linux) && !defined(CONFIG_NOCUTILS) +#if defined(linux) { FILE *pid_stat; char ps_cmd[64]; @@ -2021,7 +2060,7 @@ static void compute_status(HTTPContext *c) char cpuperc[10]; char cpuused[64]; - if (fscanf(pid_stat, "%10s %64s", cpuperc, + if (fscanf(pid_stat, "%9s %63s", cpuperc, cpuused) == 2) { avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n", cpuperc, cpuused); @@ -2127,12 +2166,13 @@ static int open_input_stream(HTTPContext *c, const char *info) char buf[128]; char input_filename[1024]; AVFormatContext *s = NULL; - int i, ret; + int buf_size, i, ret; int64_t stream_pos; /* find file name */ if (c->stream->feed) { strcpy(input_filename, c->stream->feed->feed_filename); + buf_size = FFM_PACKET_SIZE; /* compute position (absolute time) */ if (av_find_info_tag(buf, sizeof(buf), "date", info)) { if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0) @@ -2144,6 +2184,7 @@ static int open_input_stream(HTTPContext *c, const char *info) stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000; } else { strcpy(input_filename, c->stream->feed_filename); + buf_size = 0; /* compute position (relative time) */ if (av_find_info_tag(buf, sizeof(buf), "date", info)) { if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0) @@ -2159,6 +2200,10 @@ static int open_input_stream(HTTPContext *c, const char *info) http_log("could not open %s: %d\n", input_filename, ret); return -1; } + + /* set buffer size */ + if (buf_size > 0) ffio_set_buf_size(s->pb, buf_size); + s->flags |= AVFMT_FLAG_GENPTS; c->fmt_in = s; if (strcmp(s->iformat->name, "ffm") && avformat_find_stream_info(c->fmt_in, NULL) < 0) { @@ -2580,8 +2625,11 @@ static int http_start_receive_data(HTTPContext *c) if (c->stream->truncate) { /* truncate feed file */ ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE); - ftruncate(c->feed_fd, FFM_PACKET_SIZE); http_log("Truncating feed file '%s'\n", c->stream->feed_filename); + if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) { + http_log("Error truncating feed file: %s\n", strerror(errno)); + return -1; + } } else { if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) { http_log("Error reading write index from feed file: %s\n", strerror(errno)); @@ -2667,8 +2715,6 @@ static int http_receive_data(HTTPContext *c) /* a packet has been received : write it in the store, except if header */ if (c->data_count > FFM_PACKET_SIZE) { - - // printf("writing pos=0x%"PRIx64" size=0x%"PRIx64"\n", feed->feed_write_index, feed->feed_size); /* XXX: use llseek or url_seek */ lseek(c->feed_fd, feed->feed_write_index, SEEK_SET); if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) { @@ -2829,7 +2875,7 @@ static int rtsp_parse_request(HTTPContext *c) char protocol[32]; char line[1024]; int len; - RTSPMessageHeader header1, *header = &header1; + RTSPMessageHeader header1 = { 0 }, *header = &header1; c->buffer_ptr[0] = '\0'; p = c->buffer; @@ -2855,7 +2901,6 @@ static int rtsp_parse_request(HTTPContext *c) } /* parse each header line */ - memset(header, 0, sizeof(*header)); /* skip to next line */ while (*p != '\n' && *p != '\0') p++; @@ -2916,12 +2961,14 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, { AVFormatContext *avc; AVStream *avs = NULL; + AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); int i; avc = avformat_alloc_context(); - if (avc == NULL) { + if (avc == NULL || !rtp_format) { return -1; } + avc->oformat = rtp_format; av_dict_set(&avc->metadata, "title", stream->title[0] ? stream->title : "No Title", 0); avc->nb_streams = stream->nb_streams; @@ -2971,7 +3018,8 @@ static void rtsp_cmd_describe(HTTPContext *c, const char *url) char path1[1024]; const char *path; uint8_t *content; - int content_length, len; + int content_length; + socklen_t len; struct sockaddr_in my_addr; /* find which url is asked */ @@ -3086,9 +3134,12 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url, found: /* generate session id if needed */ - if (h->session_id[0] == '\0') + if (h->session_id[0] == '\0') { + unsigned random0 = av_lfg_get(&random_state); + unsigned random1 = av_lfg_get(&random_state); snprintf(h->session_id, sizeof(h->session_id), "%08x%08x", - av_lfg_get(&random_state), av_lfg_get(&random_state)); + random0, random1); + } /* find rtp session, and create it if none found */ rtp_c = find_rtp_session(h->session_id); @@ -3457,6 +3508,9 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int cop { AVStream *fst; + if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams)) + return NULL; + fst = av_mallocz(sizeof(AVStream)); if (!fst) return NULL; @@ -3464,7 +3518,7 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int cop fst->codec = avcodec_alloc_context3(NULL); memcpy(fst->codec, codec, sizeof(AVCodecContext)); if (codec->extradata_size) { - fst->codec->extradata = av_malloc(codec->extradata_size); + fst->codec->extradata = av_mallocz(codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(fst->codec->extradata, codec->extradata, codec->extradata_size); } @@ -3543,10 +3597,12 @@ static void extract_mpeg4_header(AVFormatContext *infile) AVStream *st; const uint8_t *p; + infile->flags |= AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE; + mpeg4_count = 0; for(i=0;i<infile->nb_streams;i++) { st = infile->streams[i]; - if (st->codec->codec_id == CODEC_ID_MPEG4 && + if (st->codec->codec_id == AV_CODEC_ID_MPEG4 && st->codec->extradata_size == 0) { mpeg4_count++; } @@ -3556,10 +3612,10 @@ static void extract_mpeg4_header(AVFormatContext *infile) printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename); while (mpeg4_count > 0) { - if (av_read_packet(infile, &pkt) < 0) + if (av_read_frame(infile, &pkt) < 0) break; st = infile->streams[pkt.stream_index]; - if (st->codec->codec_id == CODEC_ID_MPEG4 && + if (st->codec->codec_id == AV_CODEC_ID_MPEG4 && st->codec->extradata_size == 0) { av_freep(&st->codec->extradata); /* fill extradata with the header */ @@ -3571,7 +3627,7 @@ static void extract_mpeg4_header(AVFormatContext *infile) p[2] == 0x01 && p[3] == 0xb6) { size = p - pkt.data; // av_hex_dump_log(infile, AV_LOG_DEBUG, pkt.data, size); - st->codec->extradata = av_malloc(size); + st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); st->codec->extradata_size = size; memcpy(st->codec->extradata, pkt.data, size); break; @@ -3662,6 +3718,8 @@ static void build_feed_streams(void) int matches = 0; if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) { + /* set buffer size */ + ffio_set_buf_size(s->pb, FFM_PACKET_SIZE); /* Now see if it matches */ if (s->nb_streams == feed->nb_streams) { matches = 1; @@ -3748,7 +3806,7 @@ static void build_feed_streams(void) s->nb_streams = feed->nb_streams; s->streams = feed->streams; if (avformat_write_header(s, NULL) < 0) { - http_log("Container doesn't supports the required parameters\n"); + http_log("Container doesn't support the required parameters\n"); exit(1); } /* XXX: need better api */ @@ -3802,6 +3860,9 @@ static void add_codec(FFStream *stream, AVCodecContext *av) { AVStream *st; + if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams)) + return; + /* compute default parameters */ switch(av->codec_type) { case AVMEDIA_TYPE_AUDIO: @@ -3873,22 +3934,22 @@ static void add_codec(FFStream *stream, AVCodecContext *av) memcpy(st->codec, av, sizeof(AVCodecContext)); } -static enum CodecID opt_audio_codec(const char *arg) +static enum AVCodecID opt_audio_codec(const char *arg) { AVCodec *p= avcodec_find_encoder_by_name(arg); if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO) - return CODEC_ID_NONE; + return AV_CODEC_ID_NONE; return p->id; } -static enum CodecID opt_video_codec(const char *arg) +static enum AVCodecID opt_video_codec(const char *arg) { AVCodec *p= avcodec_find_encoder_by_name(arg); if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO) - return CODEC_ID_NONE; + return AV_CODEC_ID_NONE; return p->id; } @@ -3931,7 +3992,7 @@ static int ffserver_opt_default(const char *opt, const char *arg, static int ffserver_opt_preset(const char *arg, AVCodecContext *avctx, int type, - enum CodecID *audio_id, enum CodecID *video_id) + enum AVCodecID *audio_id, enum AVCodecID *video_id) { FILE *f=NULL; char filename[1000], tmp[1000], tmp2[1000], line[1000]; @@ -4013,7 +4074,7 @@ static int parse_ffconfig(const char *filename) FFStream **last_stream, *stream, *redirect; FFStream **last_feed, *feed, *s; AVCodecContext audio_enc, video_enc; - enum CodecID audio_id, video_id; + enum AVCodecID audio_id, video_id; f = fopen(filename, "r"); if (!f) { @@ -4030,8 +4091,8 @@ static int parse_ffconfig(const char *filename) stream = NULL; feed = NULL; redirect = NULL; - audio_id = CODEC_ID_NONE; - video_id = CODEC_ID_NONE; + audio_id = AV_CODEC_ID_NONE; + video_id = AV_CODEC_ID_NONE; #define ERROR(...) report_config_error(filename, line_num, &errors, __VA_ARGS__) for(;;) { @@ -4039,7 +4100,7 @@ static int parse_ffconfig(const char *filename) break; line_num++; p = line; - while (isspace(*p)) + while (av_isspace(*p)) p++; if (*p == '\0' || *p == '#') continue; @@ -4059,7 +4120,7 @@ static int parse_ffconfig(const char *filename) ERROR("%s:%d: Invalid host/IP address: %s\n", arg); } } else if (!av_strcasecmp(cmd, "NoDaemon")) { - ffserver_daemon = 0; + // do nothing here, its the default now } else if (!av_strcasecmp(cmd, "RTSPPort")) { get_arg(arg, sizeof(arg), &p); val = atoi(arg); @@ -4146,10 +4207,7 @@ static int parse_ffconfig(const char *filename) feed->child_argv[i] = av_strdup(arg); } - feed->child_argv[i] = av_malloc(30 + strlen(feed->filename)); - - snprintf(feed->child_argv[i], 30+strlen(feed->filename), - "http://%s:%d/%s", + feed->child_argv[i] = av_asprintf("http://%s:%d/%s", (my_http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" : inet_ntoa(my_http_addr.sin_addr), ntohs(my_http_addr.sin_port), feed->filename); @@ -4179,7 +4237,7 @@ static int parse_ffconfig(const char *filename) get_arg(arg, sizeof(arg), &p); p1 = arg; fsize = strtod(p1, &p1); - switch(toupper(*p1)) { + switch(av_toupper(*p1)) { case 'K': fsize *= 1024; break; @@ -4211,7 +4269,7 @@ static int parse_ffconfig(const char *filename) stream = av_mallocz(sizeof(FFStream)); get_arg(stream->filename, sizeof(stream->filename), &p); q = strrchr(stream->filename, '>'); - if (*q) + if (q) *q = '\0'; for (s = first_stream; s; s = s->next) { @@ -4221,11 +4279,11 @@ static int parse_ffconfig(const char *filename) } stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL); - avcodec_get_context_defaults2(&video_enc, AVMEDIA_TYPE_VIDEO); - avcodec_get_context_defaults2(&audio_enc, AVMEDIA_TYPE_AUDIO); + avcodec_get_context_defaults3(&video_enc, NULL); + avcodec_get_context_defaults3(&audio_enc, NULL); - audio_id = CODEC_ID_NONE; - video_id = CODEC_ID_NONE; + audio_id = AV_CODEC_ID_NONE; + video_id = AV_CODEC_ID_NONE; if (stream->fmt) { audio_id = stream->fmt->audio_codec; video_id = stream->fmt->video_codec; @@ -4307,13 +4365,13 @@ static int parse_ffconfig(const char *filename) } else if (!av_strcasecmp(cmd, "AudioCodec")) { get_arg(arg, sizeof(arg), &p); audio_id = opt_audio_codec(arg); - if (audio_id == CODEC_ID_NONE) { + if (audio_id == AV_CODEC_ID_NONE) { ERROR("Unknown AudioCodec: %s\n", arg); } } else if (!av_strcasecmp(cmd, "VideoCodec")) { get_arg(arg, sizeof(arg), &p); video_id = opt_video_codec(arg); - if (video_id == CODEC_ID_NONE) { + if (video_id == AV_CODEC_ID_NONE) { ERROR("Unknown VideoCodec: %s\n", arg); } } else if (!av_strcasecmp(cmd, "MaxTime")) { @@ -4504,9 +4562,9 @@ static int parse_ffconfig(const char *filename) if (stream) video_enc.dark_masking = atof(arg); } else if (!av_strcasecmp(cmd, "NoVideo")) { - video_id = CODEC_ID_NONE; + video_id = AV_CODEC_ID_NONE; } else if (!av_strcasecmp(cmd, "NoAudio")) { - audio_id = CODEC_ID_NONE; + audio_id = AV_CODEC_ID_NONE; } else if (!av_strcasecmp(cmd, "ACL")) { parse_acl_row(stream, feed, NULL, p, filename, line_num); } else if (!av_strcasecmp(cmd, "DynamicACL")) { @@ -4544,12 +4602,12 @@ static int parse_ffconfig(const char *filename) ERROR("No corresponding <Stream> for </Stream>\n"); } else { if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) { - if (audio_id != CODEC_ID_NONE) { + if (audio_id != AV_CODEC_ID_NONE) { audio_enc.codec_type = AVMEDIA_TYPE_AUDIO; audio_enc.codec_id = audio_id; add_codec(stream, &audio_enc); } - if (video_id != CODEC_ID_NONE) { + if (video_id != AV_CODEC_ID_NONE) { video_enc.codec_type = AVMEDIA_TYPE_VIDEO; video_enc.codec_id = video_id; add_codec(stream, &video_enc); @@ -4633,17 +4691,15 @@ static void handle_child_exit(int sig) static void opt_debug(void) { ffserver_debug = 1; - ffserver_daemon = 0; logfilename[0] = '-'; } -static int opt_help(const char *opt, const char *arg) +void show_help_default(const char *opt, const char *arg) { printf("usage: ffserver [options]\n" "Hyper fast multi format Audio/Video streaming server\n"); printf("\n"); - show_help_options(options, "Main options:\n", 0, 0); - return 0; + show_help_options(options, "Main options:", 0, 0, 0); } static const OptionDef options[] = { @@ -4656,7 +4712,7 @@ static const OptionDef options[] = { int main(int argc, char **argv) { - struct sigaction sigact; + struct sigaction sigact = { { 0 } }; parse_loglevel(argc, argv, options); av_register_all(); @@ -4665,8 +4721,6 @@ int main(int argc, char **argv) show_banner(argc, argv, options); my_program_name = argv[0]; - my_program_dir = getcwd(0, 0); - ffserver_daemon = 1; parse_options(NULL, argc, argv, options, NULL); @@ -4674,7 +4728,6 @@ int main(int argc, char **argv) av_lfg_init(&random_state, av_get_random_seed()); - memset(&sigact, 0, sizeof(sigact)); sigact.sa_handler = handle_child_exit; sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART; sigaction(SIGCHLD, &sigact, 0); @@ -4699,37 +4752,9 @@ int main(int argc, char **argv) compute_bandwidth(); - /* put the process in background and detach it from its TTY */ - if (ffserver_daemon) { - int pid; - - pid = fork(); - if (pid < 0) { - perror("fork"); - exit(1); - } else if (pid > 0) { - /* parent : exit */ - exit(0); - } else { - /* child */ - setsid(); - close(0); - open("/dev/null", O_RDWR); - if (strcmp(logfilename, "-") != 0) { - close(1); - dup(0); - } - close(2); - dup(0); - } - } - /* signal init */ signal(SIGPIPE, SIG_IGN); - if (ffserver_daemon) - chdir("/"); - if (http_server() < 0) { http_log("Could not start server\n"); exit(1); |