c++ - GStreamer gst_buffer_make_writable 段错误和引用计数“hack”
问题描述
我为 GStreamer 中的缓冲区实现了一个自定义元数据结构。为了使用这个结构,我创建了一个焊盘探针并使用 访问缓冲区auto buffer = gst_pad_probe_info_get_buffer(info);
,其中info
a 是GstPadProbeInfo *info
。
管道的大多数元素都有可写缓冲区,我对它们没有任何问题,但是当尝试访问队列元素的接收器垫中的缓冲区时,似乎该缓冲区不可写。我已经尝试使用该buffer = gst_buffer_make_writable(buffer);
方法,但没有运气。使用它时出现分段错误。如果我只是尝试创建另一个临时可写缓冲区,我也会遇到分段错误:auto *tmpBuffer = gst_buffer_make_writable(buffer);
(rtspserver:23806):GStreamer-CRITICAL **:09:23:03.442:gst_buffer_get_sizes_range:断言'GST_IS_BUFFER(缓冲区)'失败
(rtspserver:23806):GStreamer-CRITICAL **:09:23:03.442:gst_buffer_copy_into:断言'bufsize> = offset'失败
(rtspserver:23806):GStreamer-CRITICAL **:09:23:03.442:gst_buffer_get_sizes_range:断言'GST_IS_BUFFER(缓冲区)'失败
(rtspserver:23806):GStreamer-CRITICAL **:09:23:03.443:gst_buffer_extract:断言'GST_IS_BUFFER(缓冲区)'失败
(rtspserver:23806):GStreamer-CRITICAL **:09:23:03.443:gst_buffer_foreach_meta:断言'buffer!= NULL'失败
(rtspserver:23806):GStreamer-CRITICAL **:09:23:03.443:gst_buffer_append_region:断言'GST_IS_BUFFER(buf2)'失败分段错误
我尝试的另一件事是将缓冲区复制到另一个临时缓冲区auto *tmpBuffer = gst_buffer_copy(buffer);
,但是我也遇到了覆盖gst_buffer_replace(&buffer, tmpBuffer);
原始缓冲区的问题。
我找到了一个解决方案/hack:我增加了buffer = gst_buffer_ref(buffer);
队列元素的引用计数(从 2 到 3),然后直接访问缓冲区而不检查它的可写性。之后我取消引用缓冲区gst_buffer_unref(buffer);
。这似乎有效,我想知道为什么。如果我不增加引用计数并尝试访问缓冲区而不检查它的可写性,我会崩溃。我知道这是不安全的,因此我想以某种方式使缓冲区可写。
解决方案
如果源缓冲区 buf 的引用计数恰好为 1,则调用者是唯一所有者,此函数将返回未更改的缓冲区对象。
如果对象上有多个引用,将使用 gst_buffer_copy 进行复制。在这种情况下,传入的 buf 将不被引用,调用者现在将拥有对新返回的缓冲区对象的引用。请注意,这只是复制缓冲区结构本身,如果可以在多个缓冲区之间共享底层内存,则不会复制它。
简而言之,此函数取消引用参数中的 buf 并引用它返回的缓冲区。调用此函数后不要访问参数,除非您对它有额外的引用。
推荐阅读
- python-3.x - 将 wav 转换为文本
- sql - 获取有交集的元组
- android - RecyclerView 适配器 onItemClick 事件未触发
- html - 如何将嵌入的 html 标签执行到像这样的角度值绑定中:{{variable}}?
- java - 确保接收到的 Rabbit MQ 事件的顺序
- encryption - 如何以编程方式解密 Vault 生成的 AES256-GCM96 密文并导出 Vault 密钥?
- angular - 给出角度路由器参数而不在 url 中
- sql-server-2008 - 如何使用 SSMS 连接到 MS Dynamics 365 CRM
- javascript - 如何将滚动高度设置为数组长度?
- imagemagick - 如何在 TYPO3 安装工具中调试 ImageMagick 图像处理?