diff options
-rw-r--r-- | ffserver.c | 6 | ||||
-rw-r--r-- | ffserver_config.c | 77 |
2 files changed, 63 insertions, 20 deletions
diff --git a/ffserver.c b/ffserver.c index e24243d9ca..3702fd638a 100644 --- a/ffserver.c +++ b/ffserver.c @@ -3326,8 +3326,7 @@ static int add_av_stream(FFServerStream *feed, AVStream *st) av = st->codec; for(i=0;i<feed->nb_streams;i++) { - st = feed->streams[i]; - av1 = st->codec; + av1 = feed->streams[i]->codec; if (av1->codec_id == av->codec_id && av1->codec_type == av->codec_type && av1->bit_rate == av->bit_rate) { @@ -3355,6 +3354,9 @@ static int add_av_stream(FFServerStream *feed, AVStream *st) fst = add_av_stream1(feed, av, 0); if (!fst) return -1; + if (av_stream_get_recommended_encoder_configuration(st)) + av_stream_set_recommended_encoder_configuration(fst, + av_strdup(av_stream_get_recommended_encoder_configuration(st))); return feed->nb_streams - 1; } diff --git a/ffserver_config.c b/ffserver_config.c index 324aa262da..f34dc5e5b2 100644 --- a/ffserver_config.c +++ b/ffserver_config.c @@ -178,13 +178,15 @@ static void add_codec(FFServerStream *stream, AVCodecContext *av, FFServerConfig *config) { AVStream *st; - AVDictionary **opts; + AVDictionary **opts, *recommended = NULL; + char *enc_config; if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams)) return; opts = av->codec_type == AVMEDIA_TYPE_AUDIO ? &config->audio_opts : &config->video_opts; + 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)) @@ -196,63 +198,99 @@ static void add_codec(FFServerStream *stream, AVCodecContext *av, /* compute default parameters */ switch(av->codec_type) { case AVMEDIA_TYPE_AUDIO: - if (av->bit_rate == 0) + if (av->bit_rate == 0) { av->bit_rate = 64000; - if (av->sample_rate == 0) + av_dict_set_int(&recommended, "ab", av->bit_rate, 0); + } + if (av->sample_rate == 0) { av->sample_rate = 22050; - if (av->channels == 0) + av_dict_set_int(&recommended, "ar", av->sample_rate, 0); + } + if (av->channels == 0) { av->channels = 1; + av_dict_set_int(&recommended, "ac", av->channels, 0); + } break; case AVMEDIA_TYPE_VIDEO: - if (av->bit_rate == 0) + if (av->bit_rate == 0) { av->bit_rate = 64000; + av_dict_set_int(&recommended, "b", av->bit_rate, 0); + } if (av->time_base.num == 0){ av->time_base.den = 5; av->time_base.num = 1; + av_dict_set(&recommended, "time_base", "1/5", 0); } if (av->width == 0 || av->height == 0) { av->width = 160; av->height = 128; + av_dict_set(&recommended, "video_size", "160x128", 0); } /* Bitrate tolerance is less for streaming */ - if (av->bit_rate_tolerance == 0) + if (av->bit_rate_tolerance == 0) { av->bit_rate_tolerance = FFMAX(av->bit_rate / 4, (int64_t)av->bit_rate*av->time_base.num/av->time_base.den); - if (av->qmin == 0) + av_dict_set_int(&recommended, "bt", av->bit_rate_tolerance, 0); + } + if (av->qmin == 0) { av->qmin = 3; - if (av->qmax == 0) + av_dict_set_int(&recommended, "qmin", av->qmin, 0); + } + if (av->qmax == 0) { av->qmax = 31; - if (av->max_qdiff == 0) + av_dict_set_int(&recommended, "qmax", av->qmax, 0); + } + if (av->max_qdiff == 0) { av->max_qdiff = 3; + av_dict_set_int(&recommended, "qdiff", av->max_qdiff, 0); + } + /*FIXME: 0.5 is a default for these two, it is a dead code */ av->qcompress = 0.5; + av_dict_set(&recommended, "qcomp", "0.5", 0); av->qblur = 0.5; + av_dict_set(&recommended, "qblur", "0.5", 0); - if (!av->nsse_weight) + if (!av->nsse_weight) { av->nsse_weight = 8; + av_dict_set_int(&recommended, "nssew", av->nsse_weight, 0); + } av->frame_skip_cmp = FF_CMP_DCTMAX; - if (!av->me_method) + av_dict_set_int(&recommended, "skipcmp", FF_CMP_DCTMAX, 0); + if (!av->me_method) { av->me_method = ME_EPZS; + av_dict_set_int(&recommended, "me_method", ME_EPZS, 0); + } /* FIXME: rc_buffer_aggressivity and rc_eq are deprecated */ av->rc_buffer_aggressivity = 1.0; + av_dict_set(&recommended, "rc_buf_aggressivity", "1.0", 0); - if (!av->rc_eq) + if (!av->rc_eq) { av->rc_eq = av_strdup("tex^qComp"); - if (!av->i_quant_factor) + av_dict_set(&recommended, "rc_eq", "tex^qComp", 0); + } + if (!av->i_quant_factor) { av->i_quant_factor = -0.8; - if (!av->b_quant_factor) + av_dict_set(&recommended, "i_qfactor", "-0.8", 0); + } + if (!av->b_quant_factor) { av->b_quant_factor = 1.25; - if (!av->b_quant_offset) + av_dict_set(&recommended, "b_qfactor", "1.25", 0); + } + if (!av->b_quant_offset) { av->b_quant_offset = 1.25; - if (!av->rc_max_rate) + av_dict_set(&recommended, "b_qoffset", "1.25", 0); + } + if (!av->rc_max_rate) { av->rc_max_rate = av->bit_rate * 2; + av_dict_set_int(&recommended, "maxrate", av->rc_max_rate, 0); + } if (av->rc_max_rate && !av->rc_buffer_size) { av->rc_buffer_size = av->rc_max_rate; + av_dict_set_int(&recommended, "bufsize", av->rc_buffer_size, 0); } - - break; default: abort(); @@ -280,6 +318,9 @@ static void add_codec(FFServerStream *stream, AVCodecContext *av, st = av_mallocz(sizeof(AVStream)); if (!st) return; + av_dict_get_string(recommended, &enc_config, '=', ','); + av_dict_free(&recommended); + av_stream_set_recommended_encoder_configuration(st, enc_config); st->codec = av; stream->streams[stream->nb_streams++] = st; } |