![](/img/trans.png)
[英]What is the proper way to incorporate gstreamer into Qt (Windows)?
[英]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
最后,过了一会儿,我命令管道自行删除,我对应该删除或不删除的内容有点困惑(无论是在这个管道中还是在一般情况下)。
g_object_unref
取消对所有内容(pad、解码器、总线、管道)的引用,但是它仍然导致管道几乎没有指向它的引用(在我的例子中,3),并且不释放其资源,它会是 memory 还是线程。特别是,我会对指向某些文档的指针感兴趣,因为我找不到任何关于该主题的内容(即使 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.