Example usage:

    avconv -i INPUT -bsf filter[=opt1=val1:opt2=val2] OUTPUT

Signed-off-by: James Almer <jamr...@gmail.com>
---
 avconv.c     | 15 ++-------------
 avconv.h     |  1 -
 avconv_opt.c | 46 +++++++++++++++++++++++++++++++++++++---------
 3 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/avconv.c b/avconv.c
index 0b75cbe..4bd28e6 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 fcdf3d0..6360f76 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 362a5b7..ba37a3a 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);
+        bsf_name = av_get_token(&bsf_options_str, "=");
+        if (!bsf_name)
+            exit_program(1);
 
-        filter = av_bsf_get_by_name(bsf);
+        filter = av_bsf_get_by_name(bsf_name);
         if (!filter) {
-            av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);
+            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);
+
+        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);
 
-        ost->bitstream_filters[ost->nb_bitstream_filters++] = filter;
         if (*bsfs)
             bsfs++;
     }
-- 
2.10.1

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to