Gstreamer与OPENCV交互中的APPSINK问题

探讨了在使用GStreamer的appsink组件处理实时视频流时遇到的内存问题,特别是在第995帧左右出现map.data==NULL的情况,分析了问题原因并提供了调整max-size-time参数的解决方案。

项目中使用appsink获取实时视频流,并将获取到的数据转入OPENCV进行处理(在此使用imshow显示)。

appsink使用new-sample信号获取帧数据,使用中发现问题:

在获取到995或者996帧的时候,遇到map.data==NULL的情况,但是显示线程还是正常显示,只是图像有拖影,就像是CPU占用过高时图像处理不及时一样,暂时未找出原因。

2020-02-25更新

由于一直是在获取到995左右出问题,判断大概是因为1000的帧限制,因为appsink中有个参数:max-size-time,默认值为:1000.曾经信尝试将此参数设置为2000,还是出现一样的问题。有怀疑过是内存限制问题,但是通过top实时查看内存占用情况,整个过程中并没有超过80%的占用率。

查看gstreamer的源码,看到gst_buffer_map方法中有调试信息GST_DEBUG_OBJECT输出,因此通过使用--gst-debug=appsink:5,fdmemory:5参数查看调试信息(在此使用appsink和fdmemory是使用--gst-debug-level=5对所有日志信息进行查看,估计是这两个组件出的问题,用这两个参数是把其他不必要的信息排除,方便查看),发现出问题的时候,是gstfdmemory.c中先出:fd:-1 maped(nil)信息。在 此确定应该是内存不足的问题,但是前面使用top查看实时内存占用情况时,又没有发现内存不足问题(好纠结啊……)。重新整理思路后发现,程序中使用的是rkisp这个源,显示也是使用rkximagesink,正常显示时CPU占用很少,因为整个过程中使用的是硬件资源进行处理,或许在此过程中,内存占用不是我们看到的常规内存空间,而是像fdm(应该是这个,或者是dma)这样的内存空间。然后就出现1000frame的空间将此内存空间耗尽,所以每次都在固定的995左右出问题。

 

解决方法:appsink的参数max-size-time设置为500,程序正常运行,跑了2个小时,帧数到1W6以上,视频正常,程序正常。

