lavf/bit: Use pkt->size instead of a constant for G.729 frame size.
[ffmpeg.git] / ffserver_config.c
index 6c7b9b8..54135be 100644 (file)
@@ -25,9 +25,6 @@
 #include "libavutil/pixdesc.h"
 #include "libavutil/avassert.h"
 
-// FIXME those are internal headers, ffserver _really_ shouldn't use them
-#include "libavformat/ffm.h"
-
 #include "cmdutils.h"
 #include "ffserver_config.h"
 
@@ -42,8 +39,8 @@ static void report_config_error(const char *filename, int line_num,
                                 int log_level, int *errors, const char *fmt,
                                 ...);
 
-#define ERROR(...)   report_config_error(config->filename, config->line_num,\
-                                         AV_LOG_ERROR, &config->errors,  __VA_ARGS__)
+#define ERROR(...) report_config_error(config->filename, config->line_num,\
+                                       AV_LOG_ERROR, &config->errors, __VA_ARGS__)
 #define WARNING(...) report_config_error(config->filename, config->line_num,\
                                          AV_LOG_WARNING, &config->warnings, __VA_ARGS__)
 
@@ -116,7 +113,8 @@ void ffserver_parse_acl_row(FFServerStream *stream, FFServerStream* feed,
 {
     char arg[1024];
     FFServerIPAddressACL acl;
-    int errors = 0;
+    FFServerIPAddressACL *nacl;
+    FFServerIPAddressACL **naclp;
 
     ffserver_get_arg(arg, sizeof(arg), &p);
     if (av_strcasecmp(arg, "allow") == 0)
@@ -126,17 +124,19 @@ void ffserver_parse_acl_row(FFServerStream *stream, FFServerStream* feed,
     else {
         fprintf(stderr, "%s:%d: ACL action '%s' should be ALLOW or DENY.\n",
                 filename, line_num, arg);
-        errors++;
+        goto bail;
     }
 
     ffserver_get_arg(arg, sizeof(arg), &p);
 
     if (resolve_host(&acl.first, arg)) {
-        fprintf(stderr, "%s:%d: ACL refers to invalid host or IP address '%s'\n",
+        fprintf(stderr,
+                "%s:%d: ACL refers to invalid host or IP address '%s'\n",
                 filename, line_num, arg);
-        errors++;
-    } else
-        acl.last = acl.first;
+        goto bail;
+    }
+
+    acl.last = acl.first;
 
     ffserver_get_arg(arg, sizeof(arg), &p);
 
@@ -145,44 +145,49 @@ void ffserver_parse_acl_row(FFServerStream *stream, FFServerStream* feed,
             fprintf(stderr,
                     "%s:%d: ACL refers to invalid host or IP address '%s'\n",
                     filename, line_num, arg);
-            errors++;
+            goto bail;
         }
     }
 
-    if (!errors) {
-        FFServerIPAddressACL *nacl = av_mallocz(sizeof(*nacl));
-        FFServerIPAddressACL **naclp = 0;
+    nacl = av_mallocz(sizeof(*nacl));
+    if (!nacl) {
+        fprintf(stderr, "Failed to allocate FFServerIPAddressACL\n");
+        goto bail;
+    }
 
-        acl.next = 0;
-        *nacl = acl;
+    naclp = 0;
 
-        if (stream)
-            naclp = &stream->acl;
-        else if (feed)
-            naclp = &feed->acl;
-        else if (ext_acl)
-            naclp = &ext_acl;
-        else {
-            fprintf(stderr, "%s:%d: ACL found not in <Stream> or <Feed>\n",
-                    filename, line_num);
-            errors++;
-        }
+    acl.next = 0;
+    *nacl = acl;
 
-        if (naclp) {
-            while (*naclp)
-                naclp = &(*naclp)->next;
+    if (stream)
+        naclp = &stream->acl;
+    else if (feed)
+        naclp = &feed->acl;
+    else if (ext_acl)
+        naclp = &ext_acl;
+    else
+        fprintf(stderr, "%s:%d: ACL found not in <Stream> or <Feed>\n",
+                filename, line_num);
+
+    if (naclp) {
+        while (*naclp)
+            naclp = &(*naclp)->next;
+
+        *naclp = nacl;
+    } else
+        av_free(nacl);
+
+bail:
+  return;
 
-            *naclp = nacl;
-        } else
-            av_free(nacl);
-    }
 }
 
 /* add a codec and set the default parameters */
 static void add_codec(FFServerStream *stream, AVCodecContext *av,
                       FFServerConfig *config)
 {
-    AVStream *st;
+    LayeredAVStream *st;
     AVDictionary **opts, *recommended = NULL;
     char *enc_config;
 
@@ -194,18 +199,44 @@ static void add_codec(FFServerStream *stream, AVCodecContext *av,
     av_dict_copy(&recommended, *opts, 0);
     av_opt_set_dict2(av->priv_data, opts, AV_OPT_SEARCH_CHILDREN);
     av_opt_set_dict2(av, opts, AV_OPT_SEARCH_CHILDREN);
+
     if (av_dict_count(*opts))
         av_log(NULL, AV_LOG_WARNING,
-               "Something is wrong, %d options are not set!\n", av_dict_count(*opts));
+               "Something is wrong, %d options are not set!\n",
+               av_dict_count(*opts));
+
+    if (!config->stream_use_defaults) {
+        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);
+        }
+        goto done;
+    }
+
+    /* stream_use_defaults = true */
 
