diff --git a/doc/ffserver.texi b/doc/ffserver.texi index b7c5b6aea4..83b6520dd1 100644 --- a/doc/ffserver.texi +++ b/doc/ffserver.texi @@ -408,6 +408,12 @@ ignored, and the log is written to standard output. Set no-daemon mode. This option is currently ignored since now @command{ffserver} will always work in no-daemon mode, and is deprecated. + +@item UseDefaults +@item NoDefaults +Control whether default codec options are used for the all streams or not. +Each stream may overwrite this setting for its own. Default is @var{UseDefaults}. +The lastest occurrence overrides previous if multiple definitions. @end table @section Feed section @@ -571,6 +577,11 @@ deprecated in favor of @option{Metadata}. @item Metadata @var{key} @var{value} Set metadata value on the output stream. +@item UseDefaults +@item NoDefaults +Control whether default codec options are used for the stream or not. +Default is @var{UseDefaults} unless disabled globally. + @item NoAudio @item NoVideo Suppress audio/video. diff --git a/ffserver.c b/ffserver.c index 933eb0ec61..e24243d9ca 100644 --- a/ffserver.c +++ b/ffserver.c @@ -201,6 +201,7 @@ static FFServerConfig config = { .nb_max_http_connections = 2000, .nb_max_connections = 5, .max_bandwidth = 1000, + .use_defaults = 1, }; static void new_connection(int server_fd, int is_rtsp); diff --git a/ffserver_config.c b/ffserver_config.c index e1d8d8c378..324aa262da 100644 --- a/ffserver_config.c +++ b/ffserver_config.c @@ -191,6 +191,8 @@ static void add_codec(FFServerStream *stream, AVCodecContext *av, av_log(NULL, AV_LOG_WARNING, "Something is wrong, %d options are not set!\n", av_dict_count(*opts)); + if (config->stream_use_defaults) { + //TODO: reident /* compute default parameters */ switch(av->codec_type) { case AVMEDIA_TYPE_AUDIO: @@ -255,6 +257,25 @@ static void add_codec(FFServerStream *stream, AVCodecContext *av, default: abort(); } + } else { + switch(av->codec_type) { + case AVMEDIA_TYPE_AUDIO: + if (av->bit_rate == 0) + report_config_error(config->filename, config->line_num, AV_LOG_ERROR, + &config->errors, "audio bit rate is not set\n"); + if (av->sample_rate == 0) + report_config_error(config->filename, config->line_num, AV_LOG_ERROR, + &config->errors, "audio sample rate is not set\n"); + break; + case AVMEDIA_TYPE_VIDEO: + if (av->width == 0 || av->height == 0) + report_config_error(config->filename, config->line_num, AV_LOG_ERROR, + &config->errors, "video size is not set\n"); + break; + default: + av_assert0(0); + } + } st = av_mallocz(sizeof(AVStream)); if (!st) @@ -583,6 +604,10 @@ static int ffserver_parse_config_global(FFServerConfig *config, const char *cmd, ffserver_get_arg(config->logfilename, sizeof(config->logfilename), p); } else if (!av_strcasecmp(cmd, "LoadModule")) { ERROR("Loadable modules are no longer supported\n"); + } else if (!av_strcasecmp(cmd, "NoDefaults")) { + config->use_defaults = 0; + } else if (!av_strcasecmp(cmd, "UseDefaults")) { + config->use_defaults = 1; } else ERROR("Incorrect keyword: '%s'\n", cmd); return 0; @@ -738,6 +763,7 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, config->guessed_audio_codec_id = AV_CODEC_ID_NONE; config->guessed_video_codec_id = AV_CODEC_ID_NONE; } + config->stream_use_defaults = config->use_defaults; *pstream = stream; return 0; } @@ -1010,6 +1036,7 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, } else if (!av_strcasecmp(cmd, "NoLoop")) { stream->loop = 0; } else if (!av_strcasecmp(cmd, "")) { + config->stream_use_defaults &= 1; if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm")) { if (config->dummy_actx->codec_id == AV_CODEC_ID_NONE) config->dummy_actx->codec_id = config->guessed_audio_codec_id; @@ -1032,6 +1059,14 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) { ffserver_get_arg(stream->feed_filename, sizeof(stream->feed_filename), p); + } else if (!av_strcasecmp(cmd, "UseDefaults")) { + if (config->stream_use_defaults > 1) + WARNING("Multiple UseDefaults/NoDefaults entries.\n"); + config->stream_use_defaults = 3; + } else if (!av_strcasecmp(cmd, "NoDefaults")) { + if (config->stream_use_defaults > 1) + WARNING("Multiple UseDefaults/NoDefaults entries.\n"); + config->stream_use_defaults = 2; } else { ERROR("Invalid entry '%s' inside \n", cmd); } diff --git a/ffserver_config.h b/ffserver_config.h index 60e88ec4ae..4e1e0e09fc 100644 --- a/ffserver_config.h +++ b/ffserver_config.h @@ -106,6 +106,7 @@ typedef struct FFServerConfig { struct sockaddr_in rtsp_addr; int errors; int warnings; + int use_defaults; // Following variables MUST NOT be used outside configuration parsing code. enum AVCodecID guessed_audio_codec_id; enum AVCodecID guessed_video_codec_id; @@ -116,6 +117,7 @@ typedef struct FFServerConfig { int no_audio; int no_video; int line_num; + int stream_use_defaults; } FFServerConfig; void ffserver_get_arg(char *buf, int buf_size, const char **pp);