繁体   English   中英

Gstreamer:释放管道资源的正确方法?

[英]Gstreamer : proper way to release resources of a pipeline?

我正在使用 UriDecodeBin 在 Gstreamer 中构建管道。 该管道本应反复构建和发布,但我很难弄清楚如何正确删除该管道。

现在,我试图找出要取消引用的内容和不取消引用的内容,以便释放管道的所有资源,管道中只有一个 UriDecodeBin,但我无法以某种方式释放完整的 memory .

我的操作顺序如下:

首先,我正在构建管道和 UriDecodeBin:


_pipeline = (GstPipeline*)gst_pipeline_new("pipeline");
_bus = gst_pipeline_get_bus(_pipeline); //will be manually observed
_decoder = gst_element_factory_make("uridecodebin", "decoder");
gst_bin_add(GST_BIN(_pipeline), _decoder);
gst_element_sync_state_with_parent(_decoder);
std::string uri = std::string("file://some_video_file");
g_object_set(_decoder, "uri", uri.c_str(), nullptr);

g_signal_connect(_decoder, "no-more-pads", G_CALLBACK(GsDecoder::no_more_pads_cb), (gpointer)this);
changePipelineState(GST_STATE_PAUSED);

然后,我等待 no-more-pads 触发,并在每个焊盘上添加一个阻塞探针:

GstIterator *it = gst_element_iterate_src_pads(_decoder);
GValue padV = G_VALUE_INIT;
while(gst_iterator_next(it, &padV) == GST_ITERATOR_OK){
  GstPad* pad = (GstPad*)g_value_get_object(&padV);
  GstCaps* caps = gst_pad_get_current_caps(pad);
  if(caps_is_audio(caps)){
    _decoderAudioSrcs.push_back(pad); //adding pad to a collection
    gulong id = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, GsDecoder::pad_blocked_cb, (gpointer)this, NULL); //blocking probe
    _decoderAudioProbeIds.push_back(id); //remembering id of the probe, for later
  } else if (caps_is_video(caps)){
             //same with video but file is guaranteed to have a single video track.
    _decoderVideoSrc = pad; 
    _decoderVideoProbeId = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM, GsDecoder::pad_blocked_cb, (gpointer)this, NULL);
  } else {
            std::cout << "UNKNOWN PAD FOUND" << std::endl;
  }
  gst_caps_unref(caps); //releasing caps
  g_value_unset(&padV);
}

在这一点上,我等待所有探针阻塞焊盘,然后我解除阻塞焊盘:

for (unsigned i = 0; i < _decoderAudioSrcs.size(); i++){
  gst_pad_remove_probe(_decoderAudioSrcs[i], _decoderAudioProbeIds[i]);
}
gst_pad_remove_probe(_decoderVideoSrc, _decoderVideoProbeId);
play(); //setting the pipeline to play

最后,过了一会儿,我命令管道自行删除,我对应该删除或不删除的内容有点困惑(无论是在这个管道中还是在一般情况下)。

  • 如何删除管道? 据我了解,我必须将管道 state 设置为 Null,然后使用g_object_unref取消对所有内容(pad、解码器、总线、管道)的引用,但是它仍然导致管道几乎没有指向它的引用(在我的例子中,3),并且不释放其资源,它会是 memory 还是线程。
  • 有没有办法告诉 Gstreamer 完全删除管道和与之相关的所有内容,而不必手动取消引用所有内容?

特别是,我会对指向某些文档的指针感兴趣,因为我找不到任何关于该主题的内容(即使 Gstreamer 文档不时提到 unrefing)。

GStreamer 对象是引用计数的。 每当引用下降到 0 时,object 就会被删除。 GStreamer 文档通常会告诉您有关其传输行为的 function。 例如

gst_pad_get_current_caps() https://gstreamer.freedesktop.org/documentation/gstreamer/gstpad.html#gst_pad_get_current_caps

告诉您传输已满,您应该在不再使用它时释放它(您在示例代码中这样做)。 如果您不这样做,它将永远不会被删除。

所以典型的用例是如果我不再需要它,我就释放它。 这并不意味着它会被删除。 例如,如果您将一个元素放入管道中,管道将添加对它的引用。 它会处理引用并在管道的引用计数下降到 0 时释放它。但是由于您将它添加到管道并且您的代码本身不再需要它,您通常会释放它。

所以你需要小心参考。 如果你错过了一个很小的 object,它可能是一个大管道的一部分,它可能会导致许多对象不能被释放,因为它们相互依赖。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM