GStreamer gst_buffer_make_writable 错误和引用计数 "hack"
GStreamer gst_buffer_make_writable seg fault and refcount "hack"
我在 GStreamer 中为缓冲区实现了自定义元数据结构。为了使用这个结构,我创建了一个 pad 探针并使用 auto buffer = gst_pad_probe_info_get_buffer(info);
访问缓冲区,其中 info
是 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: assertion 'GST_IS_BUFFER (buffer)' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.442:
gst_buffer_copy_into: assertion 'bufsize >= offset' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.442:
gst_buffer_get_sizes_range: assertion 'GST_IS_BUFFER (buffer)' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.443:
gst_buffer_extract: assertion 'GST_IS_BUFFER (buffer)' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.443:
gst_buffer_foreach_meta: assertion 'buffer != NULL' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.443:
gst_buffer_append_region: assertion 'GST_IS_BUFFER (buf2)' failed
Segmentation fault
我尝试的另一件事是将缓冲区复制到另一个临时缓冲区 auto *tmpBuffer = gst_buffer_copy(buffer);
,但是我也遇到了覆盖 gst_buffer_replace(&buffer, tmpBuffer);
原始缓冲区的问题。
我发现了一个solution/hack:我增加了队列元素的引用计数buffer = gst_buffer_ref(buffer);
(从2 到3),然后直接访问缓冲区而不检查它的可写性。之后我取消引用缓冲区 gst_buffer_unref(buffer);
。这似乎有效,我想知道为什么。如果我不增加引用计数并尝试访问缓冲区而不检查它的可写性,我就会崩溃。我知道这是不安全的,因此我想以某种方式使缓冲区可写。
如果源缓冲区 buf 的引用计数恰好为 1,则调用者是唯一所有者,此函数将 return 缓冲区对象不变。
如果对象有多个引用,将使用 gst_buffer_copy 制作一份副本。在这种情况下,传入的 buf 将被取消引用,调用者现在将拥有对新 returned 缓冲区对象的引用。请注意,这只是复制缓冲区结构本身,如果它可以在多个缓冲区之间共享,则不会复制底层内存。
简而言之,此函数取消引用参数中的 buf 并引用它 return 的缓冲区。调用此函数后不要访问参数,除非您有对它的附加引用。
我在 GStreamer 中为缓冲区实现了自定义元数据结构。为了使用这个结构,我创建了一个 pad 探针并使用 auto buffer = gst_pad_probe_info_get_buffer(info);
访问缓冲区,其中 info
是 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: assertion 'GST_IS_BUFFER (buffer)' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.442: gst_buffer_copy_into: assertion 'bufsize >= offset' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.442: gst_buffer_get_sizes_range: assertion 'GST_IS_BUFFER (buffer)' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.443: gst_buffer_extract: assertion 'GST_IS_BUFFER (buffer)' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.443: gst_buffer_foreach_meta: assertion 'buffer != NULL' failed
(rtspserver:23806): GStreamer-CRITICAL **: 09:23:03.443: gst_buffer_append_region: assertion 'GST_IS_BUFFER (buf2)' failed Segmentation fault
我尝试的另一件事是将缓冲区复制到另一个临时缓冲区 auto *tmpBuffer = gst_buffer_copy(buffer);
,但是我也遇到了覆盖 gst_buffer_replace(&buffer, tmpBuffer);
原始缓冲区的问题。
我发现了一个solution/hack:我增加了队列元素的引用计数buffer = gst_buffer_ref(buffer);
(从2 到3),然后直接访问缓冲区而不检查它的可写性。之后我取消引用缓冲区 gst_buffer_unref(buffer);
。这似乎有效,我想知道为什么。如果我不增加引用计数并尝试访问缓冲区而不检查它的可写性,我就会崩溃。我知道这是不安全的,因此我想以某种方式使缓冲区可写。
如果源缓冲区 buf 的引用计数恰好为 1,则调用者是唯一所有者,此函数将 return 缓冲区对象不变。
如果对象有多个引用,将使用 gst_buffer_copy 制作一份副本。在这种情况下,传入的 buf 将被取消引用,调用者现在将拥有对新 returned 缓冲区对象的引用。请注意,这只是复制缓冲区结构本身,如果它可以在多个缓冲区之间共享,则不会复制底层内存。
简而言之,此函数取消引用参数中的 buf 并引用它 return 的缓冲区。调用此函数后不要访问参数,除非您有对它的附加引用。