Как лучше всего обрабатывать видео и передавать на плате imx6?

В последнее время пытаюсь использовать плату с процессором imx6 и камерой MIPI-CSI для передачи видео.

Наша цель — передать видео (1920x1080@30fps) по протоколу RTP, и мы сделали это с помощью конвейеров 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).

А с ПК (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.

Плата основана на проекте yocto для Linux и имеет opencv 3.1 с включенным плагином gstreamer. Наша идея состоит в том, чтобы взять видео с помощью конвейеров opencv и gstreamer, обработать и передать его... Но сначала мы сделали тест, взяв видео и передав его без обработки, но когда мы ловим видео с ПК, оно очень медленное. и задержался...

Мы хотим знать, является ли это правильным путем для достижения нашей цели. Вот исходный код, который мы используем:

#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();
}

person E. Vera    schedule 15.11.2018    source источник
comment
Привет @E.Vera 1- Не могли бы вы добавить версии gstreamer как на вашу плату, так и на ваш компьютер? 2- Когда вы используете top или htop, вы видите процесс, использующий более 100% процессора, с названием вашего приложения?   -  person Alper Kucukkomurler    schedule 18.11.2018
comment
Привет @AlperKucukkomurler, приносим извинения за задержку с ответом. Версии gstreamer: ПК: GStreamer 1.8.3 и плата: GStreamer 1.10.4. Да! вы правы, процесс использует более 100% до 150%. Ты знаешь почему? Это из-за версий gstreamer?   -  person E. Vera    schedule 20.11.2018
comment
Причина, по которой я спросил версию, заключается в том, что в gstreamer была ошибка с элементом udpsrc, что приводило к медленному воспроизведению. Однако, насколько я помню, это уже было решено в 1.8.3. Остальная часть моего комментария здесь не помещается, поэтому я отправляю его как ответ.   -  person Alper Kucukkomurler    schedule 22.11.2018


Ответы (1)


Я предполагаю, что причина того, что ваше видео замедляется, заключается в преобразовании видеоформата. OpenCv получает видео в формате BGR из элемента appsink gstreamer. Если ваш imxv4l2videosrc выводит другой формат (например, UYVY или I420), элементу videoconvert придется выполнять много вычислений. В некоторых случаях эти вычисления используют более 100% вашего ЦП, и это замедлит ваш входной поток.

Вы можете проверить, какой формат использует ваш исходный канал, добавив -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

Мы можем проверить, замедляет ли преобразование видео вашу систему, уменьшив разрешение. Можете ли вы попробовать еще раз, снизив разрешение до 1280x720 или 640x360, и проверить загрузку процессора?

Если это так, мы можем запросить вывод из 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, будут для вас полезными и быстрыми.

person Alper Kucukkomurler    schedule 22.11.2018