如何用splitmuxsrc/GStreamer正确拼接视频?C实现遇内存错误
解决GStreamer splitmuxsrc format-location回调的内存错误问题
问题根源分析
你的代码存在三个核心问题,直接导致了内存释放错误:
- 回调返回类型不匹配:
format-location信号要求回调返回GStrv(即char**),但你返回的是GStrv*(char***),类型错误导致GStreamer后续内存处理逻辑混乱。 - 字符串赋值错误:你将字符串常量直接赋值给
malloc分配的指针,覆盖了堆内存地址,既造成内存泄漏,又让GStreamer尝试释放只读的字符串常量地址,触发pointer being freed was not allocated错误。 - 指针操作优先级错误:
*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
相关产品推荐
相关产品推荐

