C++/C GST 跟踪 GstElement 生命周期

问题描述 投票:0回答:2

我正在构建一个非常复杂的 gstreamer 应用程序,如果可能,它会尝试重用部分管道。无论如何,我怀疑管道没有正确清理,因为该过程不断堆积文件描述符并且不释放它们。

我怀疑重新计算的管道

GstElement
(以及随后的
filesource
)以某种方式保持活动状态,因为我搞砸了重新计算。为了简化调试,有没有办法:

  • 添加在引用计数达到 0 之前调用的某种回调,这样我就可以确保所有管道都被正确销毁?
  • 通过某种上下文获取所有全球现有
    GstElement
    的列表?
c++ gstreamer
2个回答
0
投票

一旦元素被添加到 bin 或管道责任由父级承担。如果父元素被正确销毁,那么该元素也将被销毁。

破坏管道你可以按照这个。

{
   GstElement *pipeline = gst_pipeline_new ("mystuff")
   .
   .
   .
   // Do your stuff here
   gst_element_send_event(GST_ELEMENT(pipeline), gst_event_new_eos());
   gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
   gst_object_unref (pipeline);
}

0
投票

如果您使用的是 C++,我建议使用简单的 RAII 包装器,这有助于资源生命周期管理。一个例子:

#include <gst/gst.h>

#include <memory>
#include <type_traits>

template <auto Fn>
using FunctionObj = std::integral_constant<decltype(Fn), Fn>;

template <typename T, auto Fun>
using ResourceReleasedByFunction = std::unique_ptr<T, FunctionObj<Fun>>;

template <typename T, auto Fun>
void AddressOfPtr(T* rsc) {
  Fun(&rsc);
}

using ScopedGstElement = ResourceReleasedByFunction<GstElement, gst_object_unref>;
using ScopedGstCaps = ResourceReleasedByFunction<GstCaps, gst_caps_unref>;
using ScopedGstSample = ResourceReleasedByFunction<GstSample, gst_sample_unref>;
using ScopedGstBuffer = ResourceReleasedByFunction<GstBuffer, gst_buffer_unref>;
using ScopedGstPad = ResourceReleasedByFunction<GstPad, gst_object_unref>;
using ScopedGstBus = ResourceReleasedByFunction<GstBus, gst_object_unref>;

using ScopedGChar = ResourceReleasedByFunction<gchar, g_free>;
using ScopedGError = ResourceReleasedByFunction<GError, AddressOfPtr<GError, g_clear_error>>;
using ScopedGMainContext = ResourceReleasedByFunction<GMainContext, g_main_context_unref>;
using ScopedGMainLoop = ResourceReleasedByFunction<GMainLoop, g_main_loop_unref>;

用法示例:

ScopedGstElement pipeline{gst_pipeline_new("mypipeline")};
ScopedGstElement camerasource{gst_element_factory_make("v4l2src", "v4l2src")};
ScopedGstElement videoconvert{gst_element_factory_make("videoconvert", "videoscale")};
ScopedGstElement videosink{gst_element_factory_make("fakesink", "fakesink")};

gst_bin_add_many(GST_BIN(pipeline.get()), camerasource.release(), videoconvert.release(), videosink.release(), nullptr);

多亏了你不需要记得清理资源,甚至当你记得你可能会调用一个无效的函数,例如

gst_object_unref
而不是
gst_buffer_unref

© www.soinside.com 2019 - 2024. All rights reserved.