Nowoczesny sposób przesyłania strumieniowego H.264 z kamery Raspberry Cam

16

Mam Pi B + i kamerę Pi i teraz próbuję znaleźć najbardziej wydajną konfigurację (niski procesor) i najniższe opóźnienie, aby przesyłać strumieniowo wideo zakodowane w H.264 z kamery na mój domowy serwer.

Przeczytałem następujące:

  1. http://pi.gbaman.info/?p=150

  2. http://blog.tkjelectronics.dk/2013/06/how-to-stream-video-and-audio-from-a-raspberry-pi-with-no-latency/comment-page-1/#comments

  3. http://www.raspberrypi.org/forums/viewtopic.php?p=464522

(Wszystkie linki używają gstreamer-1.0 z deb http://vontaene.de/raspbian-updates/ . main.)

W ostatnich latach wiele zrobiono w tym zakresie.

Początkowo musieliśmy przesyłać dane wyjściowe raspividdo gst-launch-1.0(patrz link 1).

Następnie (link 2) został utworzony oficjalny sterownik V4L2, który jest teraz standardem i pozwala na bezpośrednie uzyskiwanie danych bez potoku, przy użyciu tylko gstreamer (patrz zwłaszcza post przez towolf »Sat Dec 07, 2013 3:34 pm w linku 2):

Nadawca (Pi): gst-launch-1.0 -e v4l2src do-timestamp=true ! video/x-h264,width=640,height=480,framerate=30/1 ! h264parse ! rtph264pay config-interval=1 ! gdppay ! udpsink host=192.168.178.20 port=5000

Odbiorca: gst-launch-1.0 -v udpsrc port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! fpsdisplaysink sync=false text-overlay=false

Jeśli dobrze rozumiem, oba sposoby wykorzystują GPU do dekodowania H264, ale ten ostatni jest nieco bardziej wydajny, ponieważ nie musi przechodzić przez jądro innym razem, ponieważ nie ma potoku między zaangażowanymi procesami.


Teraz mam kilka pytań na ten temat.

  1. Czy ten ostatni jest wciąż najnowszym sposobem na efektywne pobieranie H264 z aparatu? Czytałem o tym gst-omx, co pozwala na takie rurociągi gstreamer ... video/x-raw ! omxh264enc ! .... Czy to robi coś innego niż tylko używanie video/x-h264, czy może nawet jest bardziej wydajne? Co za różnica?

  2. Jak dowiedzieć się, jaka wtyczka kodująca gstreamer jest faktycznie używana, gdy korzystam z video/x-h264 ...potoku? Wydaje się, że to tylko określenie pożądanego formatu w porównaniu z innymi częściami potoku, w których wyraźnie nazywam składnik (kod) (jak h264parselub fpsdisplaysink).

  3. W tej odpowiedzi do linku 1 Mikael Lepistö wspomina: „Usunąłem jedno niepotrzebne hasło filtru ze strony przesyłania strumieniowego” , co oznacza, że ​​wyciął gdppayi gdpdepay. Co oni robią? Dlaczego są potrzebne? Czy naprawdę mogę je zdjąć?

  4. Wspomina również, że określając caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96"parametry po udpsrcstronie odbierającej, może rozpocząć / wznowić transmisję strumieniową w środku strumienia. Co osiągają te ograniczenia, dlaczego te konkretne wybory, gdzie mogę przeczytać o nich więcej?

  5. Kiedy robię to, co sugeruję w pytaniach 3 i 4 (dodawanie caps, upuszczanie gdppayi gdpdepay), wtedy moje opóźnienie wideo staje się znacznie gorsze (i wydaje się, że się kumuluje, opóźnienie wzrasta z czasem, a po kilku minutach wideo zatrzymuje się)! Dlaczego tak może być? Chciałbym uzyskać opóźnienie uzyskane dzięki oryginalnemu poleceniu, ale mam również możliwość dołączenia do strumienia w dowolnym momencie.

  6. Czytałem, że RTSP + RTP zwykle używają kombinacji TCP i UDP: TCP do komunikatów kontrolnych i innych rzeczy, których nie można zgubić, oraz UDP do rzeczywistej transmisji danych wideo. Czy w powyższych konfiguracjach faktycznie tego używam, czy tylko używam tylko UDP? Nie jest dla mnie jasne, czy gstreamer się tym zajmuje, czy nie.

Byłbym wdzięczny za odpowiedź na choćby jedno z tych pytań!

nh2
źródło
Pomysł, że korzystanie z potoku |stwarza jakiekolwiek problemy w tym kontekście, jest niesamowitym kawałkiem BS. Czy próbowałeś już jakichś raspivid | cvlcmetod? Nie miałem kamery zbyt długo lub zbyt długo, żeby się nią bawić, ale używanie jej do tworzenia strumienia http (widocznego na linuksie na drugim końcu w / vlc) wydaje się działać dobrze.
Złotowłosa
@Goldilocks Nie mówię, że potok jest „problemem”, tylko że nie jest konieczny i ma pewne obciążenie, tak jak cat file | grep ...zamiast grep ... file. Rura dodaje kolejną warstwę kopiowania do iz jądra, którą można łatwo zmierzyć, szczególnie na urządzeniach o niskiej przepustowości pamięci. Jeśli gstreamer może bezpośrednio odczytać z pliku urządzenia, dlaczego tego nie użyć? Jeśli chodzi o twoją raspivid | cvlcsugestię: korzystałem z tego, zanim przełączyłem się na rozwiązanie oparte na gstreamer, ma ono do 3 sekund dłuższe opóźnienie niż gstreamer (nie wiem dlaczego).
nh2
Tak, zdecydowanie ma pewne opóźnienia. WRT potoku, chodzi mi o „kontekst”, że nie może to być tutaj wąskie gardło - sieciowe operacje wejścia / wyjścia będą o rząd wielkości wolniejsze itp. Masz rację, ale może to trochę dodać procesora czas. Po prostu nie postawiłbym wiele; uruchomienie tej w pełnej rozdzielczości cvlczużywa ~ 45%, ale samo przepuszczenie przez rurkę z tą szybkością danych (pamiętając, że rura nie spowalnia ) ledwo poruszyłoby igłę, tak myślę. Jak <5%. Oczywiście nie jest to zupełnie nieistotne, jeśli chcesz to zrobić tak skutecznie, jak to możliwe, oczywiście ...
goldilocks
... Po prostu nie chcę, aby ktokolwiek czytał to, aby miał wrażenie, że użycie potoku tutaj może być odpowiedzialne za problemy z opóźnieniami lub inne problemy. To czerwony śledź. Albo mogę się mylić;)
złotowłosy
Jeśli zależy Ci na wydajności, możesz uwzględnić obserwowane całkowite użycie procesora dla różnych metod przy określonej rozdzielczości / liczbie klatek na sekundę. Jedyny, którego próbowałem, to ten, raspivid | cvlcktóry wynosi 40-50%. Ludzie mogą lepiej odpowiadać na pytania, które zmuszają ich do poprawy konkretnej liczby. W tej chwili zadajesz wiele pytań, nie wyjaśniając, dlaczego każdy z nich jest istotny.
złotowłosy