总结:问题出现的时候,就初步判断应该是内存问题(因为都是在995左

(csi_lowres:40430): GLib-GObject-WARNING **: 12:25:48.079: invalid cast from 'GstVideoConvert' to 'GstBin' (csi_lowres:40430): GStreamer-CRITICAL **: 12:25:48.079: gst_bin_iterate_elements: assertion 'GST_IS_BIN (bin)' failed (csi_lowres:40430): GStreamer-CRITICAL **: 12:25:48.079: gst_iterator_next: assertion 'it != NULL' failed (csi_lowres:40430): GStreamer-CRITICAL **: 12:25:48.080: gst_iterator_free: assertion 'it != NULL' failed [ WARN:0@0.309] global ./modules/videoio/src/cap_gstreamer.cpp (1226) open OpenCV | GStreamer warning: cannot find appsink in manual pipeline [ WARN:0@0.309] global ./modules/videoio/src/cap_gstreamer.cpp (862) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created CSI初始化失败!错误详情: [ 10.593283] Bluetooth: BNEP socket layer initialized [ 10.606395] Bluetooth: MGMT ver 1.23 [ 10.633165] NET: Registered PF_ALG protocol family [ 13.290639] brcmfmac: brcmf_cfg80211_set_power_mgmt: power save enabled [ 15.311267] systemd-journald[233]: File /var/log/journal/ab574c328f654edf82efde704fb5fd76/user-1000.journal corrupted or uncleanly shut down, renaming and replacing. [ 22.802438] Bluetooth: RFCOMM TTY layer initialized [ 22.802511] Bluetooth: RFCOMM socket layer initialized [ 22.802547] Bluetooth: RFCOMM ver 1.11 [ 158.520959] bcm2835_v4l2: module is from the staging directory, the quality is unknown, you have been warned. [ 298.574743] bcm2835_v4l2: module is from the staging directory, the quality is unknown, you have been warned.
最新发布
05-21
### GStreamerOpenCV 错误解决方案 用户提到的问题主要集中在以下几个方面: 1. **GStreamer 的 `gst_bin_iterate_elements` 断言失败**。 2. **OpenCV Qt 平台插件加载失败 (`xcb`) 的问题**。 以下是详细的分析和解决方案: --- ### 关于 GStreamer 的 `gst_bin_iterate_elements` 断言失败 断言失败通常是由于操作不符合预期的状态或条件引发的。以下是一些常见原因及其解决方法: #### 1. **Bin 中不存在任何 Element** 调用 `gst_bin_iterate_elements` 前,确保 Bin 已经包含了至少一个有效的 Element。如果没有添加任何 Element,则迭代器返回的结果为空,从而触发断言失败。 - 示例代码展示如何正确初始化并添加 Elements 至 Bin[^1]: ```c #include <gst/gst.h> int main(int argc, char *argv[]) { GstElement *bin, *source, *sink; gst_init(&argc, &argv); bin = gst_bin_new("my_bin"); source = gst_element_factory_make("fakesrc", "source"); sink = gst_element_factory_make("fakesink", "sink"); // 确保在调用 iterate 函数前已经成功添加了 element gst_bin_add(GST_BIN(bin), source); gst_bin_add(GST_BIN(bin), sink); // 正确使用 gst_bin_iterate_elements() GList *elements = gst_bin_iterate_elements(GST_BIN(bin)); while (elements) { GstElement *element = GST_ELEMENT(elements->data); g_print("Found element: %s\n", GST_OBJECT_NAME(element)); elements = g_list_next(elements); } gst_object_unref(bin); return 0; } ``` #### 2. **Element 生命周期管理不当** 当从 Bin 删除某个 Element 后,其引用计数会被减少。如果此时再次访问已被删除的 Element,可能会导致崩溃或断言失败。 - 解决方法:始终遵循正确的生命周期管理原则。例如,在销毁 Bin 之前清理所有子 Element[^1]。 --- ### 关于 OpenCV 和 Qt 平台插件加载失败 (`xcb`) 此问题是典型的 Linux 下 GUI 应用程序运行时遇到的错误,主要原因在于缺少必要的依赖项或配置不正确。 #### 1. **Qt 插件路径未正确定位** 即使安装了 Qt,但如果环境变量未指向正确的插件目录,也可能导致加载失败。 - 设置环境变量以显式指定插件路径: ```bash export QT_QPA_PLATFORM_PLUGIN_PATH=/path/to/qt/plugins/platforms ``` 替换 `/path/to/qt/plugins/platforms` 为实际路径。可以通过以下命令定位默认路径: ```bash find /usr/lib -type d -name platforms ``` #### 2. **XCB 协议支持缺失** 某些轻量化的操作系统镜像可能并未预装 XCB 相关库文件。 - 安装必要依赖项: ```bash sudo apt-get update && sudo apt-get install libxcb-util1 libxcb-image0 libxcb-shm0 libxcb-randr0 libxcb-render-util0 libxcb-keysyms1 ``` #### 3. **远程连接下的显示问题** 通过 SSH 访问服务器时,默认情况下不会转发图形界面数据流。 - 启用 X11 转发功能: ```bash ssh -X user@remote_host ``` 或者更高效的方式是使用 `-Y` 参数代替 `-X` 来启用受信任的转发模式。 #### 4. **无头模式(Headless Mode)下运行** 对于不需要交互式的应用场景,可切换至无头模式避免依赖复杂的 GUI 架构。 - 修改 OpenCV 初始化逻辑跳过窗口创建步骤[^5]: ```python import cv2 as cv def process_image(image_path): img = cv.imread(image_path) gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # 注释掉 imshow 行防止尝试绘制窗口 # cv.imshow('Gray Image', gray_img) # cv.waitKey(0) return gray_img ``` --- ### 综合总结 通过对上述两个核心问题的具体剖析可以看出,无论是 GStreamer 还是 OpenCV 结合 Qt 使用过程中都需要注意细节上的把控。合理规划项目结构、严格遵守 API 文档指导以及充分测试不同运行环境均有助于提升开发效率降低潜在风险。 --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值