[FFmpeg-devel] [PATCH 2/5] avfilter/vf_addroi: realloc the buf and append new ROI

lance.lmwang at gmail.com lance.lmwang at gmail.com
Thu Sep 30 04:13:57 EEST 2021


From: Limin Wang <lance.lmwang at gmail.com>

It is simpler and more efficient compared to the current code.

Signed-off-by: Limin Wang <lance.lmwang at gmail.com>
---
 libavfilter/vf_addroi.c | 98 +++++++++++++++++++------------------------------
 1 file changed, 37 insertions(+), 61 deletions(-)

diff --git a/libavfilter/vf_addroi.c b/libavfilter/vf_addroi.c
index 5f9ec21..f521a96 100644
--- a/libavfilter/vf_addroi.c
+++ b/libavfilter/vf_addroi.c
@@ -91,14 +91,40 @@ static int addroi_config_input(AVFilterLink *inlink)
     return 0;
 }
 
+static int addroi_append_roi(AVBufferRef **pbuf, AVRegionOfInterest *region)
+{
+    AVBufferRef *buf = *pbuf;
+    uint32_t old_size = buf ? buf->size : 0;
+    int ret;
+    AVRegionOfInterest *roi;
+
+    ret = av_buffer_realloc(pbuf, old_size + sizeof(*region));
+    if (ret < 0)
+        return ret;
+    buf = *pbuf;
+
+    roi = (AVRegionOfInterest *)(buf->data + old_size);
+    memcpy(roi, region, sizeof(*region));
+
+    return 0;
+}
+
 static int addroi_filter_frame(AVFilterLink *inlink, AVFrame *frame)
 {
     AVFilterContext *avctx = inlink->dst;
     AVFilterLink  *outlink = avctx->outputs[0];
     AddROIContext     *ctx = avctx->priv;
-    AVRegionOfInterest *roi;
+    AVRegionOfInterest region = (AVRegionOfInterest) {
+        .self_size = sizeof(AVRegionOfInterest),
+        .top       = ctx->region[Y],
+        .bottom    = ctx->region[Y] + ctx->region[H],
+        .left      = ctx->region[X],
+        .right     = ctx->region[X] + ctx->region[W],
+        .qoffset   = ctx->qoffset,
+    };
     AVFrameSideData *sd;
     int err;
+    AVBufferRef *buf = NULL;
 
     if (ctx->clear) {
         av_frame_remove_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
@@ -107,73 +133,23 @@ static int addroi_filter_frame(AVFilterLink *inlink, AVFrame *frame)
         sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
     }
     if (sd) {
-        const AVRegionOfInterest *old_roi;
-        uint32_t old_roi_size;
-        AVBufferRef *roi_ref;
-        int nb_roi, i;
-
-        old_roi = (const AVRegionOfInterest*)sd->data;
-        old_roi_size = old_roi->self_size;
-        av_assert0(old_roi_size && sd->size % old_roi_size == 0);
-        nb_roi = sd->size / old_roi_size + 1;
-
-        roi_ref = av_buffer_alloc(sizeof(*roi) * nb_roi);
-        if (!roi_ref) {
-            err = AVERROR(ENOMEM);
+        buf = sd->buf;
+        err = addroi_append_roi(&buf, &region);
+        if (err < 0)
             goto fail;
-        }
-        roi = (AVRegionOfInterest*)roi_ref->data;
-
-        for (i = 0; i < nb_roi - 1; i++) {
-            old_roi = (const AVRegionOfInterest*)
-                (sd->data + old_roi_size * i);
-
-            roi[i] = (AVRegionOfInterest) {
-                .self_size = sizeof(*roi),
-                .top       = old_roi->top,
-                .bottom    = old_roi->bottom,
-                .left      = old_roi->left,
-                .right     = old_roi->right,
-                .qoffset   = old_roi->qoffset,
-            };
-        }
-
-        roi[nb_roi - 1] = (AVRegionOfInterest) {
-            .self_size = sizeof(*roi),
-            .top       = ctx->region[Y],
-            .bottom    = ctx->region[Y] + ctx->region[H],
-            .left      = ctx->region[X],
-            .right     = ctx->region[X] + ctx->region[W],
-            .qoffset   = ctx->qoffset,
-        };
-
-        av_frame_remove_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
-
-        sd = av_frame_new_side_data_from_buf(frame,
-                                             AV_FRAME_DATA_REGIONS_OF_INTEREST,
-                                             roi_ref);
-        if (!sd) {
-            av_buffer_unref(&roi_ref);
-            err = AVERROR(ENOMEM);
-            goto fail;
-        }
 
+        sd->data = buf->data;
+        sd->size = buf->size;
     } else {
-        sd = av_frame_new_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST,
-                                    sizeof(AVRegionOfInterest));
+        err = addroi_append_roi(&buf, &region);
+        if (err < 0)
+            goto fail;
+        sd = av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST, buf);
         if (!sd) {
+            av_buffer_unref(&buf);
             err = AVERROR(ENOMEM);
             goto fail;
         }
-        roi = (AVRegionOfInterest*)sd->data;
-        *roi = (AVRegionOfInterest) {
-            .self_size = sizeof(*roi),
-            .top       = ctx->region[Y],
-            .bottom    = ctx->region[Y] + ctx->region[H],
-            .left      = ctx->region[X],
-            .right     = ctx->region[X] + ctx->region[W],
-            .qoffset   = ctx->qoffset,
-        };
     }
 
     return ff_filter_frame(outlink, frame);
-- 
1.8.3.1



More information about the ffmpeg-devel mailing list