Потоковое видео h264 с артефактами opencv + gstreamer - PullRequest
0 голосов
/ 20 июня 2020

Вот уже несколько недель я пытаюсь транслировать видео в формате h264 по сети с помощью opencv и gstreamer, но постоянно сталкиваюсь с проблемами. Я написал простой сервер, который захватывает кадры с веб-камеры или из файла и отправляет их по сети. И клиент, снимающий видео.

Server.py

import cv2

PIPELINE = 'appsrc ! videoconvert ! x264enc tune=zerolatency speed-preset=fast ! rtph264pay ! udpsink host=192.168.0.171 port=5004'
cap_send = cv2.VideoCapture(0)
frame_size = (1280, 720)
out_send = cv2.VideoWriter(PIPELINE, cv2.CAP_GSTREAMER, 0, 16, frame_size, True)    

while True:
    ret, frame = cap_send.read()
    frame = cv2.resize(frame, frame_size)
    out_send.write(frame)
    cv2.imshow('send', frame)
    if cv2.waitKey(1) == 27:
        break

Client.py

import cv2

PIPELINE = 'udpsrc port=5004 caps = "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96" ! rtph264depay ! decodebin ! videoconvert ! appsink'
cap_receive = cv2.VideoCapture(PIPELINE, cv2.CAP_GSTREAMER)

while True:
    ret, frame = cap_receive.read()
    cv2.imshow('receive', frame)
    if cv2.waitKey(1) == 27:
        break


В итоге получаю глючное видео с артефактами. Примеры 1 , 2

Также в консоли выдает ошибку: cv::GStreamerCapture::open OpenCV | GStreamer warning: Cannot query video position: status=1, value=3, duration=-1

В чем проблема? Следует указать какие-то дополнительные параметры? Или у меня неправильная установка? Я пытался установить всевозможные параметры синхронизации, битрейта, предустановки скорости и т. Д. c. но всегда получаю искалеченное видео.

Я также заметил, что если вы попробуете сначала Client.py, то Server.py у меня будет нормальное видео, которое через некоторое время тоже станет искаженным

1 Ответ

0 голосов
/ 23 июня 2020

Здесь несколько вещей ..

  1. UDP подвержен потере пакетов. Таким образом, если соединение с потерями или вы слишком долго блокируете получающий поток, вы потеряете данные. Неполные данные означают битую картинку.

  2. Произвольный доступ. Если вы получаете поток, когда он уже запущен, вы пропускаете данные для правильного декодирования потока. Это будет восстановлено только после того, как вы получите точку синхронизации c (I-Frame).

...