#define closesocket close
#endif
#include <string.h>
-#include <strings.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/rtsp.h"
-// XXX for ffio_open_dyn_packet_buffer, to be removed
#include "libavformat/avio_internal.h"
+#include "libavformat/internal.h"
+#include "libavformat/url.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>
#include <poll.h>
#endif
#include <errno.h>
-#include <sys/time.h>
#include <time.h>
#include <sys/wait.h>
#include <signal.h>
char title[512];
char copyright[512];
char comment[512];
- pid_t pid; /* Of ffmpeg process */
- time_t pid_start; /* Of ffmpeg process */
+ pid_t pid; /* of avconv process */
+ time_t pid_start; /* of avconv process */
char **child_argv;
struct FFStream *next;
unsigned bandwidth; /* bandwidth, in kbits/s */
HTTPContext *rtsp_c);
static const char *my_program_name;
-static const char *my_program_dir;
static const char *config_filename = "/etc/avserver.conf";
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)
{
- exit(ret);
+ 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)
+{
+ FFMContext *ffm = s->priv_data;
+ ffm->write_index = pos;
+ ffm->file_size = file_size;
}
/* FIXME: make avserver work with IPv6 */
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;
slash = pathname;
else
slash++;
- strcpy(slash, "ffmpeg");
+ strcpy(slash, "avconv");
- http_log("Launch commandline: ");
+ http_log("Launch command line: ");
http_log("%s ", pathname);
for (i = 1; feed->child_argv[i] && feed->child_argv[i][0]; i++)
http_log("%s ", feed->child_argv[i]);
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);
tmp = 1;
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp));
+ my_addr->sin_family = AF_INET;
if (bind (server_fd, (struct sockaddr *) my_addr, sizeof (*my_addr)) < 0) {
char bindmsg[32];
snprintf(bindmsg, sizeof(bindmsg), "bind(port %d)", ntohs(my_addr->sin_port));
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 (st->codec->codec)
avcodec_close(st->codec);
}
- av_close_input_file(c->fmt_in);
+ avformat_close_input(&c->fmt_in);
}
/* free RTP output streams if any */
}
h = c->rtp_handles[i];
if (h)
- url_close(h);
+ ffurl_close(h);
}
ctx = &c->fmt_ctx;
const char *p;
for (p = request; *p && *p != '\r' && *p != '\n'; ) {
- if (strncasecmp(p, "Pragma:", 7) == 0) {
+ if (av_strncasecmp(p, "Pragma:", 7) == 0) {
const char *q = p + 7;
while (*q && *q != '\n' && isspace(*q))
q++;
- if (strncasecmp(q, "stream-switch-entry=", 20) == 0) {
+ if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) {
int stream_no;
int rate_no;
int errors = 0;
get_arg(arg, sizeof(arg), &p);
- if (strcasecmp(arg, "allow") == 0)
+ if (av_strcasecmp(arg, "allow") == 0)
acl.action = IP_ALLOW;
- else if (strcasecmp(arg, "deny") == 0)
+ else if (av_strcasecmp(arg, "deny") == 0)
acl.action = IP_DENY;
else {
fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
continue;
get_arg(cmd, sizeof(cmd), &p);
- if (!strcasecmp(cmd, "ACL"))
+ if (!av_strcasecmp(cmd, "ACL"))
parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
}
fclose(f);
/* 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';
av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
- if (strncasecmp(p, "User-Agent:", 11) == 0) {
+ if (av_strncasecmp(p, "User-Agent:", 11) == 0) {
useragent = p + 11;
if (*useragent && *useragent != '\n' && isspace(*useragent))
useragent++;
redir_type = REDIR_ASX;
filename[strlen(filename)-1] = 'f';
} else if (av_match_ext(filename, "asf") &&
- (!useragent || strncasecmp(useragent, "NSPlayer", 8) != 0)) {
+ (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) {
/* if this isn't WMP or lookalike, return the redirector file */
redir_type = REDIR_ASF;
} else if (av_match_ext(filename, "rpm,ram")) {
}
if (redir_type != REDIR_NONE) {
- char *hostinfo = 0;
+ const char *hostinfo = 0;
for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
- if (strncasecmp(p, "Host:", 5) == 0) {
+ if (av_strncasecmp(p, "Host:", 5) == 0) {
hostinfo = p + 5;
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,
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'; ) {
- if (strncasecmp(p, "Pragma: log-line=", 17) == 0) {
+ if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) {
logline = p;
break;
}
- if (strncasecmp(p, "Pragma: client-id=", 18) == 0)
+ if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0)
client_id = strtol(p + 18, 0, 10);
p = strchr(p, '\n');
if (!p)
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++);
c->buffer_end = c->pb_buffer + len;
}
-/* check if the parser needs to be opened for stream i */
-static void open_parser(AVFormatContext *s, int i)
-{
- AVStream *st = s->streams[i];
- AVCodec *codec;
-
- if (!st->codec->codec) {
- codec = avcodec_find_decoder(st->codec->codec_id);
- if (codec && (codec->capabilities & CODEC_CAP_PARSE_ONLY)) {
- st->codec->parse_only = 1;
- if (avcodec_open2(st->codec, codec, NULL) < 0)
- st->codec->parse_only = 0;
- }
- }
-}
-
static int open_input_stream(HTTPContext *c, const char *info)
{
char buf[128];
c->fmt_in = s;
if (strcmp(s->iformat->name, "ffm") && avformat_find_stream_info(c->fmt_in, NULL) < 0) {
http_log("Could not find stream info '%s'\n", input_filename);
- av_close_input_file(s);
+ avformat_close_input(&s);
return -1;
}
- /* open each parser */
- for(i=0;i<s->nb_streams;i++)
- open_parser(s, i);
-
/* choose stream as clock source (we favorize video stream if
present) for packet sending */
c->pts_stream_index = 0;
* Default value from Libav
* Try to set it use configuration option
*/
- c->fmt_ctx.preload = (int)(0.5*AV_TIME_BASE);
c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
if (avformat_write_header(&c->fmt_ctx, NULL) < 0) {
return 0;
} else {
if (c->stream->loop) {
- av_close_input_file(c->fmt_in);
- c->fmt_in = NULL;
+ avformat_close_input(&c->fmt_in);
if (open_input_stream(c, "") < 0)
goto no_loop;
goto redo;
if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP)
max_packet_size = RTSP_TCP_MAX_PACKET_SIZE;
else
- max_packet_size = url_get_max_packet_size(c->rtp_handles[c->packet_stream_index]);
+ max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size);
} else {
ret = avio_open_dyn_buf(&ctx->pb);
} else {
/* send RTP packet directly in UDP */
c->buffer_ptr += 4;
- url_write(c->rtp_handles[c->packet_stream_index],
- c->buffer_ptr, len);
+ ffurl_write(c->rtp_handles[c->packet_stream_index],
+ c->buffer_ptr, len);
c->buffer_ptr += len;
/* here we continue as we can send several packets per 10 ms slot */
}
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));
/* 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) {
/* Now we have the actual streams */
if (s->nb_streams != feed->nb_streams) {
- av_close_input_stream(s);
+ avformat_close_input(&s);
av_free(pb);
http_log("Feed '%s' stream number does not match registered feed\n",
c->stream->feed_filename);
avcodec_copy_context(fst->codec, st->codec);
}
- av_close_input_stream(s);
+ avformat_close_input(&s);
av_free(pb);
}
c->buffer_ptr = c->buffer;
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;
}
/* parse each header line */
- memset(header, 0, sizeof(*header));
/* skip to next line */
while (*p != '\n' && *p != '\0')
p++;
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 */
switch(rtp_c->rtp_protocol) {
case RTSP_LOWER_TRANSPORT_UDP:
- rtp_port = rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
- rtcp_port = rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
+ rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
+ rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
"client_port=%d-%d;server_port=%d-%d",
th->client_port_min, th->client_port_max,
"rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port));
}
- if (url_open(&h, ctx->filename, AVIO_FLAG_WRITE) < 0)
+ if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0)
goto fail;
c->rtp_handles[stream_index] = h;
- max_packet_size = url_get_max_packet_size(h);
+ max_packet_size = h->max_packet_size;
break;
case RTSP_LOWER_TRANSPORT_TCP:
/* RTP/TCP case */
if (avformat_write_header(ctx, NULL) < 0) {
fail:
if (h)
- url_close(h);
+ ffurl_close(h);
av_free(ctx);
return -1;
}
}
fst->priv_data = av_mallocz(sizeof(FeedData));
fst->index = stream->nb_streams;
- av_set_pts_info(fst, 33, 1, 90000);
+ avpriv_set_pts_info(fst, 33, 1, 90000);
fst->sample_aspect_ratio = codec->sample_aspect_ratio;
stream->streams[stream->nb_streams++] = fst;
return fst;
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++;
}
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 */
if (avformat_find_stream_info(infile, NULL) < 0) {
http_log("Could not find codec parameters from '%s'\n",
stream->feed_filename);
- av_close_input_file(infile);
+ avformat_close_input(&infile);
goto fail;
}
extract_mpeg4_header(infile);
for(i=0;i<infile->nb_streams;i++)
add_av_stream1(stream, infile->streams[i]->codec, 1);
- av_close_input_file(infile);
+ avformat_close_input(&infile);
}
}
}
http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",
feed->feed_filename, s->nb_streams, feed->nb_streams);
- av_close_input_file(s);
+ avformat_close_input(&s);
} else
http_log("Deleting feed file '%s' as it appears to be corrupt\n",
feed->feed_filename);
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;
}
int ret = 0;
const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0);
if(o)
- ret = av_set_string3(avctx, opt, arg, 1, NULL);
+ ret = av_opt_set(avctx, opt, arg, 0);
return ret;
}
static int avserver_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];
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) {
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(;;) {
get_arg(cmd, sizeof(cmd), &p);
- if (!strcasecmp(cmd, "Port")) {
+ if (!av_strcasecmp(cmd, "Port")) {
get_arg(arg, sizeof(arg), &p);
val = atoi(arg);
if (val < 1 || val > 65536) {
ERROR("Invalid_port: %s\n", arg);
}
my_http_addr.sin_port = htons(val);
- } else if (!strcasecmp(cmd, "BindAddress")) {
+ } else if (!av_strcasecmp(cmd, "BindAddress")) {
get_arg(arg, sizeof(arg), &p);
if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
}
- } else if (!strcasecmp(cmd, "NoDaemon")) {
- avserver_daemon = 0;
- } else if (!strcasecmp(cmd, "RTSPPort")) {
+ } else if (!av_strcasecmp(cmd, "RTSPPort")) {
get_arg(arg, sizeof(arg), &p);
val = atoi(arg);
if (val < 1 || val > 65536) {
ERROR("%s:%d: Invalid port: %s\n", arg);
}
my_rtsp_addr.sin_port = htons(atoi(arg));
- } else if (!strcasecmp(cmd, "RTSPBindAddress")) {
+ } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) {
get_arg(arg, sizeof(arg), &p);
if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
ERROR("Invalid host/IP address: %s\n", arg);
}
- } else if (!strcasecmp(cmd, "MaxHTTPConnections")) {
+ } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) {
get_arg(arg, sizeof(arg), &p);
val = atoi(arg);
if (val < 1 || val > 65536) {
ERROR("Invalid MaxHTTPConnections: %s\n", arg);
}
nb_max_http_connections = val;
- } else if (!strcasecmp(cmd, "MaxClients")) {
+ } else if (!av_strcasecmp(cmd, "MaxClients")) {
get_arg(arg, sizeof(arg), &p);
val = atoi(arg);
if (val < 1 || val > nb_max_http_connections) {
} else {
nb_max_connections = val;
}
- } else if (!strcasecmp(cmd, "MaxBandwidth")) {
+ } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
int64_t llval;
get_arg(arg, sizeof(arg), &p);
llval = atoll(arg);
ERROR("Invalid MaxBandwidth: %s\n", arg);
} else
max_bandwidth = llval;
- } else if (!strcasecmp(cmd, "CustomLog")) {
+ } else if (!av_strcasecmp(cmd, "CustomLog")) {
if (!avserver_debug)
get_arg(logfilename, sizeof(logfilename), &p);
- } else if (!strcasecmp(cmd, "<Feed")) {
+ } else if (!av_strcasecmp(cmd, "<Feed")) {
/*********************************************/
/* Feed related options */
char *q;
*last_feed = feed;
last_feed = &feed->next_feed;
}
- } else if (!strcasecmp(cmd, "Launch")) {
+ } else if (!av_strcasecmp(cmd, "Launch")) {
if (feed) {
int i;
inet_ntoa(my_http_addr.sin_addr),
ntohs(my_http_addr.sin_port), feed->filename);
}
- } else if (!strcasecmp(cmd, "ReadOnlyFile")) {
+ } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) {
if (feed) {
get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
feed->readonly = 1;
} else if (stream) {
get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
}
- } else if (!strcasecmp(cmd, "File")) {
+ } else if (!av_strcasecmp(cmd, "File")) {
if (feed) {
get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
} else if (stream)
get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
- } else if (!strcasecmp(cmd, "Truncate")) {
+ } else if (!av_strcasecmp(cmd, "Truncate")) {
if (feed) {
get_arg(arg, sizeof(arg), &p);
feed->truncate = strtod(arg, NULL);
}
- } else if (!strcasecmp(cmd, "FileMaxSize")) {
+ } else if (!av_strcasecmp(cmd, "FileMaxSize")) {
if (feed) {
char *p1;
double fsize;
ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4);
}
}
- } else if (!strcasecmp(cmd, "</Feed>")) {
+ } else if (!av_strcasecmp(cmd, "</Feed>")) {
if (!feed) {
ERROR("No corresponding <Feed> for </Feed>\n");
}
feed = NULL;
- } else if (!strcasecmp(cmd, "<Stream")) {
+ } else if (!av_strcasecmp(cmd, "<Stream")) {
/*********************************************/
/* Stream related options */
char *q;
}
stream->fmt = avserver_guess_format(NULL, stream->filename, NULL);
- avcodec_get_context_defaults2(&video_enc, AVMEDIA_TYPE_VIDEO);
- avcodec_get_context_defaults2(&audio_enc, AVMEDIA_TYPE_AUDIO);
- audio_id = CODEC_ID_NONE;
- video_id = CODEC_ID_NONE;
+ avcodec_get_context_defaults3(&video_enc, NULL);
+ avcodec_get_context_defaults3(&audio_enc, NULL);
+ 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;
*last_stream = stream;
last_stream = &stream->next;
}
- } else if (!strcasecmp(cmd, "Feed")) {
+ } else if (!av_strcasecmp(cmd, "Feed")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
FFStream *sfeed;
else
stream->feed = sfeed;
}
- } else if (!strcasecmp(cmd, "Format")) {
+ } else if (!av_strcasecmp(cmd, "Format")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
if (!strcmp(arg, "status")) {
video_id = stream->fmt->video_codec;
}
}
- } else if (!strcasecmp(cmd, "InputFormat")) {
+ } else if (!av_strcasecmp(cmd, "InputFormat")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
stream->ifmt = av_find_input_format(arg);
ERROR("Unknown input format: %s\n", arg);
}
}
- } else if (!strcasecmp(cmd, "FaviconURL")) {
+ } else if (!av_strcasecmp(cmd, "FaviconURL")) {
if (stream && stream->stream_type == STREAM_TYPE_STATUS) {
get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
} else {
ERROR("FaviconURL only permitted for status streams\n");
}
- } else if (!strcasecmp(cmd, "Author")) {
+ } else if (!av_strcasecmp(cmd, "Author")) {
if (stream)
get_arg(stream->author, sizeof(stream->author), &p);
- } else if (!strcasecmp(cmd, "Comment")) {
+ } else if (!av_strcasecmp(cmd, "Comment")) {
if (stream)
get_arg(stream->comment, sizeof(stream->comment), &p);
- } else if (!strcasecmp(cmd, "Copyright")) {
+ } else if (!av_strcasecmp(cmd, "Copyright")) {
if (stream)
get_arg(stream->copyright, sizeof(stream->copyright), &p);
- } else if (!strcasecmp(cmd, "Title")) {
+ } else if (!av_strcasecmp(cmd, "Title")) {
if (stream)
get_arg(stream->title, sizeof(stream->title), &p);
- } else if (!strcasecmp(cmd, "Preroll")) {
+ } else if (!av_strcasecmp(cmd, "Preroll")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
stream->prebuffer = atof(arg) * 1000;
- } else if (!strcasecmp(cmd, "StartSendOnKey")) {
+ } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
if (stream)
stream->send_on_key = 1;
- } else if (!strcasecmp(cmd, "AudioCodec")) {
+ } 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 (!strcasecmp(cmd, "VideoCodec")) {
+ } 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 (!strcasecmp(cmd, "MaxTime")) {
+ } else if (!av_strcasecmp(cmd, "MaxTime")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
stream->max_time = atof(arg) * 1000;
- } else if (!strcasecmp(cmd, "AudioBitRate")) {
+ } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
audio_enc.bit_rate = lrintf(atof(arg) * 1000);
- } else if (!strcasecmp(cmd, "AudioChannels")) {
+ } else if (!av_strcasecmp(cmd, "AudioChannels")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
audio_enc.channels = atoi(arg);
- } else if (!strcasecmp(cmd, "AudioSampleRate")) {
+ } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
audio_enc.sample_rate = atoi(arg);
- } else if (!strcasecmp(cmd, "AudioQuality")) {
+ } else if (!av_strcasecmp(cmd, "AudioQuality")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
// audio_enc.quality = atof(arg) * 1000;
}
- } else if (!strcasecmp(cmd, "VideoBitRateRange")) {
+ } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
if (stream) {
int minrate, maxrate;
ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg);
}
}
- } else if (!strcasecmp(cmd, "Debug")) {
+ } else if (!av_strcasecmp(cmd, "Debug")) {
if (stream) {
get_arg(arg, sizeof(arg), &p);
video_enc.debug = strtol(arg,0,0);
}
- } else if (!strcasecmp(cmd, "Strict")) {
+ } else if (!av_strcasecmp(cmd, "Strict")) {
if (stream) {
get_arg(arg, sizeof(arg), &p);
video_enc.strict_std_compliance = atoi(arg);
}
- } else if (!strcasecmp(cmd, "VideoBufferSize")) {
+ } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
if (stream) {
get_arg(arg, sizeof(arg), &p);
video_enc.rc_buffer_size = atoi(arg) * 8*1024;
}
- } else if (!strcasecmp(cmd, "VideoBitRateTolerance")) {
+ } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
if (stream) {
get_arg(arg, sizeof(arg), &p);
video_enc.bit_rate_tolerance = atoi(arg) * 1000;
}
- } else if (!strcasecmp(cmd, "VideoBitRate")) {
+ } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
video_enc.bit_rate = atoi(arg) * 1000;
}
- } else if (!strcasecmp(cmd, "VideoSize")) {
+ } else if (!av_strcasecmp(cmd, "VideoSize")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
av_parse_video_size(&video_enc.width, &video_enc.height, arg);
ERROR("Image size must be a multiple of 16\n");
}
}
- } else if (!strcasecmp(cmd, "VideoFrameRate")) {
+ } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
AVRational frame_rate;
video_enc.time_base.den = frame_rate.num;
}
}
- } else if (!strcasecmp(cmd, "VideoGopSize")) {
+ } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
video_enc.gop_size = atoi(arg);
- } else if (!strcasecmp(cmd, "VideoIntraOnly")) {
+ } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
if (stream)
video_enc.gop_size = 1;
- } else if (!strcasecmp(cmd, "VideoHighQuality")) {
+ } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
if (stream)
video_enc.mb_decision = FF_MB_DECISION_BITS;
- } else if (!strcasecmp(cmd, "Video4MotionVector")) {
+ } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
if (stream) {
video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove
video_enc.flags |= CODEC_FLAG_4MV;
}
- } else if (!strcasecmp(cmd, "AVOptionVideo") ||
- !strcasecmp(cmd, "AVOptionAudio")) {
+ } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
+ !av_strcasecmp(cmd, "AVOptionAudio")) {
char arg2[1024];
AVCodecContext *avctx;
int type;
get_arg(arg, sizeof(arg), &p);
get_arg(arg2, sizeof(arg2), &p);
- if (!strcasecmp(cmd, "AVOptionVideo")) {
+ if (!av_strcasecmp(cmd, "AVOptionVideo")) {
avctx = &video_enc;
type = AV_OPT_FLAG_VIDEO_PARAM;
} else {
if (avserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
ERROR("AVOption error: %s %s\n", arg, arg2);
}
- } else if (!strcasecmp(cmd, "AVPresetVideo") ||
- !strcasecmp(cmd, "AVPresetAudio")) {
+ } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
+ !av_strcasecmp(cmd, "AVPresetAudio")) {
AVCodecContext *avctx;
int type;
get_arg(arg, sizeof(arg), &p);
- if (!strcasecmp(cmd, "AVPresetVideo")) {
+ if (!av_strcasecmp(cmd, "AVPresetVideo")) {
avctx = &video_enc;
video_enc.codec_id = video_id;
type = AV_OPT_FLAG_VIDEO_PARAM;
if (avserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
ERROR("AVPreset error: %s\n", arg);
}
- } else if (!strcasecmp(cmd, "VideoTag")) {
+ } else if (!av_strcasecmp(cmd, "VideoTag")) {
get_arg(arg, sizeof(arg), &p);
if ((strlen(arg) == 4) && stream)
video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
- } else if (!strcasecmp(cmd, "BitExact")) {
+ } else if (!av_strcasecmp(cmd, "BitExact")) {
if (stream)
video_enc.flags |= CODEC_FLAG_BITEXACT;
- } else if (!strcasecmp(cmd, "DctFastint")) {
+ } else if (!av_strcasecmp(cmd, "DctFastint")) {
if (stream)
video_enc.dct_algo = FF_DCT_FASTINT;
- } else if (!strcasecmp(cmd, "IdctSimple")) {
+ } else if (!av_strcasecmp(cmd, "IdctSimple")) {
if (stream)
video_enc.idct_algo = FF_IDCT_SIMPLE;
- } else if (!strcasecmp(cmd, "Qscale")) {
+ } else if (!av_strcasecmp(cmd, "Qscale")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
video_enc.flags |= CODEC_FLAG_QSCALE;
video_enc.global_quality = FF_QP2LAMBDA * atoi(arg);
}
- } else if (!strcasecmp(cmd, "VideoQDiff")) {
+ } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
video_enc.max_qdiff = atoi(arg);
ERROR("VideoQDiff out of range\n");
}
}
- } else if (!strcasecmp(cmd, "VideoQMax")) {
+ } else if (!av_strcasecmp(cmd, "VideoQMax")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
video_enc.qmax = atoi(arg);
ERROR("VideoQMax out of range\n");
}
}
- } else if (!strcasecmp(cmd, "VideoQMin")) {
+ } else if (!av_strcasecmp(cmd, "VideoQMin")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
video_enc.qmin = atoi(arg);
ERROR("VideoQMin out of range\n");
}
}
- } else if (!strcasecmp(cmd, "LumaElim")) {
+ } else if (!av_strcasecmp(cmd, "LumaElim")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
video_enc.luma_elim_threshold = atoi(arg);
- } else if (!strcasecmp(cmd, "ChromaElim")) {
+ } else if (!av_strcasecmp(cmd, "ChromaElim")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
video_enc.chroma_elim_threshold = atoi(arg);
- } else if (!strcasecmp(cmd, "LumiMask")) {
+ } else if (!av_strcasecmp(cmd, "LumiMask")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
video_enc.lumi_masking = atof(arg);
- } else if (!strcasecmp(cmd, "DarkMask")) {
+ } else if (!av_strcasecmp(cmd, "DarkMask")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
video_enc.dark_masking = atof(arg);
- } else if (!strcasecmp(cmd, "NoVideo")) {
- video_id = CODEC_ID_NONE;
- } else if (!strcasecmp(cmd, "NoAudio")) {
- audio_id = CODEC_ID_NONE;
- } else if (!strcasecmp(cmd, "ACL")) {
+ } else if (!av_strcasecmp(cmd, "NoVideo")) {
+ video_id = AV_CODEC_ID_NONE;
+ } else if (!av_strcasecmp(cmd, "NoAudio")) {
+ audio_id = AV_CODEC_ID_NONE;
+ } else if (!av_strcasecmp(cmd, "ACL")) {
parse_acl_row(stream, feed, NULL, p, filename, line_num);
- } else if (!strcasecmp(cmd, "DynamicACL")) {
+ } else if (!av_strcasecmp(cmd, "DynamicACL")) {
if (stream) {
get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p);
}
- } else if (!strcasecmp(cmd, "RTSPOption")) {
+ } else if (!av_strcasecmp(cmd, "RTSPOption")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
av_freep(&stream->rtsp_option);
stream->rtsp_option = av_strdup(arg);
}
- } else if (!strcasecmp(cmd, "MulticastAddress")) {
+ } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
if (resolve_host(&stream->multicast_ip, arg) != 0) {
stream->is_multicast = 1;
stream->loop = 1; /* default is looping */
}
- } else if (!strcasecmp(cmd, "MulticastPort")) {
+ } else if (!av_strcasecmp(cmd, "MulticastPort")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
stream->multicast_port = atoi(arg);
- } else if (!strcasecmp(cmd, "MulticastTTL")) {
+ } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
stream->multicast_ttl = atoi(arg);
- } else if (!strcasecmp(cmd, "NoLoop")) {
+ } else if (!av_strcasecmp(cmd, "NoLoop")) {
if (stream)
stream->loop = 0;
- } else if (!strcasecmp(cmd, "</Stream>")) {
+ } else if (!av_strcasecmp(cmd, "</Stream>")) {
if (!stream) {
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);
}
stream = NULL;
}
- } else if (!strcasecmp(cmd, "<Redirect")) {
+ } else if (!av_strcasecmp(cmd, "<Redirect")) {
/*********************************************/
char *q;
if (stream || feed || redirect) {
*q = '\0';
redirect->stream_type = STREAM_TYPE_REDIRECT;
}
- } else if (!strcasecmp(cmd, "URL")) {
+ } else if (!av_strcasecmp(cmd, "URL")) {
if (redirect)
get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p);
- } else if (!strcasecmp(cmd, "</Redirect>")) {
+ } else if (!av_strcasecmp(cmd, "</Redirect>")) {
if (!redirect) {
ERROR("No corresponding <Redirect> for </Redirect>\n");
} else {
}
redirect = NULL;
}
- } else if (!strcasecmp(cmd, "LoadModule")) {
+ } else if (!av_strcasecmp(cmd, "LoadModule")) {
get_arg(arg, sizeof(arg), &p);
#if HAVE_DLOPEN
load_module(arg);
static void opt_debug(void)
{
avserver_debug = 1;
- avserver_daemon = 0;
logfilename[0] = '-';
}
-static void show_help(void)
+void show_help_default(const char *opt, const char *arg)
{
printf("usage: avserver [options]\n"
"Hyper fast multi format Audio/Video streaming server\n");
printf("\n");
- show_help_options(options, "Main options:\n", 0, 0);
+ show_help_options(options, "Main options:", 0, 0, 0);
}
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();
+ 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);
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);
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);