You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GStreamer运行时获取srtserversink的stats属性并打印

获取GStreamer srtserversink运行时统计数据的实现方案

核心思路

srtserversink的stats属性是GstValueArray类型,内部存储多个GstStructure结构(每个结构对应一个客户端连接的统计数据)。要在管道运行时持续获取并打印这些数据,需要:

  1. 编写统计读取回调函数,解析GstValueArray和GstStructure
  2. 使用Glib定时器周期性触发回调,避免阻塞主循环

修正后的完整代码

#include <glib.h>
#include <gst/gst.h>

// 统计数据打印回调函数
static gboolean print_srt_stats(gpointer user_data) {
    GstElement *sink = GST_ELEMENT(user_data);
    GValueArray *stats_array = NULL;

    // 获取stats属性
    g_object_get(G_OBJECT(sink), "stats", &stats_array, NULL);

    if (stats_array && stats_array->n_values > 0) {
        g_print("\n=== SRT Server Sink Statistics ===\n");
        // 遍历每个客户端连接的统计结构
        for (guint i = 0; i < stats_array->n_values; i++) {
            GValue *val = g_value_array_get_nth(stats_array, i);
            if (GST_VALUE_HOLDS_STRUCTURE(val)) {
                GstStructure *stats_struct = gst_value_get_structure(val);
                // 打印完整统计结构(也可按需提取特定字段)
                g_print("Connection %u:\n%s\n", i, gst_structure_to_string(stats_struct));
                
                // 示例:提取特定字段(如发送字节、丢包数)
                guint64 bytes_sent;
                guint32 pkt_lost;
                if (gst_structure_get_uint64(stats_struct, "bytes-sent", &bytes_sent)) {
                    g_print("Bytes Sent: %" G_GUINT64_FORMAT " bytes\n", bytes_sent);
                }
                if (gst_structure_get_uint32(stats_struct, "pkt-lost", &pkt_lost)) {
                    g_print("Packets Lost: %u\n", pkt_lost);
                }
            }
        }
        g_print("===================================\n");
    }

    // 释放资源
    if (stats_array) {
        g_value_array_unref(stats_array);
    }

    // 返回TRUE保持定时器运行,返回FALSE停止
    return TRUE;
}

int main(int argc, char **argv) 
{
    // Initialize GStreamer
    gst_init(&argc, &argv);

    //Creating GStreamer elements
    GstElement *pipeline = gst_pipeline_new("my-pipeline");
    GstElement *src = gst_element_factory_make("nvarguscamerasrc", "src");
    GstElement *encoder = gst_element_factory_make("omxh264enc", "encoder");
    GstElement *muxer = gst_element_factory_make("mpegtsmux", "muxer");
    GstElement *sink = gst_element_factory_make("srtserversink", "sink"); // 修正:添加变量类型声明

    //Check if all elements are successfully created
    if (!pipeline || !src || !encoder || !muxer || !sink) 
    {
        g_printerr("Failed to create elements. Exiting.\n");
        return -1;
    }

    //Setting parameters for elements
    g_object_set(src, "sensor-id", 0, NULL); // 修正:C语言用NULL代替nullptr
    g_object_set(src, "sensor-mode", 0, NULL);
    g_object_set(G_OBJECT(encoder), "insert_sps_pps", TRUE, NULL);
    g_object_set(encoder, "bitrate", 25000, NULL);
    g_object_set(G_OBJECT(sink), "uri", "srt://:7008", "latency", 100, NULL);

    //Add elements to the pipeline
    gst_bin_add_many(GST_BIN(pipeline), src, encoder, muxer, sink, NULL);

    //Check if all elements are successfully added to the pipeline
    if (!gst_element_link_many(src, encoder, muxer, sink, NULL)) 
    {
        g_printerr("Failed to link elements. Exiting.\n");
        gst_object_unref(pipeline);
        return -1;
    }
  
    //Start the pipeline
    gst_element_set_state(pipeline, GST_STATE_PLAYING);

    // 添加定时器:每隔1秒触发一次统计打印(单位:毫秒)
    guint timer_id = g_timeout_add(1000, print_srt_stats, sink);
    
    //Wait until error or EOS
    GstBus *bus = gst_element_get_bus(pipeline);
    GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
    
    // 停止定时器
    g_source_remove(timer_id);

    //Stop the pipeline
    gst_element_set_state(pipeline, GST_STATE_NULL);

    //Clean up GStreamer
    gst_object_unref(bus); // 修正:添加bus的释放
    gst_object_unref(pipeline);

    return 0;
}

关键细节说明

  • 属性读取:通过g_object_get获取stats属性,得到GValueArray后必须用g_value_array_unref释放,避免内存泄漏
  • 结构解析:用gst_value_get_structure将GValue转换为GstStructure,可通过gst_structure_to_string直接打印所有字段,或用gst_structure_get_*系列函数提取特定统计项(如bytes-sent、pkt-lost、rtt等)
  • 定时器管理:g_timeout_add会将回调加入Glib主循环,管道停止时需调用g_source_remove销毁定时器
  • 代码修正:原代码中sink变量未声明类型,且C语言需用NULL代替C++的nullptr,同时添加了bus的释放逻辑

内容的提问来源于stack exchange,提问作者H_R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:20:39