如何使用GStreamer和Opencv VideoWriter?

3

我正试图使用Opencv VideoWriter传输H264流,以便通过VideoCapture在网络上的另一台计算机上获取。但是,我卡在了VideoWriter上。执行此代码会返回错误,并且out.isOpened()始终为false。

    int FOURCC = cv::VideoWriter::fourcc('H', '2', '6', '4');
    cv::VideoWriter out;
    out.open ("appsrc ! videoconvert ! x264enc tune=zerolatency bitrate=500 speed-preset=superfast ! rtph264pay ! udpsink host=127.0.0.1 port=5000",
        cv::CAP_GSTREAMER,
        FOURCC,
        16,
        cv::Size (640, 480),
        true);

    if (!out.isOpened ()) {
        qDebug () << "\ n ***** Failed to open videowriter *****";
        return -1;
    }

[ WARN:0] global D:\Libs\opencv-4.3.0\modules\videoio\src\cap_gstreamer.cpp (1274) cv::CvVideoWriter_GStreamer::close_ OpenCV | GStreamer warning: No source in GStreamer pipeline. Ignore
[ERROR:0] global D:\Libs\opencv-4.3.0\modules\videoio\src\cap.cpp (527) cv::VideoWriter::open VIDEOIO(GSTREAMER): raised OpenCV exception:
OpenCV(4.3.0) D:\Libs\opencv-4.3.0\modules\videoio\src\cap_gstreamer.cpp:144: error: (-215:Assertion failed) ptr in function 'cv::`anonymous-namespace'::GSafePtr<struct _GstElement>::get'

***** Failed open videowriter *****

即使是简单的例子也会返回错误并且 out.isOpened() 为false。
    out.open("autovideosrc ! videoconvert ! appsink",
             cv::CAP_GSTREAMER,
             FOURCC,
             16,
             cv::Size(640, 480),
             true);

[ WARN:0] global D:\Libs\opencv-4.3.0\modules\videoio\src\cap_gstreamer.cpp (1500) cv::CvVideoWriter_GStreamer::open    OpenCV | GStreamer warning: OpenCV backend does not support this file type (extension): autovideosrc ! videoconvert !   appsink
[ WARN:0] global D:\Libs\opencv-4.3.0\modules\videoio\src\cap_gstreamer.cpp (1274) cv::CvVideoWriter_GStreamer::close_  OpenCV | GStreamer warning: No source in GStreamer pipeline. Ignore

    ***** Failed to open videowriter *****

这个版本的opencv 4.3.0是使用gstreamer支持从源代码编译而来。 cv::getBuildInformation()输出:

    Video I/O:
      DC1394: NO
      FFMPEG: YES (prebuilt binaries)
        avcodec: YES (58.54.100)
        avformat: YES (58.29.100)
        avutil: YES (56.31.100)
        swscale: YES (5.5.100)
        avresample: YES (4.0.0)
      GStreamer: YES (1.16.2)
      DirectShow: YES
      Media Foundation: YES
        DXVA: YES

如何流式传输?VideoWriter需要指定哪些参数?我尝试了谷歌上的各种提示,但都没有帮助。请提供一个简单的示例,展示如何从一侧使用VideoWriter发送流并从另一侧使用VideoCapture接收流。我使用的是Windows 10 x64和Qt5.13 MSVC2017。

2个回答

2

您需要将原始视频输入到appsrc中。将fourcc设置为h264会强制VideoWriter对视频进行编码,而不是使用gstreamer管道。您可以将fourcc设置为0以推送原始视频。以下内容应该有效。

cv::VideoWriter out;
out.open ("appsrc ! videoconvert ! x264enc tune=zerolatency bitrate=500 speed-preset=superfast ! rtph264pay ! udpsink host=127.0.0.1 port=5000",
    cv::CAP_GSTREAMER,
    0,
    16,
    cv::Size (640, 480),
    true);

谢谢您的提示,但是这并没有帮助。我仍然遇到相同的错误。 - WinterMax
你会在接收电脑上使用什么管道来播放这个? - Drew
gst-launch-1.0 udpsrc port=5000 ! application/x-rtp, encoding-name=H264, payload=96 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink应该接收到这个。 - Alper Kucukkomurler

0

我相信这是OpenCV的一个漏洞,应该通过此PR修复,或者也许这个PR(或者两者都可能)。

实际上,似乎OpenCV代码曾经可以与某个版本的GStreamer一起使用,该版本在函数成功时将错误指针设置为NULL,但根据我的经验(以及文档),这不能保证在1.16.2中实现。

有了这些PR,它应该正确地使用返回值,而不是依赖于错误指针的状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接