首页 > 解决方案 > GStreamer gst_buffer_make_writable 段错误和引用计数“hack”

问题描述

我为 GStreamer 中的缓冲区实现了一个自定义元数据结构。为了使用这个结构,我创建了一个焊盘探针并使用 访问缓冲区auto buffer = gst_pad_probe_info_get_buffer(info);,其中infoa 是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);。这似乎有效,我想知道为什么。如果我不增加引用计数并尝试访问缓冲区而不检查它的可写性,我会崩溃。我知道这是不安全的,因此我想以某种方式使缓冲区可写。

标签: c++gstreamergstreamer-1.0

解决方案


如果源缓冲区 buf 的引用计数恰好为 1,则调用者是唯一所有者,此函数将返回未更改的缓冲区对象。

如果对象上有多个引用,将使用 gst_buffer_copy 进行复制。在这种情况下,传入的 buf 将不被引用,调用者现在将拥有对新返回的缓冲区对象的引用。请注意,这只是复制缓冲区结构本身,如果可以在多个缓冲区之间共享底层内存,则不会复制它。

简而言之,此函数取消引用参数中的 buf 并引用它返回的缓冲区。调用此函数后不要访问参数,除非您对它有额外的引用。


推荐阅读