Odpowiedzi:

8

Opcje:

  1. raspivid -t 0 -o - | nc -k -l 1234

  2. raspivid -t 0 -o - | cvlc stream:///dev/stdin --sout "#rtp{sdp=rtsp://:1234/}" :demux=h264

  3. cvlc v4l2:///dev/video0 --v4l2-chroma h264 --sout '#rtp{sdp=rtsp://:8554/}'

  4. raspivid -t 0 -o - | gst-launch-1.0 fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=SERVER_IP port=1234

  5. gst-launch-1.0 -e v4l2src do-timestamp=true ! video/x-h264,width=640,height=480,framerate=30/1 ! h264parse ! rtph264pay config-interval=1 ! gdppay ! udpsink host=SERVER_IP port=1234

  6. uv4l --driver raspicam

  7. picam --alsadev hw:1,0

Rzeczy do rozważenia

  • opóźnienie [ms] (zi bez pytania klienta, aby chciał więcej fps niż serwer)
  • Bezczynność procesora [%] (mierzona przez top -d 10)
  • Klient CPU 1 [%]
  • RAM [MB] (RES)
  • te same ustawienia kodowania
  • te same funkcje
    • audio
    • na nowo połączyć
    • Klient niezależny od systemu operacyjnego (vlc, webrtc itp.)

