[FFmpeg-devel] [PATCH 1/3] fftools/ffmpeg: use a bsf list instead of individual bsfs

Marton Balint cus at passwd.hu
Sat Apr 25 21:55:53 EEST 2020


Unfortunately the parsing part cannot use the API because it is supporting
shorthand options and the API is not.

Signed-off-by: Marton Balint <cus at passwd.hu>
---
 fftools/ffmpeg.c     | 72 ++++++++++++++--------------------------------------
 fftools/ffmpeg.h     |  3 +--
 fftools/ffmpeg_opt.c | 31 ++++++++++++++--------
 3 files changed, 40 insertions(+), 66 deletions(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index d896b14a14..e46575481b 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -558,9 +558,7 @@ static void ffmpeg_cleanup(int ret)
         if (!ost)
             continue;
 
-        for (j = 0; j < ost->nb_bitstream_filters; j++)
-            av_bsf_free(&ost->bsf_ctx[j]);
-        av_freep(&ost->bsf_ctx);
+        av_bsf_free(&ost->bsf_ctx);
 
         av_frame_free(&ost->filtered_frame);
         av_frame_free(&ost->last_frame);
@@ -859,40 +857,15 @@ static void output_packet(OutputFile *of, AVPacket *pkt,
 {
     int ret = 0;
 
-    /* apply the output bitstream filters, if any */
-    if (ost->nb_bitstream_filters) {
-        int idx;
-
-        ret = av_bsf_send_packet(ost->bsf_ctx[0], eof ? NULL : pkt);
+    /* apply the output bitstream filters */
+    if (ost->bsf_ctx) {
+        ret = av_bsf_send_packet(ost->bsf_ctx, eof ? NULL : pkt);
         if (ret < 0)
             goto finish;
-
-        eof = 0;
-        idx = 1;
-        while (idx) {
-            /* get a packet from the previous filter up the chain */
-            ret = av_bsf_receive_packet(ost->bsf_ctx[idx - 1], pkt);
-            if (ret == AVERROR(EAGAIN)) {
-                ret = 0;
-                idx--;
-                continue;
-            } else if (ret == AVERROR_EOF) {
-                eof = 1;
-            } else if (ret < 0)
-                goto finish;
-
-            /* send it to the next filter down the chain or to the muxer */
-            if (idx < ost->nb_bitstream_filters) {
-                ret = av_bsf_send_packet(ost->bsf_ctx[idx], eof ? NULL : pkt);
-                if (ret < 0)
-                    goto finish;
-                idx++;
-                eof = 0;
-            } else if (eof)
-                goto finish;
-            else
-                write_packet(of, pkt, ost, 0);
-        }
+        while ((ret = av_bsf_receive_packet(ost->bsf_ctx, pkt)) >= 0)
+            write_packet(of, pkt, ost, 0);
+        if (ret == AVERROR(EAGAIN))
+            ret = 0;
     } else if (!eof)
         write_packet(of, pkt, ost, 0);
 
@@ -3015,35 +2988,28 @@ static int check_init_output_file(OutputFile *of, int file_index)
 
 static int init_output_bsfs(OutputStream *ost)
 {
-    AVBSFContext *ctx;
+    AVBSFContext *ctx = ost->bsf_ctx;
     int i, ret;
 
-    if (!ost->nb_bitstream_filters)
+    if (!ctx)
         return 0;
 
-    for (i = 0; i < ost->nb_bitstream_filters; i++) {
-        ctx = ost->bsf_ctx[i];
-
-        ret = avcodec_parameters_copy(ctx->par_in,
-                                      i ? ost->bsf_ctx[i - 1]->par_out : ost->st->codecpar);
-        if (ret < 0)
-            return ret;
+    ret = avcodec_parameters_copy(ctx->par_in, ost->st->codecpar);
+    if (ret < 0)
+        return ret;
 
-        ctx->time_base_in = i ? ost->bsf_ctx[i - 1]->time_base_out : ost->st->time_base;
+    ctx->time_base_in = ost->st->time_base;
 
-        ret = av_bsf_init(ctx);
-        if (ret < 0) {
-            av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
-                   ost->bsf_ctx[i]->filter->name);
-            return ret;
-        }
+    ret = av_bsf_init(ctx);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Error initializing bitstream filter: %s\n",
+               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;
-
     ost->st->time_base = ctx->time_base_out;
 
     return 0;
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index fbaae15377..f2e30300c1 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -459,8 +459,7 @@ typedef struct OutputStream {
     AVRational mux_timebase;
     AVRational enc_timebase;
 
-    int                    nb_bitstream_filters;
-    AVBSFContext            **bsf_ctx;
+    AVBSFContext            *bsf_ctx;
 
     AVCodecContext *enc_ctx;
     AVCodecParameters *ref_par; /* associated input codec parameters with encoders options applied */
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 680f0f1dfb..b52aa28626 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -1416,6 +1416,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
 {
     OutputStream *ost;
     AVStream *st = avformat_new_stream(oc, NULL);
+    AVBSFList *bsf_list = NULL;
     int idx      = oc->nb_streams - 1, ret = 0;
     const char *bsfs = NULL, *time_base = NULL;
     char *next, *codec_tag = NULL;
@@ -1538,6 +1539,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
     while (bsfs && *bsfs) {
         const AVBitStreamFilter *filter;
         char *bsf, *bsf_options_str, *bsf_name;
+        AVBSFContext *bsf_ctx;
 
         bsf = av_get_token(&bsfs, ",");
         if (!bsf)
@@ -1552,38 +1554,45 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
             exit_program(1);
         }
 
-        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]);
+        ret = av_bsf_alloc(filter, &bsf_ctx);
         if (ret < 0) {
             av_log(NULL, AV_LOG_ERROR, "Error allocating a bitstream filter context\n");
             exit_program(1);
         }
 
-        ost->nb_bitstream_filters++;
-
         if (bsf_options_str && filter->priv_class) {
-            const AVOption *opt = av_opt_next(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, NULL);
+            const AVOption *opt = av_opt_next(bsf_ctx->priv_data, NULL);
             const char * shorthand[2] = {NULL};
 
             if (opt)
                 shorthand[0] = opt->name;
 
-            ret = av_opt_set_from_string(ost->bsf_ctx[ost->nb_bitstream_filters-1]->priv_data, bsf_options_str, shorthand, "=", ":");
+            ret = av_opt_set_from_string(bsf_ctx->priv_data, bsf_options_str, shorthand, "=", ":");
             if (ret < 0) {
                 av_log(NULL, AV_LOG_ERROR, "Error parsing options for bitstream filter %s\n", bsf_name);
                 exit_program(1);
             }
         }
+
+        if (!bsf_list)
+            bsf_list = av_bsf_list_alloc();
+        if (!bsf_list || av_bsf_list_append(bsf_list, bsf_ctx) < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Failed to allocate or append to bsf list\n");
+            exit_program(1);
+        }
+
         av_freep(&bsf);
 
         if (*bsfs)
             bsfs++;
     }
+    if (bsf_list) {
+        ret = av_bsf_list_finalize(&bsf_list, &ost->bsf_ctx);
+        if (ret < 0) {
+            av_log(NULL, AV_LOG_ERROR, "Failed to finalize bsf list\n");
+            exit_program(1);
+        }
+    }
 
     MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);
     if (codec_tag) {
-- 
2.16.4



More information about the ffmpeg-devel mailing list