Cara modern untuk streaming H.264 dari Raspberry Cam

16

Saya mendapatkan Pi B + dan kamera Pi dan sekarang saya mencoba menemukan konfigurasi (CPU rendah) yang paling efisien dan terendah untuk mengalirkan video yang dikodekan H.264 dari kamera ke server rumah saya.

Saya sudah membaca yang berikut ini:

  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

(Semua tautan menggunakan gstreamer-1.0 dari deb http://vontaene.de/raspbian-updates/ . main.)

Banyak yang telah dilakukan dalam hal ini dalam beberapa tahun terakhir.

Awalnya, kami harus menyalurkan output raspividke gst-launch-1.0(lihat tautan 1).

Kemudian (tautan 2) dibuat driver V4L2 resmi yang sekarang menjadi standar, dan memungkinkan untuk secara langsung mendapatkan data tanpa pipa, menggunakan hanya gstreamer (lihat terutama pos oleh towolf »Sat 07 Des 2013, 3:34 pm dalam tautan 2):

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

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

Jika saya mengerti dengan benar, kedua cara menggunakan GPU untuk melakukan decoding H264, tetapi yang kedua agak lebih efisien karena tidak perlu melalui kernel lain kali karena tidak ada pipa antara proses yang terlibat.


Sekarang saya punya beberapa pertanyaan tentang ini.

  1. Apakah yang terakhir masih merupakan cara terbaru untuk mendapatkan H264 dari kamera secara efisien? Saya pernah membaca tentang gst-omx, yang memungkinkan saluran pipa gstreamer seperti ... video/x-raw ! omxh264enc ! .... Apakah ini melakukan sesuatu yang berbeda dengan hanya menggunakan video/x-h264, atau bahkan mungkin lebih efisien? Apa bedanya?

  2. Bagaimana cara mengetahui plugin encoding gstreamer apa yang sebenarnya digunakan ketika saya menggunakan video/x-h264 ...pipeline? Ini tampaknya hanya menentukan format yang saya inginkan, dibandingkan dengan bagian pipa lainnya, di mana saya secara eksplisit memberi nama komponen (kode) (suka h264parseatau fpsdisplaysink).

  3. Dalam balasan ini untuk menghubungkan 1 Mikael Lepistö menyebutkan "Saya menghapus satu pass filter yang tidak perlu dari sisi streaming" , yang berarti bahwa ia memotong gdppaydan gdpdepay. Apa yang mereka lakukan? Mengapa mereka dibutuhkan? Bisakah saya benar-benar menanggalkannya?

  4. Dia juga menyebutkan bahwa dengan menentukan caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96"parameter untuk udpsrcdi sisi penerima, dia dapat memulai / melanjutkan streaming di tengah aliran. Apa yang dicapai topi ini, mengapa pilihan spesifik ini, di mana saya dapat membaca lebih banyak tentang mereka?

  5. Ketika saya melakukan apa yang disarankan di pertanyaan 3 dan 4 (menambahkan caps, menjatuhkan, gdppaydan gdpdepay) maka latensi video saya menjadi jauh lebih buruk (dan tampaknya terakumulasi, latensi meningkat seiring waktu, dan setelah beberapa menit video berhenti)! Kenapa bisa begitu? Saya ingin mendapatkan latensi yang saya peroleh dengan perintah asli, tetapi juga memiliki fitur untuk dapat bergabung dengan aliran kapan saja.

  6. Saya telah membaca bahwa RTSP + RTP biasanya menggunakan kombinasi TCP dan UDP: TCP untuk pesan kontrol dan hal-hal lain yang tidak boleh hilang, dan UDP untuk transmisi data video aktual. Pada pengaturan di atas, apakah saya benar-benar menggunakan itu, atau apakah saya hanya menggunakan UDP saja? Ini agak buram bagi saya apakah Gstreamer menangani ini atau tidak.

Saya akan menghargai jawaban apa pun untuk satu pun dari pertanyaan ini!

nh2
sumber
Gagasan bahwa menggunakan pipa |menciptakan masalah dalam konteks ini adalah bagian yang luar biasa dari BS. Sudahkah Anda mencoba raspivid | cvlcmetode apa pun ? Saya belum punya kamera untuk waktu yang sangat lama atau banyak waktu untuk bermain dengannya, tetapi menggunakannya untuk menghasilkan aliran http (dapat dilihat di linux di ujung w / vlc) tampaknya bekerja dengan baik.
goldilocks
@ Goldilocks Saya tidak mengatakan bahwa pipa adalah "masalah", hanya saja itu tidak perlu dan memiliki beberapa overhead, sama seperti cat file | grep ...bukan grep ... file. Pipa menambahkan lapisan lain penyalinan ke dan dari kernel, yang mudah diukur, terutama pada perangkat dengan bandwidth memori rendah. Jika gstreamer dapat membaca dari file perangkat secara langsung, mengapa tidak menggunakannya? Mengenai raspivid | cvlcsaran Anda : Saya menggunakan ini sebelum saya beralih ke solusi berbasis gstreamer, ia memiliki latensi hingga 3 detik lebih banyak daripada gstreamer (saya tidak tahu mengapa).
nh2
Ya pasti memiliki beberapa latensi. WRT pipa, poin saya tentang "konteks" adalah bahwa ini tidak mungkin menjadi hambatan di sini - jaringan I / O akan menjadi pesanan dengan magnitude lebih lambat, dll. Anda benar, meskipun, itu mungkin menambahkan sedikit ke CPU waktu. Aku hanya bertaruh tidak banyak; menjalankan itu pada resolusi penuh, cvlcmenggunakan ~ 45%, tetapi hanya berjalan melalui pipa pada kecepatan data itu (ingat lagi, pipa tidak memperlambatnya ) tidak akan menggerakkan jarum, saya pikir. Suka <5%. Tidak sepenuhnya sepele jika Anda ingin melakukan ini seefisien mungkin tentu saja ...
goldilocks
... Saya hanya tidak ingin orang lain membaca ini untuk mendapatkan kesan bahwa menggunakan pipa di sini mungkin bertanggung jawab atas masalah latensi atau masalah lainnya. Itu ikan haring merah. Atau saya bisa saja salah;)
goldilocks
Jika efisiensi yang Anda cari, Anda mungkin ingin memasukkan total penggunaan CPU yang diamati untuk berbagai metode pada tingkat resolusi / frame tertentu. Satu-satunya yang saya coba adalah raspivid | cvlcyang 40-50%. Orang-orang mungkin merespons dengan lebih baik pertanyaan yang menantang mereka untuk memperbaiki angka tertentu. Saat ini Anda banyak bertanya mengapa, tanpa menjelaskan mengapa masing-masing alasan itu penting.
goldilocks

