Hallo zusammen, mit einem Raspberry Pi4 sollen mehrere (bis zu 6) IP Kameras angezeigt werden. Bewegungserkennung, Aufzeichnung etc. sind nicht notwendig. Jede der Kameras schickt ihren Stream per RTSP ins Netzwerk (Kabelgebunden, kein WiFi). Am Raspberry Pi ist ein 15 Zoll Touchscreen angeschlossen (1920x1080), wird nun auf einen der Kamerastreams getippt soll dieser im Vollbild angezeigt werden(1920x1080). Bei erneutem drücken soll wieder die Übersicht angezeigt werden, falls nötig kann dann die Auflösung je Stream entsprechend reduziert werden. Zunächst sah motioneye recht vielversprechend aus, leider wird das ganze bereits mit dem zweiten Stream furchtbar langsam. Das ein Raspberry Pi recht begrenzte Resourcen hat ist klar, dennoch hatte ich gehofft eine schlanke Software zu finden bei der bis zu 6 Streams einigermaßen flüssig laufen. Kennt hier jemand eine schlanke Software für den Pi bei der bis zu 6 Kameras flüssig laufen? Danke Daniel
Hallo, Währe interessant was deine CAMs ausgeben, RTSP ist ja nur die Art der Übertragung und sagt nichts über die Codierung aus. Und wenn der PI für den Stream keine Hardware Dekodierung unterstützt wirst du schlechte Karten haben. Sascha
:
Bearbeitet durch User
Hallo, das Enconding das in der Kamera eingestellt ist ist h265. Mit (Netzwerk)kameras begebe ich mich auf Neuland, kann der Raspberry damit umgehen?
Sascha W. schrieb: > Währe interessant was deine CAMs ausgeben, RTSP ist ja nur die Art der > Übertragung und sagt nichts über die Codierung aus. Und wenn der PI für > den Stream keine Hardware Dekodierung unterstützt wirst du schlechte > Karten haben. Das ist der eine Aspekt, der andere ist die Netzwerkbandbreite [1]. Wenn genug davon vorhanden ist könnte der RasPi die Streams ggf. über OpenCV lesen und entsprechend konvertieren [2]. Der Mensch in diesem Link benutzt aber, wenn ich das richtig sehe, Motion-JPEG (MJPEG), das recht viel Bandbreite braucht -- und da der RasPi standardmäßig nur eine einzige 1GbE-Schnitstelle hat, über die schon die sechs Eingabestreams laufen müssen, wird die wohl schnell saturiert sein. Es gibt wohl 5GbE-Adapter für USB3, aber damit habe ich keine Erfahrung -- YMMV. [1] https://www.cctvcalculator.net/en/calculations/bandwidth-calculator/ [2] https://www.pyimagesearch.com/2019/09/02/opencv-stream-video-to-web-browser-html-page/
Die Netzwerkbandbreite liegt bei ca 80Mbit/s, da alle Komponenten 1GBit/s unterstützen wird das wohl nicht der Flaschenhals sein. Die CPU Auslastung des Raspberry ist jedoch bei allen 4 Kernen bei 100%, daraus schließe ich das er mit dem Encoding nicht fertig wird. Da man in den Kameras nichts anderes als h265 einstellen kann wird wohl nichts anderes bleiben als auf eine andere Hardware zu wechseln. Oder liege ich mit meiner Einschätzung daneben?
rpi schrieb: > Die CPU Auslastung des Raspberry ist jedoch bei allen 4 Kernen bei 100%, > daraus schließe ich das er mit dem Encoding nicht fertig wird. Du meinst: Decoding. Aber ja, genau das schafft er offensichtlich nicht. Mit etwas älteren Kameras mit H.246 hätte es eventuell klappen können, die kann der Pi nämlich in Hardware decodieren. > Da man in den Kameras nichts anderes als h265 einstellen kann wird wohl > nichts anderes bleiben als auf eine andere Hardware zu wechseln. > Oder liege ich mit meiner Einschätzung daneben? Nö, würde ich auch so sehen. Wobei die Frage zu stellen wäre: Welche Hardware soll getauscht werden. Die guten aktuellen Kameras gegen was altes oder der offensichtlich untermotorisierte RasPi gegen einen richtigen Rechner?
Können die Kameras auch n standbild ausgeben als jpg? Dann könnte man das in ne Website einbauen und per JS zyklisch das Standbild pollen, per Antippen dann auf das Vollbild mit Livestream
rpi schrieb: > Die Netzwerkbandbreite liegt bei ca 80Mbit/s, da alle Komponenten > 1GBit/s unterstützen wird das wohl nicht der Flaschenhals sein. > > Die CPU Auslastung des Raspberry ist jedoch bei allen 4 Kernen bei 100%, > daraus schließe ich das er mit dem Encoding nicht fertig wird. Oder es liegt am Decoding, wir wissen es halt nicht. > Da man in den Kameras nichts anderes als h265 einstellen kann wird wohl > nichts anderes bleiben als auf eine andere Hardware zu wechseln. Ein denkbarer Ansatz wäre aus meiner Perspektive, daß die Cams doch vermutlich bereits fertig encodierte Videostreams liefern. Müssen die denn zwangsläufig über den RasPi laufen, oder kann das Webinterface des Pi nur darauf verlinken? Und selbst wenn Du über den Pi gehen willst: müssen die dort de- und encodiert werden? Kann man da nicht einfach einen TCP Reverse Proxy dazwischen hängen?
Nach einigen Tagen des einlesens und ausprobierens bin ich ein Stück weiter gekommen: Der Raspberry Pi 4 unterstützt das Hardwaredecoding von h265, leider ist die bisher einzige Software (die ich gefunden habe)die das auch benutzt Kodi. Hier bekomme ich aber ein flüssiges Bild bei nur 10% CPU Auslastung. Wenn ich es richtig verstanden habe benutzt Kodi, ebenso wie Motioneye unter der Haube ffmpeg. ffmpeg sollte man aber auch mit h265 Unterstützung kompilieren können, dann sollte Motioneye, das mir deutlich besser gefällt, doch auch auf einem Raspberry Pi 4 h265 decodieren können. Die Formulierung ist etwas holprig, da ja nicht Motioneye decodiert sondern ffmpeg, aber ich glaube es ist klar was ich meine. Kann diese Theorie jemand bestätigen bevor ich mich jetzt einarbeite wie man ffmpeg auf dem Pi kompiliert? Danke und Gruß Daniel
Ich denke, Du hast die falsche Hardware. Ein NVIdia Jetson Nano oder besser ein Xavier NX wäre eher geeignet, denn da ist neben den den ARM-Kernen noch eine halbwegs dicke GPU dabei, die Du haben willst. Und die wird von NVidia auch gut unterstützt. Auf dieser Plattform solltest Du dich dann mit GStreamer beschäftigen, das die Hardwarebeschleunigung gut unterstützt. fchk
fchk schrieb: > Ich denke, Du hast die falsche Hardware. Ein NVIdia Jetson Nano oder > besser ein Xavier NX wäre eher geeignet, denn da ist neben den den > ARM-Kernen noch eine halbwegs dicke GPU dabei, die Du haben willst. Und > die wird von NVidia auch gut unterstützt. Auf dieser Plattform solltest > Du dich dann mit GStreamer beschäftigen, das die Hardwarebeschleunigung > gut unterstützt. Tatsächlich haben auch die RasPis eine leistungsfähige GPU.
rpi schrieb: > Der Raspberry Pi 4 unterstützt das Hardwaredecoding von h265, leider ist > die bisher einzige Software (die ich gefunden habe)die das auch benutzt > Kodi. Hier bekomme ich aber ein flüssiges Bild bei nur 10% CPU > Auslastung. Und? Was nützt Dir das? Du willst ja gleich sechs h265 Streams parallel dekodieren, und das in Hardware, weil in Software packt das der Pi sowieso nicht. Schon mal erkundigt, wie viele Streams in Hardware parallel dekodiert werden können? In der Spec zum Pi steht nix davon, daß mehr als ein Stream (4k) möglich ist. Das sieht mir stark nach dem falschen Werkzeug für die Aufgabe aus.pi h265 hardware Nur_ein_Typ schrieb: > Tatsächlich haben auch die RasPis eine leistungsfähige GPU. Du weißt mehr? Dann her mit einem Link. Also, eigentlich ist das mal wieder so ein typischer Thread, wie leider so viele hier im Forum. Statt das der TE fragt, wie eine Aufgabe zu lösen ist, also "6 FHD Streams (natürlich skaliert) gleichzeitig auf einem Bildschirm darzustellen", kommt er zuerst mit dem Werkzeug. Das liest sich immer so, als wenn jemand mit Schraubendreher und Nägeln daher kommt und will damit nun ein Regal an der Wand anbringen und dann muß gefrickelt und gewurschtelt werden, weil man ja schon mal einen kleinen Nagel mit der Schraubendreherkopf in Holz eingeschlagen hat und "so schwer kann ja ne Lösung nicht sein" usw. usf...
Auf meinem Raspi wird das 4k Demofile unter vlc https://x265.com/hevc-video-files/ Ruckelfrei ohne viel Last abgespielt, aber der Monitor wird immer wieder dunkel dabei, trotz orginal Raspi-Netzteil fällt die interne Betriebsspannung mit Peaks unter die magischen 4,85V. Etwas besser ist es im Fullscreen-Mode.
1 | $ v4l2-ctl -d 10 --list-formats-out |
2 | ioctl: VIDIOC_ENUM_FMT |
3 | Type: Video Output Multiplanar |
4 | |
5 | [0]: 'H264' (H.264, compressed) |
6 | [1]: 'MJPG' (Motion-JPEG, compressed) |
7 | |
8 | $ vcgencmd codec_enabled H264 |
9 | H264=enabled |
10 | $ vcgencmd codec_enabled H265 |
11 | H265=disabled |
Letzteres verrät was wirklich los ist. (https://www.raspberrypi.org/forums/viewtopic.php?t=262558) omxplayer soll vielleicht gehen.
1 | $ omxplayer -i /home/pi/Videos/Demo_4k_BigBuckBunny_2000hevc.mp4 |
2 | Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/pi/Videos/Demo_4k_BigBuckBunny_2000hevc.mp4': |
3 | Metadata: |
4 | major_brand : iso4 |
5 | minor_version : 1 |
6 | compatible_brands: iso4hvc1 |
7 | creation_time : 2014-08-25T21:13:56.000000Z |
8 | Duration: 00:00:10.00, start: 0.083333, bitrate: 2013 kb/s |
9 | Stream #0:0(und): Video: hevc (Main) (hvc1 / 0x31637668), yuv420p(tv), 3840x2160, 2010 kb/s, 24 fps, 24 tbr, 24k tbn, 24 tbc (default) |
10 | Metadata: |
11 | creation_time : 2014-08-25T21:13:56.000000Z |
12 | handler_name : hevc:fps=24@GPAC0.5.1-DEV-rev4807 |
13 | have a nice day ;) |
14 | |
15 | $ omxplayer /home/pi/Videos/Demo_4k_BigBuckBunny_2000hevc.mp4 |
16 | Vcodec id unknown: ad |
17 | have a nice day ;) |
Klappte nicht. Hier steht noch etwas: https://www.raspberrypi.org/forums/viewtopic.php?t=273444 Etwas wenig Memory ist für gpu reserviert. $ vcgencmd get_mem gpu gpu=76M
:
Bearbeitet durch User
M.M.M schrieb: > Nur_ein_Typ schrieb: >> Tatsächlich haben auch die RasPis eine leistungsfähige GPU. > > Du weißt mehr? Dann her mit einem Link. Offenbar weiß ich mehr, und natürlich google ich das gerne für Dich: [1]. > Also, eigentlich ist das mal wieder so ein typischer Thread, wie leider > so viele hier im Forum. Statt das der TE fragt, wie eine Aufgabe zu > lösen ist, > also "6 FHD Streams (natürlich skaliert) gleichzeitig auf einem > Bildschirm darzustellen", kommt er zuerst mit dem Werkzeug. Stimmt, das ist ein sehr typischer Tread, denn Du erklärst sein Werkzeug gleich für ungeeignet -- ohne es näher zu kennen, wohlgemerkt, sonst hättest Du mich ja nicht um einen Link "bitten" müssen -- und empfiehlst deswegen stattdessen gleich einfach mal andere Werkzeuge. Das kennen wir hier sehr gut, egal um was es geht; insbesondere dann, wenn jemand Jeho^WRaspberry Pi sagt, kann man die Uhr danach stellen, wann der Erste nach einer zünftigen Steinigung ruft. Dabei hat "Sheeva P." die ideale Lösung doch schon genannt: gar nicht auf dem Webserver de- oder enkodieren, sondern die Videos einfach durchreichen -- sie also gar nicht serverseitig zu de- und wieder enkodieren, sondern das Dekodieren ganz alleine den Clients überlassen. Die Clients brauchen ohnehin ausreichende Leistungsfähigkeit, um die Streams zu dekodieren und darzustellen. Solange nun auf dem Server keine Verarbeitung stattfinden muß, ist das auch dann die beste Lösung, wenn der Server eine richtig fette Maschine mit mehreren Nvidia- oder ATI-Grafikkarten ist. Denn die teure, aber völlig überflüssige Rechnerei kostet nur unnötig Energie: blöd für den Geldbeutel, blöd für die Umwelt. [1] https://de.wikipedia.org/wiki/Raspberry_Pi#Grafik
Nur_ein_Typ schrieb: > Dabei hat "Sheeva P." die ideale Lösung doch schon genannt: gar nicht > auf dem Webserver de- oder enkodieren, sondern die Videos einfach > durchreichen -- sie also gar nicht serverseitig zu de- und wieder > enkodieren, sondern das Dekodieren ganz alleine den Clients überlassen. Nein. Lesen der Frage hilft: rpi schrieb: > Am Raspberry Pi ist ein 15 Zoll Touchscreen angeschlossen > (1920x1080), wird nun auf einen der Kamerastreams getippt soll dieser im > Vollbild angezeigt werden(1920x1080) Es gibt keinen weiteren Client...
Thomas schrieb: > Nein. Lesen der Frage hilft: > > rpi schrieb: >> Am Raspberry Pi ist ein 15 Zoll Touchscreen angeschlossen >> (1920x1080), wird nun auf einen der Kamerastreams getippt soll dieser im >> Vollbild angezeigt werden(1920x1080) > > Es gibt keinen weiteren Client... Oh, stimmt. Also auch insofern ein typischer Thread... :-)
Nur_ein_Typ schrieb: > fchk schrieb: >> Ich denke, Du hast die falsche Hardware. Ein NVIdia Jetson Nano oder >> besser ein Xavier NX wäre eher geeignet, denn da ist neben den den >> ARM-Kernen noch eine halbwegs dicke GPU dabei, die Du haben willst. Und >> die wird von NVidia auch gut unterstützt. Auf dieser Plattform solltest >> Du dich dann mit GStreamer beschäftigen, das die Hardwarebeschleunigung >> gut unterstützt. > > Tatsächlich haben auch die RasPis eine leistungsfähige GPU. Nützt aber nichts, wenn die nicht richtig unterstützt wird. Da ist nVidia im Vorteil. Und ein Xavier NX soll 32 H.265 Streams in 1920*1080@30Hz parallel dekodieren können. Ich habe ein entsprechendes Devkit da, habe das aber noch nicht ausprobiert. https://www.stereolabs.com/blog/h-264-h-265-video-encoding-support-matrix-for-nvidia-jetson/ fchk
Hallo zusammen, ich habe mir eure Tipps zu Herzen genommen, ein Jetson Nano bestellt und mich in gstreamer eingearbeitet. Mit dieser Pipeline bekomme ich einen beinahe verzögerungsfreien Stream.
1 | gst-launch-1.0 rtspsrc location=rtsp://192.168....... latency=0 ! rtph265depay ! h265parse ! nvv4l2decoder ! nvoverlaysink |
Um das nun in eine GUI zu packen habe ich mich dann mit GTK befasst und folgendes Programm geschrieben.
1 | |
2 | #include <stdlib.h> |
3 | #include <gtk/gtk.h> |
4 | #include <gst/gst.h> |
5 | #include <inttypes.h> |
6 | #include <stdbool.h> |
7 | |
8 | //TODO: use cameraURL instead of dummys |
9 | const uint8_t cams[] = |
10 | { |
11 | 1, |
12 | 2, |
13 | 3, |
14 | 4 |
15 | }; |
16 | |
17 | |
18 | GstElement *pipeline[(sizeof(cams)/sizeof(cams[0]))]; |
19 | |
20 | GtkWidget* newCamera(uint8_t pipeNum) |
21 | { |
22 | GtkWidget *video_window; |
23 | GstElement *source, *depay, *parse, *decoder, *converter, *sink; |
24 | |
25 | pipeline[pipeNum] = gst_pipeline_new("pipe"); |
26 | |
27 | source = gst_element_factory_make("rtspsrc", NULL); |
28 | g_object_set(source, "location", "rtsp://192.168.178.211:554/user=admin_password=_channel=1_stream=0", NULL); |
29 | |
30 | depay = gst_element_factory_make("rtph265depay", NULL); |
31 | parse = gst_element_factory_make("h265parse", NULL); |
32 | decoder = gst_element_factory_make("nvv4l2decoder", NULL); |
33 | converter = gst_element_factory_make("nvvidconv", NULL); |
34 | sink = gst_element_factory_make("gtksink", NULL); |
35 | |
36 | if(!source || !depay || !parse || !decoder || !converter|| !sink) |
37 | { |
38 | printf("ERROR: not all elements could be created\n\r"); |
39 | } |
40 | |
41 | gst_bin_add_many(GST_BIN(pipeline[pipeNum]), source, depay, parse, decoder, converter, sink, NULL); |
42 | |
43 | if(!gst_element_link(source, depay)) |
44 | { |
45 | printf("ERROR: linking source-depay\n\r"); |
46 | } |
47 | |
48 | if(!gst_element_link(depay, parse)) |
49 | { |
50 | printf("ERROR: linking depay-parse\n\r"); |
51 | } |
52 | |
53 | if(!gst_element_link(parse, decoder)) |
54 | { |
55 | printf("ERROR: linking parse-decode\n\r"); |
56 | } |
57 | |
58 | if(!gst_element_link(decoder, converter)) |
59 | { |
60 | printf("ERROR: linking decode-convert\n\r"); |
61 | } |
62 | |
63 | if(!gst_element_link(converter, sink)) |
64 | { |
65 | printf("ERROR: linking convert-sink\n\r"); |
66 | } |
67 | |
68 | /* |
69 | source = gst_element_factory_make("videotestsrc", NULL); |
70 | sink = gst_element_factory_make("gtksink", NULL); |
71 | gst_bin_add_many(GST_BIN(pipeline[pipeNum]), source, sink, NULL); |
72 | gst_element_link(source, sink); |
73 | |
74 | */ |
75 | g_object_get(sink, "widget", &video_window, NULL); |
76 | return video_window; |
77 | } |
78 | |
79 | int main (int argc, char *argv[]) |
80 | { |
81 | GtkWidget *window; |
82 | GtkWidget *vbox1; |
83 | GtkWidget *vbox2; |
84 | GtkWidget *hbox; |
85 | |
86 | gtk_init(&argc, &argv); |
87 | gst_init(&argc, &argv); |
88 | |
89 | //generate Layout |
90 | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
91 | vbox1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); |
92 | vbox2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); |
93 | hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); |
94 | |
95 | //add Cameras to row1 |
96 | gtk_box_pack_start(GTK_BOX(vbox1), newCamera(0), FALSE, FALSE, 0); |
97 | gtk_box_pack_end(GTK_BOX(vbox1), newCamera(1), FALSE, FALSE, 0); |
98 | |
99 | //add Cameras to row2 |
100 | gtk_box_pack_start(GTK_BOX(vbox2), newCamera(2), FALSE, FALSE, 0); |
101 | gtk_box_pack_end(GTK_BOX(vbox2), newCamera(3), FALSE, FALSE, 0); |
102 | |
103 | //add rows to columns |
104 | gtk_box_pack_start(GTK_BOX(hbox), vbox1, FALSE, FALSE, 0); |
105 | gtk_box_pack_end(GTK_BOX(hbox), vbox2, FALSE, FALSE, 0); |
106 | |
107 | gtk_container_add(GTK_CONTAINER(window), hbox); |
108 | |
109 | for(uint8_t i = 0; i < (sizeof(cams)/sizeof(cams[0])); i = i + 1) |
110 | { |
111 | gst_element_set_state(pipeline[i], GST_STATE_PLAYING); |
112 | } |
113 | |
114 | gtk_window_fullscreen(GTK_WINDOW(window)); |
115 | gtk_widget_show_all(window); |
116 | gtk_main(); |
117 | |
118 | return 0; |
119 | } |
Das Problem ist das das Linken zwischen rtspsrc und rtph265depay nicht funktioniert. In der Konsole funktioniert die Pipeline. könnte mir jemand erklären wo das Problem liegt? Danke und Gruß Daniel
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.