OpenCV 中 H.264 编码相机流的 GStreamer 管道存在问题

问题描述 投票:0回答:1

我对 GStreamer 管道相对较新,目前正在开发一项相机服务,需要使用 OpenCV 和 GStreamer 读取 H.264 编码的相机流。

以下 GStreamer 管道工作正常:

const char *pipeline_str = "v4l2src device=/dev/video0 ! videoconvert ! video/x-raw, width=640, height=480, framerate=30/1 ! x264enc ! h264parse ! avdec_h264 ! videoconvert ! appsink";
cv::VideoCapture cap(pipeline_str, cv::CAP_GSTREAMER);

if (!cap.isOpened()) {
    std::cerr << "Failed to open appsink as VideoCapture\n";
    return;
}

但是,当我尝试不使用 H.264 解码部分的类似管道时:

const char *pipeline_str = "v4l2src device=/dev/video0 ! videoconvert ! video/x-raw, width=640, height=480, framerate=30/1 ! x264enc ! h264parse ! appsink";
cv::VideoCapture cap(pipeline_str, cv::CAP_GSTREAMER);

if (!cap.isOpened()) {
    std::cerr << "Failed to open appsink as VideoCapture\n";
    return;
}

无法以VideoCapture方式打开appsink。我不确定非工作场景中编码流的问题是什么。

有人可以帮我理解为什么没有 H.264 解码的管道无法按预期工作吗?任何见解或建议将不胜感激。

c++ opencv gstreamer gstreamer-1.0
1个回答
0
投票

首先,让我区分原始视频和压缩视频(例如 h264)。描述很简单,但应该足以指出问题所在。 在原始视频中,每个视频帧都未经压缩地存储,以便每个像素存储一系列字节(RGB 或 BGR 帧每个像素 3 个字节,YUV 帧每个像素 2 个字节)。 对于压缩视频,视频帧被压缩到较低的内存,您需要一个编码器将其转换回原始视频。

让我们检查一下您的管道:

v4l2src device=/dev/video0 ! videoconvert ! video/x-raw, width=640, height=480, framerate=30/1
-->原始视频在这里

x264enc
--> h264 编码视频

h264parse ! avdec_h264
--> 再次原始视频

videoconvert ! appsink
--> 仍然原始视频

在第一个管道中,您将原始视频传递到 appsink,而在第二个管道中,您将压缩的 h264 视频数据。

VideoCapture
需要原始视频,这就是为什么它无法打开压缩视频帧。

我相信您正在尝试发送 h264 压缩数据并在 OpenCV 中读取它以进行进一步处理。如果是这样,您需要先使用

avdec_h264
进行解码。

© www.soinside.com 2019 - 2024. All rights reserved.