#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
#include "libavformat/ffm.h"
#include "libavformat/network.h"
#include "libavformat/os_support.h"
#include "libavformat/rtpdec.h"
+#include "libavformat/rtpproto.h"
#include "libavformat/rtsp.h"
#include "libavformat/avio_internal.h"
#include "libavformat/internal.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 <time.h>
#include <sys/wait.h>
#include <signal.h>
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
#include "cmdutils.h"
HTTPContext *rtsp_c);
static const char *my_program_name;
-static const char *my_program_dir;
-static const char *config_filename = "/etc/avserver.conf";
+static const char *config_filename;
static int avserver_debug;
-static int avserver_daemon;
static int no_launch;
static int need_to_start_children;
static FILE *logfile = NULL;
-void exit_program(int ret)
+static int64_t ffm_read_write_index(int fd)
+{
+ uint8_t buf[8];
+
+ lseek(fd, 8, SEEK_SET);
+ if (read(fd, buf, 8) != 8)
+ return AVERROR(EIO);
+ return AV_RB64(buf);
+}
+
+static int ffm_write_write_index(int fd, int64_t pos)
+{
+ uint8_t buf[8];
+ int i;
+
+ for(i=0;i<8;i++)
+ buf[i] = (pos >> (56 - i * 8)) & 0xff;
+ lseek(fd, 8, SEEK_SET);
+ 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)
{
- exit(ret);
+ FFMContext *ffm = s->priv_data;
+ ffm->write_index = pos;
+ ffm->file_size = file_size;
}
/* FIXME: make avserver work with IPv6 */
close(i);
if (!avserver_debug) {
- i = open("/dev/null", O_RDWR);
- if (i != -1) {
- dup2(i, 0);
- dup2(i, 1);
- dup2(i, 2);
- close(i);
- }
+ 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;");
}
- /* This is needed to make relative pathnames work */
- chdir(my_program_dir);
-
signal(SIGPIPE, SIG_DFL);
execvp(pathname, feed->child_argv);
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);
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) {
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++;
}
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++;
int quote;
p = *pp;
- while (isspace(*p)) p++;
+ while (av_isspace(*p)) p++;
q = buf;
quote = 0;
if (*p == '\"' || *p == '\'')
if (*p == quote)
break;
} else {
- if (isspace(*p))
+ if (av_isspace(*p))
break;
}
if (*p == '\0')
break;
line_num++;
p = line;
- while (isspace(*p))
+ while (av_isspace(*p))
p++;
if (*p == '\0' || *p == '#')
continue;
/* 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];
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"))
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);
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';
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;
}
}
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) {
char *eoh;
char hostbuf[260];
- while (isspace(*hostinfo))
+ while (av_isspace(*hostinfo))
hostinfo++;
eoh = strchr(hostinfo, '\n');
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,
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'; ) {
/* 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) {
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 */
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];
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 == AV_CODEC_ID_MPEG4 &&
return p->id;
}
-/* simplistic plugin support */
-
-#if HAVE_DLOPEN
-static void load_module(const char *filename)
-{
- void *dll;
- void (*init_func)(void);
- dll = dlopen(filename, RTLD_NOW);
- if (!dll) {
- fprintf(stderr, "Could not load module '%s' - %s\n",
- filename, dlerror());
- return;
- }
-
- init_func = dlsym(dll, "avserver_module_init");
- if (!init_func) {
- fprintf(stderr,
- "%s: init function 'avserver_module_init()' not found\n",
- filename);
- dlclose(dll);
- }
-
- init_func();
-}
-#endif
-
static int avserver_opt_default(const char *opt, const char *arg,
AVCodecContext *avctx, int type)
{
break;
line_num++;
p = line;
- while (isspace(*p))
+ while (av_isspace(*p))
p++;
if (*p == '\0' || *p == '#')
continue;
if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
}
- } else if (!av_strcasecmp(cmd, "NoDaemon")) {
- avserver_daemon = 0;
} else if (!av_strcasecmp(cmd, "RTSPPort")) {
get_arg(arg, sizeof(arg), &p);
val = atoi(arg);
get_arg(arg, sizeof(arg), &p);
p1 = arg;
fsize = strtod(p1, &p1);
- switch(toupper(*p1)) {
+ switch(av_toupper(*p1)) {
case 'K':
fsize *= 1024;
break;
ERROR("VideoQMin out of range\n");
}
}
- } else if (!av_strcasecmp(cmd, "LumaElim")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.luma_elim_threshold = atoi(arg);
- } else if (!av_strcasecmp(cmd, "ChromaElim")) {
- get_arg(arg, sizeof(arg), &p);
- if (stream)
- video_enc.chroma_elim_threshold = atoi(arg);
} else if (!av_strcasecmp(cmd, "LumiMask")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
redirect = NULL;
}
} else if (!av_strcasecmp(cmd, "LoadModule")) {
- get_arg(arg, sizeof(arg), &p);
-#if HAVE_DLOPEN
- load_module(arg);
-#else
- ERROR("Module support not compiled into this version: '%s'\n", arg);
-#endif
+ ERROR("Loadable modules no longer supported\n");
} else {
ERROR("Incorrect keyword: '%s'\n", cmd);
}
static void opt_debug(void)
{
avserver_debug = 1;
- avserver_daemon = 0;
logfilename[0] = '-';
}
{
struct sigaction sigact = { { 0 } };
+ config_filename = av_strdup("/etc/avserver.conf");
+
parse_loglevel(argc, argv, options);
av_register_all();
avformat_network_init();
show_banner();
my_program_name = argv[0];
- my_program_dir = getcwd(0, 0);
- avserver_daemon = 1;
parse_options(NULL, argc, argv, options, NULL);
compute_bandwidth();
- /* put the process in background and detach it from its TTY */
- if (avserver_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 (avserver_daemon)
- chdir("/");
-
if (http_server() < 0) {
http_log("Could not start server\n");
exit(1);