ffserver: allow skip setting defaults
authorLukasz Marek <lukasz.m.luki2@gmail.com>
Sat, 15 Nov 2014 17:43:41 +0000 (18:43 +0100)
committerLukasz Marek <lukasz.m.luki2@gmail.com>
Wed, 26 Nov 2014 22:32:33 +0000 (23:32 +0100)
Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
doc/ffserver.texi
ffserver.c
ffserver_config.c
ffserver_config.h

index b7c5b6a..83b6520 100644 (file)
@@ -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.
index 933eb0e..e24243d 100644 (file)
@@ -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);
index e1d8d8c..324aa26 100644 (file)
@@ -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, "</Stream>")) {
+        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 <Stream></Stream>\n", cmd);
     }
index 60e88ec..4e1e0e0 100644 (file)
@@ -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);