Qt GStreamer/QML应用程序中的多个4K视频=黑色闪烁
我正在开发一个QML应用程序,它可以显示多达四个4K视频,带有Decklink 8K Pro和qmlglsink元素 硬件设置如下所示:Qt GStreamer/QML应用程序中的多个4K视频=黑色闪烁,qt,qml,gstreamer,flicker,blink,Qt,Qml,Gstreamer,Flicker,Blink,我正在开发一个QML应用程序,它可以显示多达四个4K视频,带有Decklink 8K Pro和qmlglsink元素 硬件设置如下所示: 4台4K摄像机 1 DeckLink 8K Pro 1台Dell Precision,配备2台Intel Xeon E5-2698(40c/80t)、256GB内存和一台Nvidia GeForce GTX 1080 在我的应用程序中同时显示4个视频时,我经常会出现黑色边框(我看到一个黑色闪光灯,然后视频又回来了)。当显示3个视频时,眨眼的频率要低得多,而
- 4台4K摄像机
- 1 DeckLink 8K Pro
- 1台Dell Precision,配备2台Intel Xeon E5-2698(40c/80t)、256GB内存和一台Nvidia GeForce GTX 1080
- 如果我启动4个Gstreamer实例,每个实例中有一个4K视频,就不会出现闪烁
- 如果我启动应用程序的4个实例,每个实例中有一个4K视频,则不会出现闪烁
- 假设我正在显示2倍摄影机A和2倍摄影机B(我还有一些硬件来复制视频流)。当闪烁发生时,该摄像机的两个视频视图(a或B)都会闪烁
// Create the source element (see below for the makeElement method):
GstElement* decklink_src = VideoView::makeElement("decklinkvideosrc", { {"device-number", 0}, {"mode", "2160p2997"}, {"profile", 4} });
// Create the pipeline element (see below for the generatePipeline method):
GstElement* pipeline = generatePipeline(_source, m_videoViewItem->findChild<QQuickItem*> ("videoView"));
// Schedule rendering:
m_window->scheduleRenderJob(new SetPlaying (m_pipeline), QQuickWindow::BeforeSynchronizingStage);
GstElement* VideoView::makeElement(const std::string& _elementName, const std::map<std::string, QVariant>& _params)
{
GstElement* element = gst_element_factory_make(_elementName.c_str(), nullptr);
for(const auto& attribute : _params)
{
const char* name = attribute.first.c_str();
switch (attribute.second.type())
{
case QVariant::Type::Int:
g_object_set (element, name, attribute.second.toInt(), nullptr);
break;
case QVariant::Type::String:
gst_util_set_object_arg (G_OBJECT(element), name, attribute.second.toString().toStdString().c_str());
break;
default: break;
}
}
return element;
}
GstElement* VideoView::generatePipeline(GstElement* _src, QQuickItem* _parent)
{
GstElement* pipeline = gst_pipeline_new(nullptr);
GstElement* queue = gst_element_factory_make ("queue", nullptr);
GstElement* glupload = gst_element_factory_make ("glupload", nullptr);
GstElement* glcolorconvert = gst_element_factory_make ("glcolorconvert", nullptr);
GstElement* sink = gst_element_factory_make ("qmlglsink", nullptr);
g_assert (_src && queue && glupload && glcolorconvert && sink);
gst_bin_add_many(GST_BIN (pipeline), _src, queue, glupload, glcolorconvert, sink, nullptr);
gst_element_link_many( _src, queue, glupload, glcolorconvert, sink, nullptr);
g_object_set(sink, "widget", _parent, nullptr);
return pipeline;
}
//创建源元素(makeElement方法见下文):
GstElement*decklink_src=VideoView::makeElement(“decklinkvideosrc”,{{“设备编号”,0},{“模式”,“2160p2997”},{“配置文件”,4});
//创建管道元素(请参见下面的GeneratePiline方法):
GstElement*pipeline=generatePiline(_source,m_videoViewItem->findChild(“videoView”);
//计划渲染:
m_window->scheduleRenderJob(新设置播放(m_管道),QQuickWindow::Before SynchronizingStage);
GstElement*VideoView::makeElement(常量std::string&_elementName,常量std::map&_参数)
{
GstElement*element=gst\u element\u factory\u make(\u elementName.c\u str(),nullptr);
用于(常量自动和属性:_参数)
{
const char*name=attribute.first.c_str();
开关(attribute.second.type())
{
案例QVariant::Type::Int:
g_object_set(元素、名称、属性.second.toInt()、nullptr);
打破
案例QVariant::类型::字符串:
gst_util_set_object_arg(G_object(element),name,attribute.second.toString().tostString().c_str());
打破
默认:中断;
}
}
返回元素;
}
GstElement*VideoView::generatePiline(GstElement*\u src,QQuickItem*\u父级)
{
GstElement*管道=gst_管道_新(nullptr);
GstElement*队列=gst\u元素\u工厂\u制造(“队列”,空PTR);
GstElement*glupload=gst元素工厂制造(“glupload”,nullptr);
GstElement*glcolorconvert=gst\u元素\u工厂制造商(“glcolorconvert”,nullptr);
GSTLEMENT*sink=gst\U元件\U工厂制造商(“qmlglsink”,nullptr);
g_assert(_src&&queue&&glupload&&glcolorconvert&&sink);
gst_bin_add_many(gst_bin(管道),_src,queue,glupload,glcolorconvert,sink,nullptr);
gst\u元素\u链接\u多(\u src、queue、glupload、glcolorconvert、sink、nullptr);
g_对象_集(接收器、“小部件”、“父对象”、“空PTR”);
回流管道;
}
我可以以代码的形式发布我的建议,但是伙计,这是不是太详细了,我记不起其他Stack*论坛是做什么的了?尽管如此,这听起来几乎像是工作,并不一定对你有帮助(不知道视频到底是如何呈现的,建议进行大的返工?)。请考虑一下这个问题:简单地说,我们正在处理一些QT QML缺陷。谢谢链接,我可以尝试一些建议。我还将尝试固定布局(目前视频可以拖放)。渲染由GStreamer完成。如果您想查看一下,它发生在qtitem.cc()的QtGLVideoItem::updatePaintNode方法和GstQSGTexture()中。如果您不熟悉Gstreamer,则有点难以理解。虽然我没有使用QtGLVideoItem,但我有根据地猜测,您需要在QQuickWindow::beforeRendering信号之前进行多个挂起的OpenGL更新。这将使闪烁最小化。我熟悉GStreamer,但仍然没有使用它们。@AlexanderV,谢谢。我把我的QML降到了最低,并尝试了一些关于你链接的建议,但没有改变。我想问题在于qmlglsink元素本身,我将在GStreamer的GitLab中打开一个票证。作为参考,这里是GStreamer票证: