Cách hiện đại để truyền phát H.264 từ Raspberry Cam


16

Tôi đã nhận được Pi B + và máy ảnh Pi và hiện đang cố gắng tìm cấu hình hiệu quả nhất (CPU thấp) và độ trễ thấp nhất để truyền phát video được mã hóa H.264 từ máy ảnh đến máy chủ nhà của tôi.

Tôi đã đọc như sau:

  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

(Tất cả các liên kết sử dụng guxer-1.0 từ deb http://vontaene.de/raspbian-updates/ . main.)

Rất nhiều đã được thực hiện trong vấn đề này trong những năm qua.

Ban đầu, chúng tôi phải chuyển đầu ra raspividthành gst-launch-1.0(xem liên kết 1).

Sau đó (liên kết 2) trình điều khiển V4L2 chính thức đã được tạo, hiện đang là tiêu chuẩn và nó cho phép lấy trực tiếp dữ liệu mà không cần đường ống, chỉ sử dụng trình điều khiển (xem đặc biệt là bài đăng của Towolf »Sat Dec 07, 2013 3:34 chiều trong liên kết 2):

Người gửi (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

Người nhận: gst-launch-1.0 -v udpsrc port=5000 ! gdpdepay ! rtph264depay ! avdec_h264 ! fpsdisplaysink sync=false text-overlay=false

Nếu tôi hiểu chính xác, cả hai cách đều sử dụng GPU để thực hiện giải mã H264, nhưng cách thứ hai thì hơi hiệu quả vì nó không cần phải đi qua nhân vào lúc khác vì không có đường ống giữa các quá trình liên quan.


Bây giờ tôi có một số câu hỏi về điều này.

  1. Đây có phải là cách gần đây nhất để có được H264 hiệu quả từ máy ảnh không? Tôi đã đọc về gst-omx, cho phép các đường ống dẫn dòng như thế nào ... video/x-raw ! omxh264enc ! .... Điều này có làm gì khác với chỉ sử dụng video/x-h264, hoặc thậm chí có thể hiệu quả hơn? Có gì khác biệt?

  2. Làm cách nào để tìm hiểu plugin mã hóa guxer nào thực sự được sử dụng khi tôi sử dụng video/x-h264 ...đường ống dẫn? Điều này dường như chỉ là xác định định dạng tôi muốn, so với các phần đường ống khác, nơi tôi đặt tên rõ ràng thành phần (mã) (như h264parsehoặc fpsdisplaysink).

  3. Trong bài trả lời này cho liên kết 1 Mikael Lepistö có đề cập "Tôi đã xóa một bộ lọc không cần thiết từ phía phát trực tuyến" , nghĩa là anh ấy đã cắt bỏ gdppaygdpdepay. Những người đó làm gì? Tại sao họ cần? Tôi thực sự có thể lột chúng ra?

  4. Anh ta cũng đề cập rằng bằng cách chỉ định caps="application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, payload=(int)96"các tham số cho udpsrcphía nhận, anh ta có thể bắt đầu / tiếp tục phát trực tuyến ở giữa luồng. Những cái mũ này đạt được gì, tại sao những lựa chọn cụ thể này, tôi có thể đọc thêm về chúng ở đâu?

  5. Khi tôi thực hiện những gì được đề xuất trong câu hỏi 3 và 4 (thêm caps, giảm gdppaygdpdepay) thì độ trễ video của tôi trở nên tồi tệ hơn nhiều (và dường như được tích lũy, độ trễ tăng theo thời gian và sau vài phút video dừng lại)! Tại sao có thể như vậy? Tôi muốn nhận được độ trễ tôi nhận được bằng lệnh ban đầu, nhưng cũng có tính năng có thể tham gia luồng bất cứ lúc nào.

  6. Tôi đã đọc rằng RTSP + RTP thường sử dụng kết hợp TCP và UDP: TCP cho các thông điệp điều khiển và những thứ khác không bị mất và UDP để truyền dữ liệu video thực tế. Trong các thiết lập ở trên, tôi thực sự đang sử dụng nó hay tôi chỉ đang sử dụng UDP? Nó hơi mờ đối với tôi cho dù người quản lý có quan tâm đến việc này hay không.

Tôi sẽ đánh giá cao bất kỳ câu trả lời cho ngay cả một trong những câu hỏi này!


Ý tưởng rằng việc sử dụng một đường ống |tạo ra bất kỳ vấn đề nào trong bối cảnh này là một phần đáng kinh ngạc của BS Bạn đã thử raspivid | cvlcphương pháp nào chưa? Tôi đã không có máy ảnh trong một thời gian dài hoặc nhiều thời gian để chơi với nó, nhưng sử dụng nó để tạo ra một luồng http (có thể xem trên linux ở đầu kia w / vlc) có vẻ hoạt động tốt.
goldilocks

@goldilocks Tôi không nói rằng đường ống là một "vấn đề", chỉ là nó không cần thiết và có một số chi phí, giống như cat file | grep ...thay vì grep ... file. Ống thêm một lớp sao chép vào và từ kernel, có thể dễ dàng đo được, đặc biệt là trên các thiết bị có băng thông bộ nhớ thấp. Nếu guxer có thể đọc từ tập tin thiết bị direcly, tại sao không sử dụng nó? Về raspivid | cvlcđề xuất của bạn : Tôi đã sử dụng điều này trước khi tôi chuyển sang giải pháp dựa trên công cụ tìm kiếm, nó có độ trễ cao hơn tới 3 giây so với công cụ tìm kiếm (tôi không biết tại sao).
nh2

Vâng, nó chắc chắn có một số độ trễ. WRT the pipe, quan điểm của tôi về "bối cảnh" là điều này có thể không phải là nút cổ chai ở đây - I / O mạng sẽ là các đơn đặt hàng có cường độ chậm hơn, v.v. Tuy nhiên, bạn có thể thêm một chút vào CPU thời gian. Chỉ là tôi cá cược không nhiều; chạy ở độ phân giải đầy đủ, cvlcsử dụng ~ 45%, nhưng chỉ cần chạy qua một đường ống ở tốc độ dữ liệu đó (hãy nhớ lại, đường ống không làm chậm nó ) sẽ hầu như không di chuyển kim, tôi nghĩ vậy. Thích <5%. Nó không hoàn toàn không đáng kể nếu bạn muốn làm điều này một cách hiệu quả nhất có thể ...
goldilocks

... Tôi chỉ không muốn bất kỳ ai khác đọc điều này để có ấn tượng rằng việc sử dụng một đường ống ở đây có thể chịu trách nhiệm cho các vấn đề về độ trễ hoặc các vấn đề khác. Đó là cá trích đỏ. Hoặc tôi có thể sai;)
goldilocks

Nếu đó là hiệu quả mà bạn đang theo đuổi, bạn có thể muốn bao gồm tổng mức sử dụng CPU được quan sát cho các phương pháp khác nhau ở độ phân giải / khung hình cụ thể. Người duy nhất tôi đã thử là người raspivid | cvlcduy nhất và đó là 40-50%. Mọi người có thể trả lời tốt hơn cho một câu hỏi thách thức họ cải thiện trên một con số cụ thể. Ngay bây giờ bạn đang hỏi rất nhiều lý do tại sao, mà không giải thích tại sao mỗi lý do tại sao lại quan trọng.
goldilocks

Câu trả lời:


8

Các tùy chọn:

  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

Những điều cần cân nhắc

  • độ trễ [ms] (có và không yêu cầu khách hàng muốn nhiều khung hình / giây hơn máy chủ)
  • CPU nhàn rỗi [%] (được đo bằng top -d 10)
  • CPU 1 máy khách [%]
  • RAM [MB] (RES)
  • cài đặt mã hóa giống nhau
  • cùng tính năng
    • âm thanh
    • kết nối lại
    • Hệ điều hành máy khách độc lập (vlc, webrtc, v.v.)

So sánh:

            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
Tại sao tất cả các giá trị trong bảng này " ?"?
larsks

@larsks vì không ai quan tâm để kiểm tra và điền dữ liệu vào wiki wiki cộng đồng này
user1133275 19/03/18

6

Cách hiện đại duy nhất để truyền H264 tới trình duyệt là UV4L : không có độ trễ, không có cấu hình, với âm thanh tùy chọn, âm thanh / video hai chiều tùy chọn. Không có nước sốt GStreamer ma thuật, nhưng vẫn có thể mở rộng việc sử dụng nó.


Vì tôi muốn phát trực tuyến đến máy chủ của mình và có khả năng là điện thoại thông minh, nên truyền phát đến trình duyệt không phải là một yêu cầu. Ngoài ra, trình duyệt có thể đặt thêm hạn chế cho nó (ví dụ: không có RTSP, có khả năng không có TCP trừ khi bạn sử dụng WebRTC, nhưng điều đó thật khó hiểu). Nhưng UV4L vẫn có vẻ đầy hứa hẹn. Bạn có thể liên kết đến một nơi mà tôi có thể đọc về cách sử dụng nó / lấy dữ liệu ra khỏi đó để truyền phát qua mạng không?
nh2

Chúa ơi, tôi nghĩ rằng tôi đã tìm thấy trang ví dụ ... điều này dường như có thể làm mọi thứ ! Truyền trực tuyến RTMP, RTSP, HTTPS, WebRTC, "Phát hiện đối tượng trong thời gian thực và theo dõi đối tượng + Nhận diện khuôn mặt" - cái quái gì vậy ?? Mỗi với một số cờ dòng lệnh đơn giản để uv4l? Đường ống dẫn của tôi trông khá lỗi thời! Không thể chờ đợi để kiểm tra độ trễ như thế nào!
nh2

1
Ồ không, đó là nguồn đóng :( Điều đó không đủ điều kiện cho việc sử dụng giám sát tại nhà mà tôi có trong tâm trí :(
nh2

Nó không hỗ trợ WebRTC, WebRTC 2 chiều. độ trễ là ~ 200ms âm thanh / video, âm thanh có lẽ ít hơn
prinxis

@ nh2, liên kết dường như bị hỏng, bạn có vị trí cập nhật nào cho trang ví dụ đó không?
Trừng phạt Soni

0

1.) h264es phát trực tuyến trên mạng (chỉ mẫu)

trên máy chủ:

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

trên máy khách:

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

2.) mjpeg truyền phát qua mạng (chỉ mẫu)

trên máy chủ:

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

trên máy khách:

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

tất cả điều này thậm chí hoạt động trên RPi Zero W (được định cấu hình như máy chủ)


Hey, cảm ơn bạn đã trả lời, sample onlycó nghĩa là gì?
nh2

Tôi muốn nói "đó chỉ là một ví dụ". Bạn có thể thích ứng điều này với nhu cầu của bạn.
Sparkie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.