diff --git a/avconv.c b/avconv.c index 0b75cbe214..4bd28e6e3b 100644 --- a/avconv.c +++ b/avconv.c @@ -190,7 +190,6 @@ static void avconv_cleanup(int ret) for (j = 0; j < ost->nb_bitstream_filters; j++) av_bsf_free(&ost->bsf_ctx[j]); av_freep(&ost->bsf_ctx); - av_freep(&ost->bitstream_filters); av_frame_free(&ost->filtered_frame); @@ -1798,17 +1797,8 @@ static int init_output_bsfs(OutputStream *ost) if (!ost->nb_bitstream_filters) return 0; - ost->bsf_ctx = av_mallocz_array(ost->nb_bitstream_filters, sizeof(*ost->bsf_ctx)); - if (!ost->bsf_ctx) - return AVERROR(ENOMEM); - for (i = 0; i < ost->nb_bitstream_filters; i++) { - ret = av_bsf_alloc(ost->bitstream_filters[i], &ctx); - if (ret < 0) { - av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n"); - return ret; - } - ost->bsf_ctx[i] = ctx; + ctx = ost->bsf_ctx[i]; ret = avcodec_parameters_copy(ctx->par_in, i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar); @@ -1820,12 +1810,11 @@ static int init_output_bsfs(OutputStream *ost) ret = av_bsf_init(ctx); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n", - ost->bitstream_filters[i]->name); + ctx->filter->name); return ret; } } - ctx = ost->bsf_ctx[ost->nb_bitstream_filters - 1]; ret = avcodec_parameters_copy(ost->st->codecpar, ctx->par_out); if (ret < 0) return ret; diff --git a/avconv.h b/avconv.h index fcdf3d0461..6360f76c0b 100644 --- a/avconv.h +++ b/avconv.h @@ -360,7 +360,6 @@ typedef struct OutputStream { AVRational mux_timebase; int nb_bitstream_filters; - const AVBitStreamFilter **bitstream_filters; AVBSFContext **bsf_ctx; AVCodecContext *enc_ctx; diff --git a/avconv_opt.c b/avconv_opt.c index 362a5b7f5e..ba37a3a31d 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -1025,26 +1025,54 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st); while (bsfs && *bsfs) { const AVBitStreamFilter *filter; - char *bsf; + const char *bsf, *bsf_options_str, *bsf_name; + AVDictionary *bsf_options = NULL; - bsf = av_get_token(&bsfs, ","); + bsf = bsf_options_str = av_get_token(&bsfs, ","); if (!bsf) exit_program(1); - - filter = av_bsf_get_by_name(bsf); - if (!filter) { - av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf); + bsf_name = av_get_token(&bsf_options_str, "="); + if (!bsf_name) exit_program(1); + + filter = av_bsf_get_by_name(bsf_name); + if (!filter) { + av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf_name); + exit_program(1); + } + if (*bsf_options_str++) { + ret = av_dict_parse_string(&bsf_options, bsf_options_str, "=", ":", 0); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error parsing options for bitstream filter %s\n", bsf_name); + exit_program(1); + } } av_freep(&bsf); - ost->bitstream_filters = av_realloc_array(ost->bitstream_filters, - ost->nb_bitstream_filters + 1, - sizeof(*ost->bitstream_filters)); - if (!ost->bitstream_filters) + ost->bsf_ctx = av_realloc_array(ost->bsf_ctx, + ost->nb_bitstream_filters + 1, + sizeof(*ost->bsf_ctx)); + if (!ost->bsf_ctx) exit_program(1); - ost->bitstream_filters[ost->nb_bitstream_filters++] = filter; + ret = av_bsf_alloc(filter, &ost->bsf_ctx[ost->nb_bitstream_filters]); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error allocating a bistream filter context\n"); + exit_program(1); + } + ost->nb_bitstream_filters++; + + if (bsf_options) { + ret = av_opt_set_dict(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, &bsf_options); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error setting options for bitstream filter %s\n", bsf_name); + exit_program(1); + } + assert_avoptions(bsf_options); + av_dict_free(&bsf_options); + } + av_freep(&bsf_name); + if (*bsfs) bsfs++; }