Modo moderno per lo streaming di H.264 dalla Raspberry Cam


16

Ho ottenuto il Pi B + e la videocamera Pi e ora sto cercando di trovare la configurazione più efficiente (CPU bassa) e latenza più bassa per lo streaming di video con codifica H.264 dalla videocamera al mio server di casa.

Ho letto quanto segue:

  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

(Tutti i collegamenti usano gstreamer-1.0 da deb http://vontaene.de/raspbian-updates/ . main.)

Molto è stato fatto in questo senso negli ultimi anni.

Inizialmente, abbiamo dovuto reindirizzare l'output di raspividin gst-launch-1.0(vedi link 1).

Quindi (link 2) è stato creato il driver V4L2 ufficiale, che ora è standard, e consente di ottenere direttamente i dati senza pipe, usando solo gstreamer (vedi in particolare il post di towolf »sab 07 dic 2013 15:34 in link 2):

Mittente (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

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

Se ho capito bene, entrambi i modi usano la GPU per eseguire la decodifica H264, ma quest'ultima è un po 'più efficiente dal momento che non ha bisogno di passare attraverso il kernel un'altra volta poiché non c'è pipe tra i processi coinvolti.


Ora ho alcune domande a riguardo.

  1. Quest'ultimo è ancora il modo più recente per ottenere in modo efficiente H264 dalla fotocamera? Ho letto gst-omx, che consente pipeline gstreamer come ... video/x-raw ! omxh264enc ! .... Questo fa qualcosa di diverso dal solo utilizzo video/x-h264o potrebbe anche essere più efficiente? Qual è la differenza?

  2. Come faccio a sapere quale plug-in di codifica gstreamer viene effettivamente utilizzato quando utilizzo la video/x-h264 ...pipeline? Questo sembra solo specificare il formato che desidero, rispetto alle altre parti della pipeline, dove chiamo esplicitamente il componente (codice) (come h264parseo fpsdisplaysink).

  3. In questa risposta al collegamento 1 Mikael Lepistö menziona "Ho rimosso un passaggio filtro non necessario dal lato streaming" , il che significa che ha eliminato il gdppaye gdpdepay. Cosa fanno quelli? Perché sono necessari? Posso davvero toglierli?

  4. Egli menziona anche che specificando i caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96"parametri per il udpsrclato ricevente, è in grado di avviare / riprendere lo streaming nel mezzo del flusso. Cosa ottengono questi tappi, perché queste scelte specifiche, dove posso leggere di più su di loro?

  5. Quando faccio quanto suggerito nelle domande 3 e 4 (aggiungendo caps, rilasciando gdppaye gdpdepay) la mia latenza video peggiora (e sembra accumularsi, la latenza aumenta nel tempo e dopo pochi minuti il ​​video si interrompe)! Perché potrebbe essere? Vorrei ottenere la latenza ottenuta con il comando originale, ma ho anche la caratteristica di poter unire il flusso in qualsiasi momento.

  6. Ho letto che RTSP + RTP di solito usano una combinazione di TCP e UDP: TCP per i messaggi di controllo e altre cose che non devono perdersi e UDP per la trasmissione effettiva dei dati video. Nelle configurazioni sopra, lo sto effettivamente usando o sto solo usando UDP? È un po 'opaco per me se gstreamer se ne occupi o no.

Gradirei qualsiasi risposta anche a una sola di queste domande!


L'idea che l'uso di una pipe |crei problemi in questo contesto è un incredibile pezzo di BS Hai provato qualche raspivid | cvlcmetodo? Non ho avuto la fotocamera per molto o troppo tempo per giocarci, ma usarlo per produrre un flusso http (visualizzabile su Linux dall'altra parte w / vlc) sembra funzionare bene.
riccioli d'oro

@goldilocks Non sto dicendo che il tubo sia un "problema", solo che non è necessario e ha un certo sovraccarico, proprio come cat file | grep ...invece di grep ... file. La pipe aggiunge un altro livello di copia da e verso il kernel, che è facilmente misurabile, specialmente su dispositivi con larghezza di banda di memoria ridotta. Se gstreamer è in grado di leggere direttamente dal file del dispositivo, perché non utilizzarlo? Per quanto riguarda il tuoraspivid | cvlc suggerimento: lo stavo usando prima di passare alla soluzione basata su gstreamer, ha una latenza fino a 3 secondi in più rispetto a gstreamer (non so perché).
nh2,

Sì, ha sicuramente un po 'di latenza. WRT la pipa, il mio punto sul "contesto" è che questo non può essere un collo di bottiglia qui - l'I / O di rete sarà più lento di ordini di grandezza, ecc. Hai ragione, tuttavia, potrebbe aggiungere un po 'alla CPU tempo. Scommetto che non scommetterei molto; eseguendolo alla massima risoluzione, cvlcusa ~ 45%, ma semplicemente scorrendo un tubo a quella velocità di dati (tenendo presente di nuovo, il tubo non lo sta rallentando ), a mala pena spostare l'ago, penso. Come <5%. Non è del tutto insignificante se vuoi farlo nel modo più efficiente possibile ovviamente ...
goldilocks

... Non voglio che nessun altro legga questo per avere l'impressione che l'uso di una pipe qui possa essere responsabile di problemi di latenza o di altri problemi. È un'aringa rossa. O potrei sbagliarmi;)
Riccioli d'oro

Se è l'efficienza che stai cercando, potresti voler includere l'utilizzo totale osservato della CPU per vari metodi a risoluzione / frame rate specifici. L'unico che ho provato è raspivid | cvlcquello del 40-50%. Le persone possono rispondere meglio a una domanda che li sfida a migliorare su una figura specifica. In questo momento stai chiedendo molto perché, senza spiegare perché ognuno dei quali è significativo.
riccioli d'oro

Risposte:


8

Le opzioni:

  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

Cose da considerare

  • latenza [ms] (con e senza chiedere al client di desiderare più fps del server)
  • CPU inattiva [%] (misurata da top -d 10)
  • Client CPU 1 [%]
  • RAM [MB] (RES)
  • stesse impostazioni di codifica
  • stesse caratteristiche
    • Audio
    • riconnessione
    • Client indipendente dal sistema operativo (vlc, webrtc, ecc.)

Confronto:

            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 ?    ?    ?    ?    ?    ?    ?

1
Perché tutti i valori in questa tabella " ?"?
Larks

@larsks perché nessuno si preoccupa di testare e compilare i dati su questo 'wiki della community'
user1133275

6

L' unico modo moderno per trasmettere H264 a un browser è con UV4L : nessuna latenza, nessuna configurazione, con audio opzionale, audio / video bidirezionale opzionale. Nessuna salsa magica GStreamer, ma è possibile estenderne l'utilizzo.


Dal momento che voglio eseguire lo streaming sul mio server e potenzialmente smartphone, lo streaming su un browser non è un requisito. Inoltre, il browser potrebbe porre ulteriori restrizioni su di esso (ad es. Senza RTSP, potenzialmente senza TCP a meno che non si utilizzi WebRTC, ma questo è complicato). Ma UV4L sembra ancora promettente. Potresti collegarti a un posto dove posso leggere su come usarlo / estrarre i dati per lo streaming sulla rete?
nh2,

Santa mucca, penso di aver trovato la pagina di esempio ... questa cosa sembra essere in grado di fare tutto ! RTMP, RTSP, streaming HTTPS, WebRTC, "Rilevamento oggetti in tempo reale e rilevamento oggetti + Rilevamento volti" - che diavolo ?? Ognuno con alcuni semplici flag da riga di comando a uv4l? La mia pipeline gstreamer sembra piuttosto obsoleta ora! Non vedo l'ora di testare la latenza!
nh2,

1
Oh no, è una fonte chiusa :( Questo lo squalifica per l'uso della sorveglianza domestica che avevo in mente :(
nh2

supporta WebRTC, WebRTC a 2 vie. la latenza è ~ 200ms audio / video, audio meno probabilmente
prinxis

@ nh2, il collegamento sembra interrotto, hai qualche posizione aggiornata per quella pagina di esempio?
Punit Soni,

1

1.) streaming h264es attraverso la rete (solo campione)

sul server:

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

sul cliente:

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 attraverso la rete (solo campione)

sul server:

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

sul cliente:

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

tutto questo funziona anche su un RPi Zero W (configurato come server)


Ehi, grazie per la tua risposta, cosa sample onlysignifica?
nh2

Volevo dire "è solo un esempio". Puoi adattarlo alle tue esigenze.
Sparkie,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.