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

GStreamer多视频流合成模块appsrc is-live配置问题求助

GStreamer多视频流合成模块时间戳与丢包问题解决方案

问题根源分析

  1. is-live=false时冻结:compositor在非live模式下会等待所有sink pad都有数据才输出,当某路流播放结束后无新数据输入,整个合成流会停滞。你设置的ignore-inactive-pads=true本应解决此问题,但非live模式下该参数不生效——compositor仍会等待已结束的流发送数据。
  2. is-live=true时丢包:日志中显示buffer的DTS为99:99:99.999999999(无效值),且PTS可能与流水线运行时间不同步。live模式下appsrc会严格校验buffer时间戳,若时间戳滞后或无效,会判定为过期buffer并丢弃。do-timestamp=true无效是因为该参数仅给无时间戳的buffer自动打戳,若buffer本身带错误时间戳,反而会干扰流水线同步。

具体修复步骤

1. 修正输入Buffer的时间戳

推送到appsrc的每个buffer必须携带有效且单调递增的PTS/DTS:

  • 对于文件源:保留原始视频帧的PTS,或按帧率计算连续时间戳(如第n帧的PTS为n * GST_SECOND / fps)。
  • 对于RTP流:直接使用RTP包携带的时间戳转换为GStreamer时钟时间。
  • 强制清除无效DTS:若输入buffer的DTS为GST_CLOCK_TIME_NONE或无效值,将其设置为与PTS相同(无B帧场景)。

2. 调整appsrc参数配置

live模式下,确保参数与时间戳逻辑匹配:

for (int i = 0; i < _number_of_inputs; ++i)
{
    g_object_set(G_OBJECT(_appsrcs->at(i)), 
                 "block", true,                  // 推送时阻塞直到流水线接收,避免buffer堆积
                 "stream-type", GST_APP_STREAM_TYPE_STREAM,
                 "leaky-type", GST_APP_LEAKY_TYPE_NONE, // 关闭自动丢包,先确保时间戳正确
                 "format", GST_FORMAT_TIME,
                 "do-timestamp", false,          // 输入buffer已有正确时间戳,关闭自动打戳
                 "is-live", true, NULL);
}

3. 处理流结束的EOS事件

当某路输入流读取完毕时,给对应的appsrc发送EOS事件,compositor会标记该pad为inactive并继续处理其他流:

// 某路流读取完成后调用
gst_app_src_end_of_stream(GST_APP_SRC(_appsrcs->at(i)));

4. 修复request_pad内存泄漏

你请求的compositor pad需要在流水线销毁时手动释放,否则会造成内存泄漏:

// 在流水线销毁前执行
for (int i = 0; i < _number_of_inputs; ++i)
{
    gchar *pad_name = g_strdup_printf("sink_%u", i);
    GstPad *compositor_pad = gst_element_get_static_pad(_compositor, pad_name);
    if (compositor_pad) {
        gst_element_release_request_pad(_compositor, compositor_pad);
        gst_object_unref(compositor_pad);
    }
    g_free(pad_name);
}

5. 推送Buffer时的时间戳校验示例

// 假设读取到帧数据data,帧率fps,帧索引frame_idx
GstBuffer *buffer = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY, data, size, 0, size, NULL, NULL);

// 计算并设置有效时间戳
GstClockTime frame_duration = GST_SECOND / fps;
GstClockTime pts = frame_idx * frame_duration;
GST_BUFFER_PTS(buffer) = pts;
GST_BUFFER_DTS(buffer) = pts; // 无B帧时DTS与PTS一致
GST_BUFFER_DURATION(buffer) = frame_duration;

// 推送buffer
GstFlowReturn ret = gst_app_src_push_buffer(GST_APP_SRC(_appsrcs->at(i)), buffer);
if (ret != GST_FLOW_OK) {
    // 处理推送失败逻辑(如日志记录、重试)
}

最终效果验证

  • 设置is-live=true+正确时间戳后,丢包警告会消失,多路流可正常同步合成。
  • 某路流结束发送EOS后,compositor会忽略该pad,其他流继续播放,不会出现冻结。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:23:14