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

如何用splitmuxsrc/GStreamer正确拼接视频?C实现遇内存错误

解决GStreamer splitmuxsrc format-location回调的内存错误问题

问题根源分析

你的代码存在三个核心问题,直接导致了内存释放错误:

  1. 回调返回类型不匹配:format-location信号要求回调返回GStrv(即char**),但你返回的是GStrv*(char***),类型错误导致GStreamer后续内存处理逻辑混乱。
  2. 字符串赋值错误:你将字符串常量直接赋值给malloc分配的指针,覆盖了堆内存地址,既造成内存泄漏,又让GStreamer尝试释放只读的字符串常量地址,触发pointer being freed was not allocated错误。
  3. 指针操作优先级错误:*pppvid[i]的运算优先级是先取pppvid[i]再解引用,而非先解引用pppvid再取数组元素,导致指针越界访问非法内存。

正确实现方式

核心要点

  • 使用GLib的内存管理函数(g_new0、g_strdup),因为GStreamer会用g_strfreev自动释放返回的路径数组,确保内存生命周期匹配。
  • 回调返回GStrv类型,数组必须以NULL结尾(GStreamer依赖此标记数组长度)。
  • 路径字符串必须复制到堆内存,不能直接使用字符串常量。

修正后的代码

回调函数

static GStrv format_location_callback (GstElement *splitmuxsrc, gpointer udata) {
    // 分配路径数组:2个视频路径 + NULL结尾,共3个元素
    GStrv paths = g_new0(char*, 3);
    
    // 复制路径到堆内存(必须用g_strdup,不能直接赋值字符串常量)
    paths[0] = g_strdup("path/to/video1.mp4");
    paths[1] = g_strdup("path/to/video2.mp4");
    
    // 打印验证(可选)
    for (int i = 0; paths[i] != NULL; i++) {
        g_print("待拼接路径:%s\n", paths[i]);
    }
    
    return paths;
}

信号连接代码

GstElement *splitmuxsrc = gst_element_factory_make("splitmuxsrc", "splitmuxsrc");
// 注意回调函数的签名要匹配,这里不需要额外的指针包装
g_signal_connect(splitmuxsrc, "format-location", G_CALLBACK(format_location_callback), appCtx);

额外注意事项

  • 确保路径字符串是有效的绝对路径或相对路径,GStreamer能正确访问文件。
  • 如果需要动态生成路径列表(比如从用户上下文udata中获取),可以从appCtx中读取数据,再构造数组。
  • 不要手动释放返回的paths数组,GStreamer会在使用完成后调用g_strfreev自动释放所有内存。

内容的提问来源于stack exchange,提问作者thanh.nguyen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 01:08:13