[FFmpeg-devel] [PATCH 2/2] avcodec/bsf: add av_bsf_join() to chain bitstream filters

Marton Balint cus at passwd.hu
Thu Apr 9 01:42:31 EEST 2020


Signed-off-by: Marton Balint <cus at passwd.hu>
---
 doc/APIchanges       |  3 +++
 libavcodec/avcodec.h | 19 ++++++++++++++++
 libavcodec/bsf.c     | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/version.h |  2 +-
 4 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index f1d7eac2ee..1473742139 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,9 @@ libavutil:     2017-10-21
 
 API changes, most recent first:
 
+2020-04-xx - xxxxxxxxxx - lavc 58.77.102 - avcodec.h
+  Add av_bsf_join() to chain bitstream filters.
+
 2020-03-29 - xxxxxxxxxx - lavf 58.42.100 - avformat.h
   av_read_frame() now guarantees to handle uninitialized input packets
   and to return refcounted packets on success.
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 8fc0ad92c9..2812055e8a 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -6056,6 +6056,25 @@ int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt);
  */
 void av_bsf_flush(AVBSFContext *ctx);
 
+/**
+ * Join a new bitstream filter to an already operating one.
+ *
+ * @param[in,out] out_bsf *out_bsf contains the existing, already initialized bitstream
+ *                        filter, the new filter will be joined to the output of this.
+ *                        It can be NULL, in which case an empty filter is assumed.
+ *                        Upon successful return *out_bsf will contain the new, combined
+ *                        bitstream filter which will be initialized.
+ * @param[in]     bsf     the bitstream filter to be joined to the output of *out_bsf.
+ *                        This filter must be uninitialized but it must be ready to be
+ *                        initalized, so input codec parameters and time base must be
+ *                        set if *out_bsf is NULL, otherwise the function will set these
+ *                        automatically based on the output parameters of *out_bsf.
+ *                        Upon successful return the bsf will be initialized.
+ *
+ * @return 0 on success, negative on error.
+ */
+int av_bsf_join(AVBSFContext **out_bsf, AVBSFContext *bsf);
+
 /**
  * Free a bitstream filter context and everything associated with it; write NULL
  * into the supplied pointer.
diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c
index b9fc771a88..1bca28d1ae 100644
--- a/libavcodec/bsf.c
+++ b/libavcodec/bsf.c
@@ -487,6 +487,68 @@ end:
     return ret;
 }
 
+int av_bsf_join(AVBSFContext **out_bsf, AVBSFContext *bsf)
+{
+    BSFListContext *lst;
+    AVBSFContext *obsf = *out_bsf;
+    AVBSFContext *new_list_bsf = NULL;
+    int ret;
+
+    if (!obsf) {
+        ret = av_bsf_init(bsf);
+        if (ret < 0)
+            return ret;
+        *out_bsf = bsf;
+        return 0;
+    }
+
+    if (obsf->filter != &ff_list_bsf) {
+        ret = av_bsf_alloc(&ff_list_bsf, &new_list_bsf);
+        if (ret < 0)
+            return ret;
+        lst = new_list_bsf->priv_data;
+        ret = av_dynarray_add_nofree(&lst->bsfs, &lst->nb_bsfs, obsf);
+        if (ret < 0)
+            goto fail;
+        ret = avcodec_parameters_copy(new_list_bsf->par_in, obsf->par_in);
+        if (ret < 0)
+            goto fail;
+        new_list_bsf->time_base_in = obsf->time_base_in;
+        obsf = new_list_bsf;
+    } else {
+        lst = obsf->priv_data;
+    }
+
+    ret = avcodec_parameters_copy(bsf->par_in, lst->bsfs[lst->nb_bsfs-1]->par_out);
+    if (ret < 0)
+        goto fail;
+    bsf->time_base_in = lst->bsfs[lst->nb_bsfs-1]->time_base_out;
+
+    ret = av_bsf_init(&bsf);
+    if (ret < 0)
+        goto fail;
+
+    ret = avcodec_parameters_copy(obsf->par_out, bsf->par_out);
+    if (ret < 0)
+        goto fail;
+    obsf->time_base_out = bsf->time_base_out;
+
+    ret = av_dynarray_add_nofree(&lst->bsfs, &lst->nb_bsfs, bsf);
+    if (ret < 0)
+        goto fail;
+
+    *out_bsf = obsf;
+    return 0;
+
+fail:
+    if (new_list_bsf) {
+        if (lst->nb_bsfs)
+            lst->bsfs[0] = NULL;
+        av_bsf_free(&new_list_bsf);
+    }
+    return ret;
+}
+
 static int bsf_parse_single(const char *str, AVBSFList *bsf_lst)
 {
     char *bsf_name, *bsf_options_str, *buf;
diff --git a/libavcodec/version.h b/libavcodec/version.h
index f4d1d4de21..dadca75430 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 
 #define LIBAVCODEC_VERSION_MAJOR  58
 #define LIBAVCODEC_VERSION_MINOR  77
-#define LIBAVCODEC_VERSION_MICRO 101
+#define LIBAVCODEC_VERSION_MICRO 102
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
-- 
2.16.4



More information about the ffmpeg-devel mailing list