Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt GStreamer/QML应用程序中的多个4K视频=黑色闪烁_Qt_Qml_Gstreamer_Flicker_Blink - Fatal编程技术网

Qt GStreamer/QML应用程序中的多个4K视频=黑色闪烁

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个视频时,眨眼的频率要低得多,而

我正在开发一个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个视频时,眨眼的频率要低得多,而且我认为我在只显示1或2个视频时没有看到它们

有几件有趣的事:

  • 如果我启动4个Gstreamer实例,每个实例中有一个4K视频,就不会出现闪烁
  • 如果我启动应用程序的4个实例,每个实例中有一个4K视频,则不会出现闪烁
  • 假设我正在显示2倍摄影机A和2倍摄影机B(我还有一些硬件来复制视频流)。当闪烁发生时,该摄像机的两个视频视图(a或B)都会闪烁
在我看来,这似乎是一个线程问题,但向管道中添加队列元素并不能解决该问题。将QSG_RENDER_循环设置为使用qputenv线程化也不起作用

还有什么我能做的吗

下面是一些用于创建管道的代码:

// 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票证: