如何将 Opencv VideoWriter 与 GStreamer 一起使用?

Posted

技术标签:

【中文标题】如何将 Opencv VideoWriter 与 GStreamer 一起使用?【英文标题】:How to use Opencv VideoWriter with GStreamer? 【发布时间】:2020-04-23 18:45:55 【问题描述】:

我正在尝试使用 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

【问题讨论】:

【参考方案1】:

您需要将原始视频提供给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);

【讨论】:

感谢您的提示,但这无济于事。我得到同样的错误 你会在接收计算机上使用什么管道来播放这个? gst-launch-1.0 udpsrc port=5000 ! application/x-rtp, encoding-name=H264, payload=96 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink 应该会收到这个。【参考方案2】:

我认为这是 OpenCV 中的一个错误,应该由this PR 或this one(或两者兼有)修复。

确实,OpenCV 代码似乎曾经与某些版本的 GStreamer 一起工作,当函数成功时会将错误指针设置为 NULL,但根据我的经验(以及从文档)。

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

【讨论】:

以上是关于如何将 Opencv VideoWriter 与 GStreamer 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV VideoWriter 帧率问题

如何捕获 OpenCV 写入 stderr 的消息?

opencv-videowriter

23 视频处理与保存

OpenCV:来自 VideoWriter 的写入是不是应该在独立线程中运行?

无法在 iOS 10 上使用 OpenCV 3.1 使用 VideoWriter 创建文件