[FFmpeg-cvslog] avfilter/f_graphmonitor: add several more flags

Paul B Mahol git at videolan.org
Fri Mar 4 15:06:53 EET 2022


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Fri Mar  4 13:01:26 2022 +0100| [aede8424fed7964d4056a6d1380b4dcac685ac38] | committer: Paul B Mahol

avfilter/f_graphmonitor: add several more flags

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=aede8424fed7964d4056a6d1380b4dcac685ac38
---

 doc/filters.texi             |  12 +++++
 libavfilter/f_graphmonitor.c | 102 +++++++++++++++++++++++++++++++++++++++----
 2 files changed, 105 insertions(+), 9 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 59f9dab2ea..15d9d0fd8d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -13432,12 +13432,21 @@ Display number of frames taken from filter.
 @item frame_count_out
 Display number of frames given out from filter.
 
+ at item frame_count_delta
+Display delta number of frames between above two values.
+
 @item pts
 Display current filtered frame pts.
 
+ at item pts_delta
+Display pts delta between current and previous frame.
+
 @item time
 Display current filtered frame time.
 
+ at item time_delta
+Display time delta between current and previous frame.
+
 @item timebase
 Display time base for filter link.
 
@@ -13458,6 +13467,9 @@ Display number of samples taken from filter.
 
 @item sample_count_out
 Display number of samples given out from filter.
+
+ at item sample_count_delta
+Display delta number of samples between above two values.
 @end table
 
 @item rate, r
diff --git a/libavfilter/f_graphmonitor.c b/libavfilter/f_graphmonitor.c
index 51d0a568e3..9cc5ea940e 100644
--- a/libavfilter/f_graphmonitor.c
+++ b/libavfilter/f_graphmonitor.c
@@ -32,6 +32,10 @@
 #include "internal.h"
 #include "video.h"
 
+typedef struct CacheItem {
+    int64_t previous_pts_us;
+} CacheItem;
+
 typedef struct GraphMonitorContext {
     const AVClass *class;
 
@@ -49,6 +53,10 @@ typedef struct GraphMonitorContext {
     uint8_t green[4];
     uint8_t blue[4];
     uint8_t bg[4];
+
+    CacheItem *cache;
+    unsigned int cache_size;
+    unsigned int cache_index;
 } GraphMonitorContext;
 
 enum {
@@ -64,6 +72,10 @@ enum {
     MODE_EOF   = 1 << 9,
     MODE_SCIN  = 1 << 10,
     MODE_SCOUT = 1 << 11,
+    MODE_PTS_DELTA = 1 << 12,
+    MODE_TIME_DELTA = 1 << 13,
+    MODE_FC_DELTA = 1 << 14,
+    MODE_SC_DELTA = 1 << 15,
 };
 
 #define OFFSET(x) offsetof(GraphMonitorContext, x)
@@ -83,8 +95,11 @@ static const AVOption graphmonitor_options[] = {
         { "queue",            NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_QUEUE},   0, 0, VF, "flags" },
         { "frame_count_in",   NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_FCOUT},   0, 0, VF, "flags" },
         { "frame_count_out",  NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_FCIN},    0, 0, VF, "flags" },
+        { "frame_count_delta",NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_FC_DELTA},0, 0, VF, "flags" },
         { "pts",              NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_PTS},     0, 0, VF, "flags" },
+        { "pts_delta",        NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_PTS_DELTA},0,0, VF, "flags" },
         { "time",             NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_TIME},    0, 0, VF, "flags" },
+        { "time_delta",       NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_TIME_DELTA},0,0,VF, "flags" },
         { "timebase",         NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_TB},      0, 0, VF, "flags" },
         { "format",           NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_FMT},     0, 0, VF, "flags" },
         { "size",             NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_SIZE},    0, 0, VF, "flags" },
@@ -92,11 +107,24 @@ static const AVOption graphmonitor_options[] = {
         { "eof",              NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_EOF},     0, 0, VF, "flags" },
         { "sample_count_in",  NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_SCOUT},   0, 0, VF, "flags" },
         { "sample_count_out", NULL, 0, AV_OPT_TYPE_CONST, {.i64=MODE_SCIN},    0, 0, VF, "flags" },
