aboutsummaryrefslogtreecommitdiff
path: root/lib/ffmpeg/ffserver.c
diff options
context:
space:
mode:
authorFlyingRat <flyingrat@outlook.com>2013-04-07 16:36:04 +0200
committerFlyingRat <flyingrat@outlook.com>2013-04-07 16:36:04 +0200
commit0e63a815aa6af63a21848e04b683d3f506dd41b1 (patch)
tree002f61d8a5b1d294d99fd4ba5b6982d76a612f0c /lib/ffmpeg/ffserver.c
parent71862137c5337fc678681a23bfbc65f4db7a7b2f (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.c307
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);