Jawaban:

8

Opsi:

  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

Hal-hal yang perlu dipertimbangkan

  • latency [ms] (dengan dan tanpa meminta klien menginginkan lebih banyak fps daripada server)
  • CPU idle [%] (diukur dengan top -d 10)
  • Klien CPU 1 [%]
  • RAM [MB] (RES)
  • pengaturan penyandian yang sama
  • fitur yang sama
    • audio
    • terhubung kembali
    • Klien independen OS (vlc, webrtc, dll)

Perbandingan:

            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 ?    ?    ?    ?    ?    ?    ?
user1133275
sumber
1
Mengapa semua nilai dalam tabel ini " ?"?
larsks
@ larsks karena tidak ada yang peduli untuk menguji dan mengisi data pada 'komunitas wiki' ini
user1133275
6

Satu- satunya cara modern untuk mengalirkan H264 ke browser adalah dengan UV4L : tidak ada latensi, tidak ada konfigurasi, dengan audio opsional, audio / video dua arah opsional. Tidak ada saus GStreamer ajaib, namun masih memungkinkan untuk memperpanjang penggunaannya.

prinxis
sumber
Karena saya ingin melakukan streaming ke server saya dan berpotensi smartphone, streaming ke browser bukan keharusan. Selain itu, peramban dapat memberikan batasan ekstra padanya (mis. Tidak ada RTSP, kemungkinan tidak ada TCP kecuali Anda menggunakan WebRTC, tapi itu sangat buruk). Namun UV4L masih terlihat menjanjikan. Bisakah Anda menautkan ke tempat di mana saya bisa membaca tentang cara menggunakannya / mendapatkan data dari itu untuk streaming melalui jaringan?
nh2
Astaga, kurasa aku menemukan halaman contoh ... benda ini sepertinya bisa melakukan semuanya ! RTMP, RTSP, streaming HTTPS, WebRTC, "Deteksi Objek Real-time dan Pelacakan Objek + Deteksi wajah" - apa-apaan ?? Masing-masing dengan beberapa flag baris perintah sederhana uv4l? Pipa gstreamer saya terlihat cukup usang sekarang! Tidak sabar untuk menguji bagaimana latensi itu!
nh2
1
Oh tidak, itu adalah sumber tertutup :( Itu mendiskualifikasi untuk penggunaan pengawasan rumah yang ada dalam pikiran saya :(
nh2
itu mendukung WebRTC, WebRTC 2 arah. latency ~ 200 ms audio / video, audio kurang mungkin
prinxis
@ nh2, tautannya tampaknya rusak, apakah Anda memiliki lokasi yang diperbarui untuk halaman contoh itu?
Punit Soni
1

1.) h264 streaming di seluruh jaringan (hanya sampel)

di 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

pada klien:

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 di seluruh jaringan (hanya sampel)

di server:

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

pada klien:

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

semua ini bahkan berfungsi pada RPi Zero W (dikonfigurasi sebagai server)

sparkie
sumber
Hei, terima kasih atas jawaban Anda, apa sample onlyartinya?
nh2
Saya ingin mengatakan 'ini hanya contoh'. Anda dapat menyesuaikan ini dengan kebutuhan Anda.
sparkie