網頁

2020年10月16日 星期五

DeepStream performance 測量

1. 直接取得時間
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, GstPadProbeCallback, NULL, NULL);

GstPadProbeReturn *GstPadProbeCallback(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
{
    GstBuffer *buf = (GstBuffer *) info->data;
    if (GST_BUFFER_DTS_IS_VALID(buf)) {
        GstClockTime dts = GST_BUFFER_DTS(buf);
        g_print("dts=%ldms ", dts/1000000);
    }
    if (GST_BUFFER_PTS_IS_VALID(buf)) {
        GstClockTime pts = GST_BUFFER_PTS(buf);
        g_print("pts=%ldms ", pts/1000000);
    }
    if (GST_BUFFER_DURATION_IS_VALID(buf)) {
        GstClockTime duration = GST_BUFFER_DURATION(buf);
        g_print("duration=%ldms ", duration/1000000);
    }
    g_print("\n");
}

2. 使用 DeepStream 提供的 deepstream_perf.h
$ cp apps/apps-common/includes/deepstream_perf.h .
$ cp apps/apps-common/includes/deepstream_config.h .
$ cp apps/apps-common/src/deepstream_perf.c .

#include "deepstream_perf.h"

/**
 * callback function to print the performance numbers of each stream.
 */
static GMutex fps_lock;
static gdouble fps[MAX_SOURCE_BINS];
static gdouble fps_avg[MAX_SOURCE_BINS];

NvDsAppPerfStructInt perf_struct;
enable_perf_measurement (&perf_struct, osd_sink_pad,
    1, //num_sources
    5, //interval_sec,
    1, //num_surfaces_per_frame
    perf_callback);

static void perf_callback(gpointer context, NvDsAppPerfStruct * str)
{
    static guint header_print_cnt = 0;
    guint i;
    guint numf = str->num_instances;

    g_mutex_lock (&fps_lock);
    for (i = 0; i < numf; i++) {
        fps[i] = str->fps[i];
        fps_avg[i] = str->fps_avg[i];
    }

    if (header_print_cnt % 20 == 0) {
        g_print ("\n**PERF:  ");
        for (i = 0; i < numf; i++) {
            g_print ("FPS %d (Avg)\t", i);
        }
        g_print ("\n");
        header_print_cnt = 0;
    }
    header_print_cnt++;

    time_t t = time (NULL);
    struct tm *tm = localtime (&t);
    g_print ("%s", asctime (tm));
    g_print ("**PERF:  ");

    for (i = 0; i < numf; i++) {
        g_print ("%.2f (%.2f)\t", fps[i], fps_avg[i]);
    }
    g_print ("\n");
    g_mutex_unlock (&fps_lock);
}

3. 使用 fpsdisplaysink 替換原先的 sink, 可以利用 fps-measurements signal 或 last-message
//sink = gst_element_factory_make ("nveglglessink", "nvvideo-renderer");
GstElement *nvsink = gst_element_factory_make ("nveglglessink", "nvvideo-renderer");
sink = gst_element_factory_make ("fpsdisplaysink", "fps-display");
g_object_set (G_OBJECT(sink), "video-sink", nvsink, // 替換原先的 videosink
    "text-overlay", FALSE, // TRUE 時, 會自動加入 textoverlay
    "signal-fps-measurements", TRUE, // 產生 fps-measurements signal
    "fps-update-interval", 1 * 1000,
    "sync", FALSE,
    NULL);
g_signal_connect (sink, "fps-measurements", G_CALLBACK (fps_measurements_callback), NULL);
gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, GstPadProbeCallback, (gpointer)sink, NULL);

static void fps_measurements_callback(GstElement  fpsdisplaysink,
        gdouble fps, gdouble droprate, gdouble avgfps, gpointer udata) 
{
    g_print("fps=%.1f droprate=%.2f avgfps=%.1f\n", fps, droprate, avgfps);
}

GstPadProbeReturn *GstPadProbeCallback(GstPad *pad, GstPadProbeInfo *info, gpointer sink)
{
    gchar *last_message;
    g_object_get(G_OBJECT(sink), "last-message", &last_message, NULL);
    g_print("Fps info: %s\n", last_message);
}

沒有留言:

張貼留言