#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/random_seed.h"
#include "libavutil/parseutils.h"
#include "libavutil/opt.h"
+#include "libavutil/time.h"
+
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
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) {
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"
"<p>The number of current connections is %d, and this exceeds the limit of %d.</p>\r\n"
"</body></html>\r\n",
nb_connections, nb_max_connections);
+ av_assert0(len < sizeof(buffer));
send(fd, buffer, len, 0);
}
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"
"<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;
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"
"<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;
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"
//"<!-- 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:
{
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:
int sdp_data_size, 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);
}
/* 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")) {
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;
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"
"<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;
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);
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++;
}
if (av_read_packet(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 */
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;
}
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];
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(;;) {
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;
} 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")) {
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")) {
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);
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[] = {