The equivalents of those fields are already present in many filters, so
this will allow removing some duplication.
It can also be potentially interesting to the user programs.
---
 doc/APIchanges         |    4 ++++
 libavfilter/avfilter.c |   30 +++++++++++++++++++++++++++++-
 libavfilter/avfilter.h |   41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index fe1e1b3..fa527c6 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,10 @@ libavutil:     2012-10-22
 
 API changes, most recent first:
 
+2013-xx-xx - lavfi 3.9.0
+  Add AVFilterContext: nb_{frames,samples}_{in,out}, tracking the number of
+  frames/samples passing through the filter.
+
 2013-05-xx - xxxxxxx - lavu 52.11.0 - pixdesc.h
   Replace PIX_FMT_* flags with AV_PIX_FMT_FLAG_*.
 
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 47e7370..55eb77a 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -478,6 +478,10 @@ void avfilter_free(AVFilterContext *filter)
     av_freep(&filter->inputs);
     av_freep(&filter->outputs);
     av_freep(&filter->priv);
+    av_freep(&filter->nb_frames_in);
+    av_freep(&filter->nb_frames_out);
+    av_freep(&filter->nb_samples_in);
+    av_freep(&filter->nb_samples_out);
     av_free(filter);
 }
 
@@ -538,6 +542,19 @@ int avfilter_init_dict(AVFilterContext *ctx, AVDictionary 
**options)
     else if (ctx->filter->init_dict)
         ret = ctx->filter->init_dict(ctx, options);
 
+    if (ctx->nb_inputs) {
+        ctx->nb_frames_in   = av_mallocz(sizeof(*ctx->nb_frames_in)   * 
ctx->nb_inputs);
+        ctx->nb_samples_in  = av_mallocz(sizeof(*ctx->nb_samples_in)  * 
ctx->nb_inputs);
+        if (!ctx->nb_frames_in || !ctx->nb_samples_in)
+            return AVERROR(ENOMEM);
+    }
+    if (ctx->nb_outputs) {
+        ctx->nb_frames_out  = av_mallocz(sizeof(*ctx->nb_frames_out)  * 
ctx->nb_outputs);
+        ctx->nb_samples_out = av_mallocz(sizeof(*ctx->nb_samples_out) * 
ctx->nb_outputs);
+        if (!ctx->nb_frames_out || !ctx->nb_samples_out)
+            return AVERROR(ENOMEM);
+    }
+
     return ret;
 }
 
@@ -678,10 +695,15 @@ int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
     int (*filter_frame)(AVFilterLink *, AVFrame *);
     AVFilterPad *dst = link->dstpad;
     AVFrame *out;
+    int idx, ret, nb_samples = frame->nb_samples;
 
     FF_DPRINTF_START(NULL, filter_frame);
     ff_dlog_link(NULL, link, 1);
 
+    idx = link->srcpad - link->src->output_pads;
+    link->src->nb_frames_out[idx]++;
+    link->src->nb_samples_out[idx] += nb_samples;
+
     if (!(filter_frame = dst->filter_frame))
         filter_frame = default_filter_frame;
 
@@ -723,7 +745,13 @@ int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
     } else
         out = frame;
 
-    return filter_frame(link, out);
+    ret = filter_frame(link, out);
+
+    idx = link->dstpad - link->dst->input_pads;
+    link->dst->nb_frames_in[idx]++;
+    link->dst->nb_samples_in[idx] += nb_samples;
+
+    return ret;
 }
 
 const AVClass *avfilter_get_class(void)
diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
index 6ab31a0..0cf6229 100644
--- a/libavfilter/avfilter.h
+++ b/libavfilter/avfilter.h
@@ -481,6 +481,47 @@ struct AVFilterContext {
     void *priv;                     ///< private data for use by the filter
 
     struct AVFilterGraph *graph;    ///< filtergraph this filter belongs to
+
+    /**
+     * A nb_inputs-sized array of counters that track the number of frames that
+     * were received by this filter on each input. Set by libavfilter.
+     * This array is allocated by libavfilter after the filter is initialized.
+     *
+     * Implementation note: this value is incremented after filter_frame()
+     * callback for the corresponding input returns.
+     */
+    uint64_t *nb_frames_in;
+    /**
+     * A nb_outputs-sized array of counters that track the number of frames 
that
+     * were output by this filter on each output. Set by libavfilter.
+     * This array is allocated by libavfilter after the filter is initialized.
+     *
+     * Implementation note: this value is incremented immediately after
+     * ff_filter_frame() is called for the corresponding output.
+     */
+    uint64_t *nb_frames_out;
+    /**
+     * A nb_inputs-sized array of counters that track the number of audio
+     * samples that were received by this filter on each input. The values make
+     * sense only for audio inputs, but to simplify access the array size
+     * includes all the inputs, not just audio.  Set by libavfilter.
+     * This array is allocated by libavfilter after the filter is initialized.
+     *
+     * Implementation note: this value is incremented after filter_frame()
+     * callback for the corresponding input returns.
+     */
+    uint64_t *nb_samples_in;
+    /**
+     * A nb_outputs-sized array of counters that track the number of audio
+     * samples that were output by this filter on each output. The values make
+     * sense only for audio outputs, but to simplify access the array size
+     * includes all the outputs, not just audio.  Set by libavfilter.
+     * This array is allocated by libavfilter after the filter is initialized.
+     *
+     * Implementation note: this value is incremented immediately after
+     * ff_filter_frame() is called for the corresponding output.
+     */
+    uint64_t *nb_samples_out;
 };
 
 /**
-- 
1.7.10.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to