[FFmpeg-devel] [PATCH 8/9] avcodec/bsf: Avoid allocation for AVBSFInternal

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Thu Aug 5 08:42:43 EEST 2021


Do this by allocating AVBSFContext together with the data that is
currently in AVBSFInternal; or rather: Put AVBSFContext at the beginning
of a new structure called FFBSFContext (which encompasses more than just
the internal fields and is a proper context in its own right, hence the
name) and remove the AVBSFInternal altogether.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at outlook.com>
---
This patch is a new version of my old patch [1], redone according to
what was preferred back then (namely putting the public context inside
the internal context instead of putting both contexts in one structure).

Needless to say, this patch breaks ABI.

[1]: https://patchwork.ffmpeg.org/project/ffmpeg/patch/20200810135522.5972-1-andreas.rheinhardt@gmail.com/

 libavcodec/bsf.c | 45 +++++++++++++++++++--------------------------
 libavcodec/bsf.h |  8 --------
 2 files changed, 19 insertions(+), 34 deletions(-)

diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c
index 0305244f8d..0f56655f78 100644
--- a/libavcodec/bsf.c
+++ b/libavcodec/bsf.c
@@ -32,29 +32,30 @@
 
 #define IS_EMPTY(pkt) (!(pkt)->data && !(pkt)->side_data_elems)
 
-struct AVBSFInternal {
+typedef struct FFBSFContext {
+    AVBSFContext public;
     AVPacket *buffer_pkt;
     int eof;
-};
+} FFBSFContext;
 
 void av_bsf_free(AVBSFContext **pctx)
 {
     AVBSFContext *ctx;
+    FFBSFContext *bsfi;
 
     if (!pctx || !*pctx)
         return;
-    ctx = *pctx;
+    ctx  = *pctx;
+    bsfi = (FFBSFContext*)ctx;
 
-    if (ctx->internal) {
+    if (ctx->priv_data) {
         if (ctx->filter->close)
             ctx->filter->close(ctx);
-        av_packet_free(&ctx->internal->buffer_pkt);
-        av_freep(&ctx->internal);
+        if (ctx->filter->priv_class)
+            av_opt_free(ctx->priv_data);
+        av_freep(&ctx->priv_data);
     }
-    if (ctx->filter->priv_class && ctx->priv_data)
-        av_opt_free(ctx->priv_data);
-
-    av_freep(&ctx->priv_data);
+    av_packet_free(&bsfi->buffer_pkt);
 
     avcodec_parameters_free(&ctx->par_in);
     avcodec_parameters_free(&ctx->par_out);
@@ -92,12 +93,13 @@ const AVClass *av_bsf_get_class(void)
 int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
 {
     AVBSFContext *ctx;
-    AVBSFInternal *bsfi;
+    FFBSFContext *bsfi;
     int ret;
 
-    ctx = av_mallocz(sizeof(*ctx));
-    if (!ctx)
+    bsfi = av_mallocz(sizeof(*bsfi));
+    if (!bsfi)
         return AVERROR(ENOMEM);
+    ctx  = &bsfi->public;
 
     ctx->av_class = &bsf_class;
     ctx->filter   = filter;
@@ -120,15 +122,6 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx)
             av_opt_set_defaults(ctx->priv_data);
         }
     }
-    /* Allocate AVBSFInternal; must happen after priv_data has been allocated
-     * so that a filter->close needing priv_data is never called without. */
-    bsfi = av_mallocz(sizeof(*bsfi));
-    if (!bsfi) {
-        ret = AVERROR(ENOMEM);
-        goto fail;
-    }
-    ctx->internal = bsfi;
-
     bsfi->buffer_pkt = av_packet_alloc();
     if (!bsfi->buffer_pkt) {
         ret = AVERROR(ENOMEM);
@@ -185,7 +178,7 @@ int av_bsf_init(AVBSFContext *ctx)
 
 void av_bsf_flush(AVBSFContext *ctx)
 {
-    AVBSFInternal *bsfi = ctx->internal;
+    FFBSFContext *const bsfi = (FFBSFContext*)ctx;
 
     bsfi->eof = 0;
 
@@ -197,7 +190,7 @@ void av_bsf_flush(AVBSFContext *ctx)
 
 int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
 {
-    AVBSFInternal *bsfi = ctx->internal;
+    FFBSFContext *const bsfi = (FFBSFContext*)ctx;
     int ret;
 
     if (!pkt || IS_EMPTY(pkt)) {
@@ -228,7 +221,7 @@ int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
 
 int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
 {
-    AVBSFInternal *bsfi = ctx->internal;
+    FFBSFContext *const bsfi = (FFBSFContext*)ctx;
     AVPacket *tmp_pkt;
 
     if (bsfi->eof)
@@ -249,7 +242,7 @@ int ff_bsf_get_packet(AVBSFContext *ctx, AVPacket **pkt)
 
 int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt)
 {
-    AVBSFInternal *bsfi = ctx->internal;
+    FFBSFContext *const bsfi = (FFBSFContext*)ctx;
 
     if (bsfi->eof)
         return AVERROR_EOF;
diff --git a/libavcodec/bsf.h b/libavcodec/bsf.h
index 3b5faa85cb..8c5355d186 100644
--- a/libavcodec/bsf.h
+++ b/libavcodec/bsf.h
@@ -34,8 +34,6 @@
  * @{
  */
 
-typedef struct AVBSFInternal AVBSFInternal;
-
 /**
  * The bitstream filter state.
  *
@@ -57,12 +55,6 @@ typedef struct AVBSFContext {
      */
     const struct AVBitStreamFilter *filter;
 
-    /**
-     * Opaque libavcodec internal data. Must not be touched by the caller in any
-     * way.
-     */
-    AVBSFInternal *internal;
-
     /**
      * Opaque filter-specific private data. If filter->priv_class is non-NULL,
      * this is an AVOptions-enabled struct.
-- 
2.30.2



More information about the ffmpeg-devel mailing list