Forum: PC Hard- und Software Mehrere Livestreams auf Raspberry Pi


von rpi (Gast)


Lesenswert?

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

von Sascha W. (sascha-w)


Lesenswert?

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
von rpi (Gast)


Lesenswert?

Hallo,

das Enconding das in der Kamera eingestellt ist ist h265.
Mit (Netzwerk)kameras begebe ich mich auf Neuland, kann der Raspberry 
damit umgehen?

von Sheeva P. (sheevaplug)


Lesenswert?

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/

von rpi (Gast)


Lesenswert?

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?

von c-hater (Gast)


Lesenswert?

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?

von Weingut P. (weinbauer)


Lesenswert?

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

von Sheeva P. (sheevaplug)


Lesenswert?

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?

von rpi (Gast)


Lesenswert?

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

von fchk (Gast)


Lesenswert?

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

von Nur_ein_Typ (Gast)


Lesenswert?

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.

von Dieter D. (Firma: Hobbytheoretiker) (dieter_1234)


Lesenswert?

Probiere es mal mit v4l, bzw. v4l2 und fswebcam.

von M.M.M (Gast)


Lesenswert?

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

von Dieter D. (Firma: Hobbytheoretiker) (dieter_1234)


Lesenswert?

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
von Nur_ein_Typ (Gast)


Lesenswert?

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

von Thomas (Gast)


Lesenswert?

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

von Nur_ein_Typ (Gast)


Lesenswert?

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... :-)

von Frank K. (fchk)


Lesenswert?

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

von rpi (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.