3. 视频测试源显示到窗口

任务目标

构建一个最小GStreamer管道,使用videotestsrc生成测试视频源,通过autovideosink自动选择视频输出方式显示到窗口,并显式设置分辨率和帧率参数。

环境依赖

  • GStreamer核心库及基础插件:gstreamer-1.0、gst-plugins-base-1.0、gst-plugins-good-1.0
  • 视频显示依赖平台后端(X11/Wayland/Windows),由autovideosink自动探测
  • 编译工具:pkg-config、C编译器(gcc/clang)

完整实现代码

#include <gst/gst.h>

int main(int argc, char *argv[]) {
    GstElement *pipeline, *src, *sink;
    GstCaps *caps;
    GError *error = NULL;

    gst_init(&argc, &argv);

    // 创建元素
    src = gst_element_factory_make("videotestsrc", "source");
    sink = gst_element_factory_make("autovideosink", "sink");
    if (!src || !sink) {
        g_printerr("元素创建失败,请检查插件是否安装\n");
        return -1;
    }

    // 设置视频源参数:分辨率1280x720,帧率30fps
    g_object_set(src, "pattern", 0, NULL);  // 0 = 彩条测试图案
    caps = gst_caps_new_simple("video/x-raw",
                               "width", G_TYPE_INT, 1280,
                               "height", G_TYPE_INT, 720,
                               "framerate", GST_TYPE_FRACTION, 30, 1,
                               NULL);
    g_object_set(src, "caps", caps, NULL);
    gst_caps_unref(caps);

    // 构建管道
    pipeline = gst_pipeline_new("test-pipeline");
    gst_bin_add_many(GST_BIN(pipeline), src, sink, NULL);
    if (!gst_element_link(src, sink)) {
        g_printerr("元素连接失败\n");
        gst_object_unref(pipeline);
        return -1;
    }

    // 启动播放
    gst_element_set_state(pipeline, GST_STATE_PLAYING);
    g_print("视频窗口已打开,按 Ctrl+C 退出\n");

    // 等待错误或EOS
    GstBus *bus = gst_element_get_bus(pipeline);
    GstMessage *msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
                                                  GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
    if (msg) {
        GstMsgError *err = NULL;
        if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ERROR) {
            gst_message_parse_error(msg, &error, NULL);
            g_printerr("运行错误: %s\n", error->message);
            g_error_free(error);
        }
        gst_message_unref(msg);
    }

    // 清理
    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_object_unref(pipeline);
    return 0;
}

编译与运行

# 编译
gcc test_src.c -o test_src $(pkg-config --cflags --libs gstreamer-1.0)

# 运行(需图形环境)
./test_src

验证方法

  1. 程序启动后应弹出窗口,显示标准彩条测试图案(左侧依次为白、黄、青、绿、紫、红、蓝、黑八条竖带)
  2. 窗口内容动态刷新,帧率约30fps(肉眼可感知连续运动,若图案为静态则检查帧率设置)
  3. 终端无报错输出,按Ctrl+C可正常退出

若需确认实际分辨率,可在代码中gst_element_set_state前添加以下调试代码:

gst_element_set_state(pipeline, GST_STATE_PAUSED);
GstCaps *negotiated = gst_pad_get_current_caps(gst_element_get_static_pad(src, "src"));
g_print("协商格式: %s\n", gst_caps_to_string(negotiated));
gst_caps_unref(negotiated);

预期输出格式字符串包含video/x-raw, width=(int)1280, height=(int)720, framerate=(fraction)30/1。

常见问题

  • 窗口未弹出:确认处于图形会话中,安装gst-plugins-base和gst-plugins-good;嵌入式环境可改用ximagesink或waylandsink显式指定
  • 帧率不准确:videotestsrc的帧率受系统时钟调度影响,轻微波动属正常;若严重偏低,检查是否开启垂直同步限制
  • 修改分辨率:直接修改gst_caps_new_simple中的width/height值即可,需确保显示后端支持该分辨率