Porównanie:

            1    2    3    4    5    6    7
latency     2000 5000 ?    ?    ?    ?    1300
CPU         ?    1.4  ?    ?    ?    ?    ?
CPU 1       ?    1.8  ?    ?    ?    ?    ?
RAM         ?    14   ?    ?    ?    ?    ?
encoding    ?    ?    ?    ?    ?    ?    ?
audio       n    ?    ?    ?    ?    y    ?
reconnect   y    y    ?    ?    ?    y    ?
any OS      n    y    ?    ?    ?    y    ?
latency fps ?    ?    ?    ?    ?    ?    ?
wersji użytkownik1133275
źródło
1
Dlaczego wszystkie wartości w tej tabeli „ ?”?
larsks
@larsks, ponieważ nikomu nie zależy na testowaniu i wypełnianiu danych na tej „wiki społeczności”
user1133275,
6

Tylko nowoczesny sposób, aby strumień H264 do przeglądarki jest z UV4L : brak opóźnienia, brak konfiguracji z opcjonalnym dźwiękiem, opcjonalnie dwukierunkowe audio / wideo. Bez magicznego sosu GStreamer, ale można rozszerzyć jego użycie.

prinxis
źródło
Ponieważ chcę przesyłać strumieniowo na mój serwer i potencjalnie smartfony, przesyłanie strumieniowe do przeglądarki nie jest wymagane. Ponadto przeglądarka może nałożyć na to dodatkowe ograniczenia (np. Brak RTSP, potencjalnie brak TCP, chyba że użyjesz WebRTC, ale to dziwne). Ale UV4L nadal wygląda obiecująco. Czy możesz podać link do miejsca, w którym mogę poczytać o tym, jak z niego korzystać / uzyskać z niego dane do przesyłania strumieniowego przez sieć?
nh2
Święta krowa, myślę, że znalazłem przykładową stronę ... wydaje się, że ta rzecz jest w stanie zrobić wszystko ! RTMP, RTSP, HTTPS streaming, WebRTC, „Wykrywanie obiektów w czasie rzeczywistym i śledzenie obiektów + wykrywanie twarzy” - co do cholery? Każdy z kilkoma prostymi flagami wiersza poleceń do uv4l? Mój potok gstreamer wygląda teraz dość przestarzały! Nie mogę się doczekać, aby sprawdzić, jak opóźnienie!
nh2
1
O nie, to jest zamknięte źródło :( To dyskwalifikuje go do użytku w monitoringu domowym, o którym myślałem :(
nh2
obsługuje WebRTC, dwukierunkowy WebRTC. opóźnienie wynosi ~
200 ms
@ nh2, link wydaje się być uszkodzony, czy masz zaktualizowaną lokalizację dla tej przykładowej strony?
Punit Soni,
1

1.) Przesyłanie strumieniowe h264es przez sieć (tylko próbka)

na serwerze:

raspivid -v -a 524 -a 4 -a "rpi-0 %Y-%m-%d %X" -fps 15 -n -md 2 -ih -t 0 -l -o tcp://0.0.0.0:5001

na kliencie:

mplayer -nostop-xscreensaver -nolirc -fps 15 -vo xv -vf rotate=2,screenshot -xy 1200 -demuxer h264es ffmpeg://tcp://<rpi-ip-address>:5001

2.) Streaming mjpeg w sieci (tylko próbka)

na serwerze:

/usr/local/bin/mjpg_streamer -o output_http.so -w ./www -i input_raspicam.so -x 1920 -y 1440 -fps 3

na kliencie:

mplayer -nostop-xscreensaver -nolirc -fps 15 -vo xv -vf rotate=2,screenshot -xy 1200 -demuxer lavf http://<rpi-ip-address>:8080/?action=stream

wszystko to działa nawet na RPi Zero W (skonfigurowanym jako serwer)

sparkie
źródło
Hej, dziękuję za odpowiedź, co to sample onlyznaczy?
nh2
Chciałem powiedzieć „to tylko przykład”. Możesz dostosować to do swoich potrzeb.
sparkie