-    if (config->stream_use_defaults) {
-    //TODO: reident
     /* compute default parameters */
     switch(av->codec_type) {
     case AVMEDIA_TYPE_AUDIO:
-        if (!av_dict_get(recommended, "ab", NULL, 0)) {
+        if (!av_dict_get(recommended, "b", NULL, 0)) {
             av->bit_rate = 64000;
-            av_dict_set_int(&recommended, "ab", av->bit_rate, 0);
+            av_dict_set_int(&recommended, "b", av->bit_rate, 0);
             WARNING("Setting default value for audio bit rate = %d. "
                     "Use NoDefaults to disable it.\n",
                     av->bit_rate);
@@ -262,8 +293,8 @@ static void add_codec(FFServerStream *stream, AVCodecContext *av,
         if (!av_dict_get(recommended, "rc_eq", NULL, 0)) {
             av->rc_eq = av_strdup("tex^qComp");
             av_dict_set(&recommended, "rc_eq", "tex^qComp", 0);
-            WARNING("Setting default value for video rate control equation = %s. "
-                    "Use NoDefaults to disable it.\n",
+            WARNING("Setting default value for video rate control equation = "
+                    "%s. Use NoDefaults to disable it.\n",
                     av->rc_eq);
         }
         if (!av_dict_get(recommended, "maxrate", NULL, 0)) {
@@ -285,43 +316,29 @@ 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));
+done:
+    st = av_mallocz(sizeof(*st));
     if (!st)
         return;
     av_dict_get_string(recommended, &enc_config, '=', ',');
     av_dict_free(&recommended);
-    av_stream_set_recommended_encoder_configuration(st, enc_config);
+    st->recommended_encoder_configuration = enc_config;
     st->codec = av;
+    st->codecpar = avcodec_parameters_alloc();
+    avcodec_parameters_from_context(st->codecpar, av);
     stream->streams[stream->nb_streams++] = st;
 }
 
-static int ffserver_set_codec(AVCodecContext *ctx, const char *codec_name, FFServerConfig *config)
+static int ffserver_set_codec(AVCodecContext *ctx, const char *codec_name,
+                              FFServerConfig *config)
 {
     int ret;
     AVCodec *codec = avcodec_find_encoder_by_name(codec_name);
     if (!codec || codec->type != ctx->codec_type) {
         report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
-                            &config->errors, "Invalid codec name: '%s'\n", codec_name);
+                            &config->errors,
+                            "Invalid codec name: '%s'\n", codec_name);
         return 0;
     }
     if (ctx->codec_id == AV_CODEC_ID_NONE && !ctx->priv_data) {
@@ -330,8 +347,10 @@ static int ffserver_set_codec(AVCodecContext *ctx, const char *codec_name, FFSer
         ctx->codec = codec;
     }
     if (ctx->codec_id != codec->id)
-        report_config_error(config->filename, config->line_num, AV_LOG_ERROR, &config->errors,
-                            "Inconsistent configuration: trying to set '%s' codec option, but '%s' codec is used previously\n",
+        report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
+                            &config->errors,
+                            "Inconsistent configuration: trying to set '%s' "
+                            "codec option, but '%s' codec is used previously\n",
                             codec_name, avcodec_get_name(ctx->codec_id));
     return 0;
 }
@@ -368,12 +387,13 @@ static int ffserver_opt_preset(const char *arg, int type, FFServerConfig *config
             continue;
         e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
         if(e){
-            av_log(NULL, AV_LOG_ERROR, "%s: Invalid syntax: '%s'\n", filename, line);
+            av_log(NULL, AV_LOG_ERROR, "%s: Invalid syntax: '%s'\n", filename,
+                   line);
             ret = AVERROR(EINVAL);
             break;
         }
-        if ((!strcmp(tmp, "acodec") && avctx->codec_type == AVMEDIA_TYPE_AUDIO) ||
-             !strcmp(tmp, "vcodec") && avctx->codec_type == AVMEDIA_TYPE_VIDEO)
+        if (!strcmp(tmp, "acodec") && avctx->codec_type == AVMEDIA_TYPE_AUDIO ||
+            !strcmp(tmp, "vcodec") && avctx->codec_type == AVMEDIA_TYPE_VIDEO)
         {
             if (ffserver_set_codec(avctx, tmp2, config) < 0)
                 break;
@@ -390,7 +410,9 @@ static int ffserver_opt_preset(const char *arg, int type, FFServerConfig *config
     return ret;
 }
 
-static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename, const char *mime_type)
+static AVOutputFormat *ffserver_guess_format(const char *short_name,
+                                             const char *filename,
+                                             const char *mime_type)
 {
     AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
 
@@ -409,7 +431,9 @@ static AVOutputFormat *ffserver_guess_format(const char *short_name, const char
     return fmt;
 }
 
-static void vreport_config_error(const char *filename, int line_num, int log_level, int *errors, const char *fmt, va_list vl)
+static void vreport_config_error(const char *filename, int line_num,
+                                 int log_level, int *errors, const char *fmt,
+                                 va_list vl)
 {
     av_log(NULL, log_level, "%s:%d: ", filename, line_num);
     av_vlog(NULL, log_level, fmt, vl);
@@ -417,7 +441,9 @@ static void vreport_config_error(const char *filename, int line_num, int log_lev
         (*errors)++;
 }
 
-static void report_config_error(const char *filename, int line_num, int log_level, int *errors, const char *fmt, ...)
+static void report_config_error(const char *filename, int line_num,
+                                int log_level, int *errors,
+                                const char *fmt, ...)
 {
     va_list vl;
     va_start(vl, fmt);
@@ -425,8 +451,9 @@ static void report_config_error(const char *filename, int line_num, int log_leve
     va_end(vl);
 }
 
-static int ffserver_set_int_param(int *dest, const char *value, int factor, int min, int max,
-                                  FFServerConfig *config, const char *error_msg, ...)
+static int ffserver_set_int_param(int *dest, const char *value, int factor,
+                                  int min, int max, FFServerConfig *config,
+                                  const char *error_msg, ...)
 {
     int tmp;
     char *tailp;
@@ -437,7 +464,7 @@ static int ffserver_set_int_param(int *dest, const char *value, int factor, int
     if (tmp < min || tmp > max)
         goto error;
     if (factor) {
-        if (FFABS(tmp) > INT_MAX / FFABS(factor))
+        if (tmp == INT_MIN || FFABS(tmp) > INT_MAX / FFABS(factor))
             goto error;
         tmp *= factor;
     }
@@ -457,8 +484,10 @@ static int ffserver_set_int_param(int *dest, const char *value, int factor, int
     return AVERROR(EINVAL);
 }
 
-static int ffserver_set_float_param(float *dest, const char *value, float factor, float min, float max,
-                                    FFServerConfig *config, const char *error_msg, ...)
+static int ffserver_set_float_param(float *dest, const char *value,
+                                    float factor, float min, float max,
+                                    FFServerConfig *config,
+                                    const char *error_msg, ...)
 {
     double tmp;
     char *tailp;
@@ -486,7 +515,8 @@ static int ffserver_set_float_param(float *dest, const char *value, float factor
     return AVERROR(EINVAL);
 }
 
-static int ffserver_save_avoption(const char *opt, const char *arg, int type, FFServerConfig *config)
+static int ffserver_save_avoption(const char *opt, const char *arg, int type,
+                                  FFServerConfig *config)
 {
     static int hinted = 0;
     int ret = 0;
@@ -537,31 +567,35 @@ static int ffserver_save_avoption(const char *opt, const char *arg, int type, FF
         option = opt;
     }
 
-    o = av_opt_find(ctx, option, NULL, type | AV_OPT_FLAG_ENCODING_PARAM, AV_OPT_SEARCH_CHILDREN);
-    if (!o && (!strcmp(option, "time_base")  || !strcmp(option, "pixel_format") ||
-               !strcmp(option, "video_size") || !strcmp(option, "codec_tag")))
+    o = av_opt_find(ctx, option, NULL, type | AV_OPT_FLAG_ENCODING_PARAM,
+                    AV_OPT_SEARCH_CHILDREN);
+    if (!o &&
+        (!strcmp(option, "time_base")  || !strcmp(option, "pixel_format") ||
+         !strcmp(option, "video_size") || !strcmp(option, "codec_tag")))
         o = av_opt_find(ctx, option, NULL, 0, 0);
     if (!o) {
         report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
                             &config->errors, "Option not found: '%s'\n", opt);
         if (!hinted && ctx->codec_id == AV_CODEC_ID_NONE) {
             hinted = 1;
-            report_config_error(config->filename, config->line_num, AV_LOG_ERROR, NULL,
-                                "If '%s' is a codec private option, then prefix it with codec name, "
-                                "for example '%s:%s %s' or define codec earlier.\n",
-                                opt, avcodec_get_name(guessed_codec_id) ,opt, arg);
+            report_config_error(config->filename, config->line_num,
+                                AV_LOG_ERROR, NULL, "If '%s' is a codec private"
+                                "option, then prefix it with codec name, for "
+                                "example '%s:%s %s' or define codec earlier.\n",
+                                opt, avcodec_get_name(guessed_codec_id) ,opt,
+                                arg);
         }
     } else if ((ret = av_opt_set(ctx, option, arg, AV_OPT_SEARCH_CHILDREN)) < 0) {
         report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
                 &config->errors, "Invalid value for option %s (%s): %s\n", opt,
                 arg, av_err2str(ret));
     } else if ((e = av_dict_get(*dict, option, NULL, 0))) {
-        if ((o->type == AV_OPT_TYPE_FLAGS) && arg && (arg[0] == '+' || arg[0] == '-'))
+        if ((o->type == AV_OPT_TYPE_FLAGS) && arg &&
+            (arg[0] == '+' || arg[0] == '-'))
             return av_dict_set(dict, option, arg, AV_DICT_APPEND);
         report_config_error(config->filename, config->line_num, AV_LOG_ERROR,
-                &config->errors,
-                "Redeclaring value of option '%s'. Previous value was: '%s'.\n",
-                opt, e->value);
+                            &config->errors, "Redeclaring value of option '%s'."
+                            "Previous value was: '%s'.\n", opt, e->value);
     } else if (av_dict_set(dict, option, arg, 0) < 0) {
         return AVERROR(ENOMEM);
     }
@@ -590,9 +624,11 @@ static int ffserver_parse_config_global(FFServerConfig *config, const char *cmd,
         if (val < 1024)
             WARNING("Trying to use IETF assigned system port: '%d'\n", val);
         config->http_addr.sin_port = htons(val);
-    } else if (!av_strcasecmp(cmd, "HTTPBindAddress") || !av_strcasecmp(cmd, "BindAddress")) {
+    } else if (!av_strcasecmp(cmd, "HTTPBindAddress") ||
+               !av_strcasecmp(cmd, "BindAddress")) {
         if (!av_strcasecmp(cmd, "BindAddress"))
-            WARNING("BindAddress option is deprecated. Use HTTPBindAddress instead.\n");
+            WARNING("BindAddress option is deprecated. Use HTTPBindAddress "
+                    "instead.\n");
         ffserver_get_arg(arg, sizeof(arg), p);
         if (resolve_host(&config->http_addr.sin_addr, arg))
             ERROR("Invalid host/IP address: '%s'\n", arg);
@@ -612,17 +648,21 @@ static int ffserver_parse_config_global(FFServerConfig *config, const char *cmd,
         ffserver_set_int_param(&val, arg, 0, 1, 65535, config,
                 "Invalid MaxHTTPConnections: %s\n", arg);
         config->nb_max_http_connections = val;
-        if (config->nb_max_connections > config->nb_max_http_connections)
-            ERROR("Inconsistent configuration: MaxClients(%d) > MaxHTTPConnections(%d)\n",
-                  config->nb_max_connections, config->nb_max_http_connections);
+        if (config->nb_max_connections > config->nb_max_http_connections) {
+            ERROR("Inconsistent configuration: MaxClients(%d) > "
+                  "MaxHTTPConnections(%d)\n", config->nb_max_connections,
+                  config->nb_max_http_connections);
+        }
     } else if (!av_strcasecmp(cmd, "MaxClients")) {
         ffserver_get_arg(arg, sizeof(arg), p);
         ffserver_set_int_param(&val, arg, 0, 1, 65535, config,
                 "Invalid MaxClients: '%s'\n", arg);
         config->nb_max_connections = val;
-        if (config->nb_max_connections > config->nb_max_http_connections)
-            ERROR("Inconsistent configuration: MaxClients(%d) > MaxHTTPConnections(%d)\n",
-                  config->nb_max_connections, config->nb_max_http_connections);
+        if (config->nb_max_connections > config->nb_max_http_connections) {
+            ERROR("Inconsistent configuration: MaxClients(%d) > "
+                  "MaxHTTPConnections(%d)\n", config->nb_max_connections,
+                  config->nb_max_http_connections);
+        }
     } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
         int64_t llval;
         char *tailp;
@@ -634,8 +674,10 @@ static int ffserver_parse_config_global(FFServerConfig *config, const char *cmd,
         else
             config->max_bandwidth = llval;
     } else if (!av_strcasecmp(cmd, "CustomLog")) {
-        if (!config->debug)
-            ffserver_get_arg(config->logfilename, sizeof(config->logfilename), p);
+        if (!config->debug) {
+            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")) {
@@ -647,8 +689,8 @@ static int ffserver_parse_config_global(FFServerConfig *config, const char *cmd,
     return 0;
 }
 
-static int ffserver_parse_config_feed(FFServerConfig *config, const char *cmd, const char **p,
-                                      FFServerStream **pfeed)
+static int ffserver_parse_config_feed(FFServerConfig *config, const char *cmd,
+                                      const char **p, FFServerStream **pfeed)
 {
     FFServerStream *feed;
     char arg[1024];
@@ -699,15 +741,16 @@ static int ffserver_parse_config_feed(FFServerConfig *config, const char *cmd, c
 
         feed->child_argv[i] =
             av_asprintf("http://%s:%d/%s",
-                        (config->http_addr.sin_addr.s_addr == INADDR_ANY) ? "127.0.0.1" :
-                        inet_ntoa(config->http_addr.sin_addr), ntohs(config->http_addr.sin_port),
-                        feed->filename);
+                        (config->http_addr.sin_addr.s_addr == INADDR_ANY) ?
+                        "127.0.0.1" : inet_ntoa(config->http_addr.sin_addr),
+                        ntohs(config->http_addr.sin_port), feed->filename);
         if (!feed->child_argv[i])
             return AVERROR(ENOMEM);
     } else if (!av_strcasecmp(cmd, "ACL")) {
         ffserver_parse_acl_row(NULL, feed, NULL, *p, config->filename,
                 config->line_num);
-    } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) {
+    } else if (!av_strcasecmp(cmd, "File") ||
+               !av_strcasecmp(cmd, "ReadOnlyFile")) {
         ffserver_get_arg(feed->feed_filename, sizeof(feed->feed_filename), p);
         feed->readonly = !av_strcasecmp(cmd, "ReadOnlyFile");
     } else if (!av_strcasecmp(cmd, "Truncate")) {
@@ -742,9 +785,10 @@ static int ffserver_parse_config_feed(FFServerConfig *config, const char *cmd, c
             break;
         }
         feed->feed_max_size = (int64_t)fsize;
-        if (feed->feed_max_size < FFM_PACKET_SIZE*4)
+        if (feed->feed_max_size < FFM_PACKET_SIZE*4) {
             ERROR("Feed max file size is too small. Must be at least %d.\n",
-                    FFM_PACKET_SIZE*4);
+                  FFM_PACKET_SIZE*4);
+        }
     } else if (!av_strcasecmp(cmd, "</Feed>")) {
         *pfeed = NULL;
     } else {
@@ -753,7 +797,8 @@ static int ffserver_parse_config_feed(FFServerConfig *config, const char *cmd, c
     return 0;
 }
 
-static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, const char **p,
+static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
+                                        const char **p,
                                         FFServerStream **pstream)
 {
     char arg[1024], arg2[1024];
@@ -824,8 +869,10 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
         } else {
             stream->stream_type = STREAM_TYPE_LIVE;
             /* JPEG cannot be used here, so use single frame MJPEG */
-            if (!strcmp(arg, "jpeg"))
-                strcpy(arg, "mjpeg");
+            if (!strcmp(arg, "jpeg")) {
+                strcpy(arg, "singlejpeg");
+                stream->single_frame=1;
+            }
             stream->fmt = ffserver_guess_format(arg, NULL, NULL);
             if (!stream->fmt)
                 ERROR("Unknown Format: '%s'\n", arg);
@@ -883,7 +930,8 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
         ffserver_get_arg(arg, sizeof(arg), p);
         ffserver_set_float_param(&f, arg, 1000, -FLT_MAX, FLT_MAX, config,
                 "Invalid %s: '%s'\n", cmd, arg);
-        if (ffserver_save_avoption_int("ab", (int64_t)lrintf(f), AV_OPT_FLAG_AUDIO_PARAM, config) < 0)
+        if (ffserver_save_avoption_int("b", (int64_t)lrintf(f),
+                                       AV_OPT_FLAG_AUDIO_PARAM, config) < 0)
             goto nomem;
     } else if (!av_strcasecmp(cmd, "AudioChannels")) {
         ffserver_get_arg(arg, sizeof(arg), p);
@@ -909,7 +957,7 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
             }
         } else
             ERROR("Incorrect format for VideoBitRateRange. It should be "
-                    "<min>-<max>: '%s'.\n", arg);
+                  "<min>-<max>: '%s'.\n", arg);
     } else if (!av_strcasecmp(cmd, "Debug")) {
         ffserver_get_arg(arg, sizeof(arg), p);
         if (ffserver_save_avoption("debug", arg, AV_OPT_FLAG_AUDIO_PARAM, config) < 0 ||
@@ -929,13 +977,13 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
     } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
         ffserver_get_arg(arg, sizeof(arg), p);
         ffserver_set_int_param(&val, arg, 1000, INT_MIN, INT_MAX, config,
-                "Invalid %s: '%s'", cmd, arg);
+                               "Invalid %s: '%s'", cmd, arg);
         if (ffserver_save_avoption_int("bt", val, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
             goto nomem;
     } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
         ffserver_get_arg(arg, sizeof(arg), p);
         ffserver_set_int_param(&val, arg, 1000, INT_MIN, INT_MAX, config,
-                "Invalid %s: '%s'", cmd, arg);
+                               "Invalid %s: '%s'", cmd, arg);
         if (ffserver_save_avoption_int("b", val, AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
            goto nomem;
     } else if (!av_strcasecmp(cmd, "VideoSize")) {
@@ -983,9 +1031,11 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
         ffserver_get_arg(arg, sizeof(arg), p);
         ffserver_get_arg(arg2, sizeof(arg2), p);
         if (!av_strcasecmp(cmd, "AVOptionVideo"))
-            ret = ffserver_save_avoption(arg, arg2, AV_OPT_FLAG_VIDEO_PARAM, config);
+            ret = ffserver_save_avoption(arg, arg2, AV_OPT_FLAG_VIDEO_PARAM,
+                                         config);
         else
-            ret = ffserver_save_avoption(arg, arg2, AV_OPT_FLAG_AUDIO_PARAM, config);
+            ret = ffserver_save_avoption(arg, arg2, AV_OPT_FLAG_AUDIO_PARAM,
+                                         config);
         if (ret < 0)
             goto nomem;
     } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
@@ -998,10 +1048,12 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
     } else if (!av_strcasecmp(cmd, "VideoTag")) {
         ffserver_get_arg(arg, sizeof(arg), p);
         if (strlen(arg) == 4 &&
-            ffserver_save_avoption_int("codec_tag", MKTAG(arg[0], arg[1], arg[2], arg[3]),
+            ffserver_save_avoption_int("codec_tag",
+                                       MKTAG(arg[0], arg[1], arg[2], arg[3]),
                                        AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
             goto nomem;
     } else if (!av_strcasecmp(cmd, "BitExact")) {
+        config->bitexact = 1;
         if (ffserver_save_avoption("flags", "+bitexact", AV_OPT_FLAG_VIDEO_PARAM, config) < 0)
             goto nomem;
     } else if (!av_strcasecmp(cmd, "DctFastint")) {
@@ -1074,13 +1126,15 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
         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;
-            if (!config->no_audio && config->dummy_actx->codec_id != AV_CODEC_ID_NONE) {
+            if (!config->no_audio &&
+                config->dummy_actx->codec_id != AV_CODEC_ID_NONE) {
                 AVCodecContext *audio_enc = avcodec_alloc_context3(avcodec_find_encoder(config->dummy_actx->codec_id));
                 add_codec(stream, audio_enc, config);
             }
             if (config->dummy_vctx->codec_id == AV_CODEC_ID_NONE)
                 config->dummy_vctx->codec_id = config->guessed_video_codec_id;
-            if (!config->no_video && config->dummy_vctx->codec_id != AV_CODEC_ID_NONE) {
+            if (!config->no_video &&
+                config->dummy_vctx->codec_id != AV_CODEC_ID_NONE) {
                 AVCodecContext *video_enc = avcodec_alloc_context3(avcodec_find_encoder(config->dummy_vctx->codec_id));
                 add_codec(stream, video_enc, config);
             }
@@ -1089,8 +1143,11 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
         av_dict_free(&config->audio_opts);
         avcodec_free_context(&config->dummy_vctx);
         avcodec_free_context(&config->dummy_actx);
+        config->no_video = 0;
+        config->no_audio = 0;
         *pstream = NULL;
-    } else if (!av_strcasecmp(cmd, "File") || !av_strcasecmp(cmd, "ReadOnlyFile")) {
+    } 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")) {
@@ -1114,7 +1171,8 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd,
     return AVERROR(ENOMEM);
 }
 
-static int ffserver_parse_config_redirect(FFServerConfig *config, const char *cmd, const char **p,
+static int ffserver_parse_config_redirect(FFServerConfig *config,
+                                          const char *cmd, const char **p,
                                           FFServerStream **predirect)
 {
     FFServerStream *redirect;