+        { "sample_count_delta",NULL,0, AV_OPT_TYPE_CONST, {.i64=MODE_SC_DELTA},0, 0, VF, "flags" },
     { "rate", "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, VF },
     { "r",    "set video rate", OFFSET(frame_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT_MAX, VF },
     { NULL }
 };
 
+static av_cold int init(AVFilterContext *ctx)
+{
+    GraphMonitorContext *s = ctx->priv;
+
+    s->cache = av_fast_realloc(NULL, &s->cache_size,
+                               8192 * sizeof(*(s->cache)));
+    if (!s->cache)
+        return AVERROR(ENOMEM);
+
+    return 0;
+}
+
 static int query_formats(AVFilterContext *ctx)
 {
     AVFilterLink *outlink = ctx->outputs[0];
@@ -173,12 +201,14 @@ static int filter_have_queued(AVFilterContext *filter)
     return 0;
 }
 
-static void draw_items(AVFilterContext *ctx, AVFrame *out,
-                       int xpos, int ypos,
-                       AVFilterLink *l,
-                       size_t frames)
+static int draw_items(AVFilterContext *ctx, AVFrame *out,
+                      int xpos, int ypos,
+                      AVFilterLink *l,
+                      size_t frames)
 {
     GraphMonitorContext *s = ctx->priv;
+    int64_t previous_pts_us = s->cache[s->cache_index].previous_pts_us;
+    int64_t current_pts_us = l->current_pts_us;
     char buffer[1024] = { 0 };
 
     if (s->flags & MODE_FMT) {
@@ -233,6 +263,11 @@ static void draw_items(AVFilterContext *ctx, AVFrame *out,
         drawtext(out, xpos, ypos, buffer, s->white);
         xpos += strlen(buffer) * 8;
     }
+    if (s->flags & MODE_FC_DELTA) {
+        snprintf(buffer, sizeof(buffer)-1, " | delta: %"PRId64, l->frame_count_in - l->frame_count_out);
+        drawtext(out, xpos, ypos, buffer, s->white);
+        xpos += strlen(buffer) * 8;
+    }
     if (s->flags & MODE_SCIN) {
         snprintf(buffer, sizeof(buffer)-1, " | sin: %"PRId64, l->sample_count_in);
         drawtext(out, xpos, ypos, buffer, s->white);
@@ -243,13 +278,28 @@ static void draw_items(AVFilterContext *ctx, AVFrame *out,
         drawtext(out, xpos, ypos, buffer, s->white);
         xpos += strlen(buffer) * 8;
     }
+    if (s->flags & MODE_SC_DELTA) {
+        snprintf(buffer, sizeof(buffer)-1, " | sdelta: %"PRId64, l->sample_count_in - l->sample_count_out);
+        drawtext(out, xpos, ypos, buffer, s->white);
+        xpos += strlen(buffer) * 8;
+    }
     if (s->flags & MODE_PTS) {
-        snprintf(buffer, sizeof(buffer)-1, " | pts: %s", av_ts2str(l->current_pts_us));
+        snprintf(buffer, sizeof(buffer)-1, " | pts: %s", av_ts2str(current_pts_us));
+        drawtext(out, xpos, ypos, buffer, s->white);
+        xpos += strlen(buffer) * 8;
+    }
+    if (s->flags & MODE_PTS_DELTA) {
+        snprintf(buffer, sizeof(buffer)-1, " | pts_delta: %s", av_ts2str(current_pts_us - previous_pts_us));
         drawtext(out, xpos, ypos, buffer, s->white);
         xpos += strlen(buffer) * 8;
     }
     if (s->flags & MODE_TIME) {
-        snprintf(buffer, sizeof(buffer)-1, " | time: %s", av_ts2timestr(l->current_pts_us, &AV_TIME_BASE_Q));
+        snprintf(buffer, sizeof(buffer)-1, " | time: %s", av_ts2timestr(current_pts_us, &AV_TIME_BASE_Q));
+        drawtext(out, xpos, ypos, buffer, s->white);
+        xpos += strlen(buffer) * 8;
+    }
+    if (s->flags & MODE_TIME_DELTA) {
+        snprintf(buffer, sizeof(buffer)-1, " | time_delta: %s", av_ts2timestr(current_pts_us - previous_pts_us, &AV_TIME_BASE_Q));
         drawtext(out, xpos, ypos, buffer, s->white);
         xpos += strlen(buffer) * 8;
     }
@@ -258,6 +308,19 @@ static void draw_items(AVFilterContext *ctx, AVFrame *out,
         drawtext(out, xpos, ypos, buffer, s->blue);
         xpos += strlen(buffer) * 8;
     }
+
+    s->cache[s->cache_index].previous_pts_us = l->current_pts_us;
+
+    if (s->cache_index + 1 >= s->cache_size / sizeof(*(s->cache))) {
+        void *ptr = av_fast_realloc(s->cache, &s->cache_size, s->cache_size * 2);
+
+        if (!ptr)
+            return AVERROR(ENOMEM);
+        s->cache = ptr;
+    }
+    s->cache_index++;
+
+    return 0;
 }
 
 static int create_frame(AVFilterContext *ctx, int64_t pts)
@@ -265,7 +328,7 @@ static int create_frame(AVFilterContext *ctx, int64_t pts)
     GraphMonitorContext *s = ctx->priv;
     AVFilterLink *outlink = ctx->outputs[0];
     AVFrame *out;
-    int xpos, ypos = 0;
+    int ret, xpos, ypos = 0;
 
     out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
     if (!out)
@@ -273,6 +336,8 @@ static int create_frame(AVFilterContext *ctx, int64_t pts)
 
     clear_image(s, out, outlink);
 
+    s->cache_index = 0;
+
     for (int i = 0; i < ctx->graph->nb_filters; i++) {
         AVFilterContext *filter = ctx->graph->filters[i];
         char buffer[1024] = { 0 };
@@ -298,7 +363,9 @@ static int create_frame(AVFilterContext *ctx, int64_t pts)
             xpos += strlen(buffer) * 8;
             drawtext(out, xpos, ypos, l->src->name, s->white);
             xpos += strlen(l->src->name) * 8 + 10;
-            draw_items(ctx, out, xpos, ypos, l, frames);
+            ret = draw_items(ctx, out, xpos, ypos, l, frames);
+            if (ret < 0)
+                goto error;
             ypos += 10;
         }
 
@@ -316,7 +383,9 @@ static int create_frame(AVFilterContext *ctx, int64_t pts)
             xpos += strlen(buffer) * 8;
             drawtext(out, xpos, ypos, l->dst->name, s->white);
             xpos += strlen(l->dst->name) * 8 + 10;
-            draw_items(ctx, out, xpos, ypos, l, frames);
+            ret = draw_items(ctx, out, xpos, ypos, l, frames);
+            if (ret < 0)
+                goto error;
             ypos += 10;
         }
         ypos += 5;
@@ -325,6 +394,9 @@ static int create_frame(AVFilterContext *ctx, int64_t pts)
     out->pts = pts;
     s->pts = pts + 1;
     return ff_filter_frame(outlink, out);
+error:
+    av_frame_free(&out);
+    return ret;
 }
 
 static int activate(AVFilterContext *ctx)
@@ -386,6 +458,14 @@ static int config_output(AVFilterLink *outlink)
     return 0;
 }
 
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    GraphMonitorContext *s = ctx->priv;
+
+    av_freep(&s->cache);
+    s->cache_size = s->cache_index = 0;
+}
+
 AVFILTER_DEFINE_CLASS_EXT(graphmonitor, "(a)graphmonitor", graphmonitor_options);
 
 #if CONFIG_GRAPHMONITOR_FILTER
@@ -410,6 +490,8 @@ const AVFilter ff_vf_graphmonitor = {
     .description   = NULL_IF_CONFIG_SMALL("Show various filtergraph stats."),
     .priv_size     = sizeof(GraphMonitorContext),
     .priv_class    = &graphmonitor_class,
+    .init          = init,
+    .uninit        = uninit,
     .activate      = activate,
     FILTER_INPUTS(graphmonitor_inputs),
     FILTER_OUTPUTS(graphmonitor_outputs),
@@ -440,6 +522,8 @@ const AVFilter ff_avf_agraphmonitor = {
     .description   = NULL_IF_CONFIG_SMALL("Show various filtergraph stats."),
     .priv_class    = &graphmonitor_class,
     .priv_size     = sizeof(GraphMonitorContext),
+    .init          = init,
+    .uninit        = uninit,
     .activate      = activate,
     FILTER_INPUTS(agraphmonitor_inputs),
     FILTER_OUTPUTS(agraphmonitor_outputs),



More information about the ffmpeg-cvslog mailing list