在imx6板上处理视频和传输的最佳方法是什么?

时间:2018-11-15 23:54:04

标签: opencv video gstreamer yocto imx6

最近,我正在尝试使用带有imx6处理器和MIPI-CSI摄像机的主板来传输视频。

我们的目标是通过RTP协议传输视频(1920x1080 @ 30fps),我们使用gstreamer管道进行了传输。要传输的命令管道为:

gst-launch-1.0 imxv4l2videosrc device=/dev/video1 imx-capture-mode=2 ! imxvpuenc_h264 quant-param=29 ! rtph264pay mtu=60000 ! udpsink host=10.42.0.1 port=5000 sync=false

该命令以1920x108的分辨率(imx-capture-mode = 2参数)传输视频。

然后从PC(10.42.0.1)使用以下命令捕获视频(端口5000):

gst-launch-1.0 -v udpsrc port=5000 ! application/x-rtp, media=video, clock-rate=90000, encoding-name=H264, payload=96 !  rtph264depay ! avdec_h264 ! fpsdisplaysink text-overlay=false sync=false &

视频流很好。

但是现在,我们要在视频传输之前对其进行处理,因为相机在运动中,我们需要添加一些算法来减少由于抖动而产生的噪声。

换句话说,主要思想是:从摄像机获取视频->处理视频->传输到RTP。所有这些都使用带有imx6的开发板。

该开发板基于linux yocto项目,并且具有启用了gstreamer插件的opencv 3.1。我们的想法是使用opencv和gstreamer管道来拍摄视频,进行处理并传输...但是首先,我们进行了一些测试,以获取视频并在不进行处理的情况下进行传输,但是当我们从PC捕获视频时,它非常慢并延迟...

我们想知道这是否是实现我们目标的正确方法。这是我们正在使用的源代码:

#include <QCoreApplication>
#include <QDebug>
#include <opencv2/opencv.hpp>
#include <opencv2/video.hpp>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    cv::VideoCapture cap("imxv4l2videosrc device=/dev/video1 imx-capture-mode=2 ! videoconvert ! appsink");
    Q_ASSERT(cap.isOpened());
    if(!cap.isOpened())
    {
        qDebug() << "Error with the video capturer";
        a.exit(-1);
    }
    cv::Mat frame;
    cap >> frame; //Dummy read
    double frame_width=   cap.get(CV_CAP_PROP_FRAME_WIDTH);
    double frame_height=   cap.get(CV_CAP_PROP_FRAME_HEIGHT);

    cv::VideoWriter writer;
    writer.open("appsrc ! videoconvert ! imxvpuenc_h264 quant-param=29 ! rtph264pay mtu=60000 ! udpsink host=10.42.0.1 port=5000 sync=false",
                0,30,cv::Size(frame_width,frame_height));
    if(!writer.isOpened())
    {
        qDebug() << "Error video writer";
        a.exit(-1);
    }

    while(true) {

            cap.read(frame);

            if(frame.empty())
                break;

            writer.write(frame);
            cv::waitKey(33);
        }

    return a.exec();
}

1 个答案:

答案 0 :(得分:0)

我猜测您的视频变慢的原因是视频格式转换。 OpenCv从gstreamer BGR元素获取appsink格式的视频。如果您的imxv4l2videosrc输出其他格式(例如UYVYI420),则videoconvert元素将需要进行大量计算。在某些情况下,这些计算会占用您100%以上的CPU,这会减慢您的输入流。

您可以通过在管道末尾添加-v来检查原始管道正在使用的格式。

gst-launch-1.0 imxv4l2videosrc device=/dev/video1 imx-capture-mode=2 ! imxvpuenc_h264 quant-param=29 ! rtph264pay mtu=60000 ! udpsink host=10.42.0.1 port=5000 sync=false -v

我们可以通过减少资源浪费来测试视频转换是否会减慢您的系统速度。您是否可以通过将资源降低到1280x720640x360来重试,并检查CPU使用率?

在这种情况下,我们可以请求来自imxv4l2videosrc的不同格式的输出。我没有使用该元素,我也不知道它的功能。但是您可以使用gst-inspect-1.0命令检查功能。

gst-inspect-1.0 imxv4l2videosrc

输出将具有这样的部分

Pad Templates:
  SRC template: 'src'
    Availability: Always
    Capabilities:

      video/x-raw
                 format: { (string)RGB16, (string)BGR, (string)RGB, (string)GRAY8, (string)GRAY16_LE, (string)GRAY16_BE, (string)YVU9, (string)YV12, (string)YUY2, (string)YVYU, (string)UYVY, (string)Y42B, (string)Y41B, (string)YUV9, (string)NV12_64Z32, (string)NV24, (string)NV61, (string)NV16, (string)NV21, (string)NV12, (string)I420, (string)BGRA, (string)BGRx, (string)ARGB, (string)xRGB, (string)BGR15, (string)RGB15 }
                  width: [ 1, 32768 ]
                 height: [ 1, 32768 ]
              framerate: [ 0/1, 2147483647/1 ]

BGRx,“ RGB”或“ xRGB”等具有B,G和R通道的格式将对您有用且快捷。