Forum: PC-Programmierung Screen-Recording per UDP Streamen


von UDP (Gast)


Lesenswert?

Hallo,

ich arbeite gerade daran, einen Windows-Screen zu "recorden", welches 
dann ein downscaling auf 320*240 (RGB 5:6:5) um es dann per UDP an einen 
uC zu streamen der das auf einem Display anzeigt.

Ich habe das mal testweise in C# implementiert und funktioniert soweit, 
allerdings dauert ein FPS (snapshot+per UDP wegsenden) fast an die 
100ms!

Kennt ihr evtl. eine fertige Video-streamer Software die das machen 
kann?


Gesendet wird das ganze dann unkomprimiert über Ethernet in 128 kleinen 
UDP Paketen zu je 1200 bytes. Damit kommt man dann auf die 320*240*2 
bytes.

Danke

von Frank K. (fchk)


Lesenswert?

VNC gibt es seit Jahrzehnten und ist quelloffen und 
plattformübergreifend. Das macht die Übertragung intelligenter und 
wahlweise auch komprimiert.

Das Protokoll ist in RFC6143 beschrieben.

fchk

von (prx) A. K. (prx)


Lesenswert?

Der Standard für Streaming ist RTP.
https://de.wikipedia.org/wiki/Real-Time_Transport_Protocol

: Bearbeitet durch User
von Matthias Schilder (Gast)


Lesenswert?

Hast du mal mit einem Profiling-Tool geschaut, wo die meiste Zeit 
vertrödelt wird?

Mal ins Blaue geraten: verwendest du zufällig die Bitmap-Klasse aus dem 
Framework, und davon die Methoden SetPixel(..)/.GetPixel(..)? Die sind 
gegenüber dem direkten Zugriff auf den Speicher einfacher zu verwenden, 
aber deutlich langsamer. Zum Lesen: 
https://docs.microsoft.com/en-us/dotnet/api/system.drawing.bitmap.lockbits

von UDP (Gast)


Lesenswert?

Ich share hier grad mal den code.. Mal gespannt ob es klappt.
Das ist quasi die Routine die das alles einmal macht.
1
    
2
      Bitmap printscreen2 = new Bitmap(1600, 1200);
3
      
4
      
5
      Graphics graphics2 = Graphics.FromImage(printscreen2 as Image);
6
      
7
      
8
      
9
      graphics2.CopyFromScreen(0, 0, 0, 0, printscreen2.Size);
10
11
      using (MemoryStream s2 = new MemoryStream())
12
      {
13
        printscreen2.Save(s2, System.Drawing.Imaging.ImageFormat.Bmp);
14
           
15
             
16
             Image bmp2 = ResizeImage(Image.FromStream(s2), 320,240);
17
           
18
             pictureBox2.Image = bmp2;
19
             
20
             
21
             bmp2.RotateFlip(RotateFlipType.Rotate180FlipX);
22
             //Creat a 16 bit copy of it using the graphics class
23
           Bitmap dest = new Bitmap(bmp2.Width, bmp2.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb565);
24
           using (Graphics g = Graphics.FromImage(dest))
25
           {
26
            g.DrawImageUnscaled(bmp2, 0, 0);
27
           }
28
             
29
         Rectangle r = new Rectangle(0,0,dest.Width,dest.Height);
30
           BitmapData bd = dest.LockBits(r, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format16bppRgb565);
31
           byte[] TftData = new byte[dest.Width * dest.Height * 2];
32
           Marshal.Copy(bd.Scan0, TftData, 0, TftData.Length);
33
           
34
           dest.UnlockBits(bd);
35
           byte[] txbuffer = new byte[1201];
36
           
37
           try{
38
             for (int i=0; i<128; i++) {
39
               Buffer.BlockCopy(TftData,0+i*1200,txbuffer,0,1200);
40
               txbuffer[1200] = (byte) i;
41
               udpClient.Send(txbuffer, 1201, "192.168.0.55", 5200);
42
             }
43
             
44
          
45
        
46
          }
47
          catch{
48
            
49
          }

von RTP-Papst (Gast)


Lesenswert?

UDP schrieb:
> Ich share hier grad mal den code.. Mal gespannt ob es klappt.
> Das ist quasi die Routine die das alles einmal macht.
>
>       Bitmap printscreen2 = new Bitmap(1600, 1200);

>              for (int i=0; i<128; i++) {
>                Buffer.BlockCopy(TftData,0+i*1200,txbuffer,0,1200);
>                txbuffer[1200] = (byte) i;
>                udpClient.Send(txbuffer, 1201, "192.168.0.55", 5200);
>              }


Wie willst du einen Bildschirm mit 1600x1200 in 128 Teile a 1201 Byte 
übertragen?

von UDP (Gast)


Lesenswert?

Na es wird ein downscaling auf 320*240 auf 16 Bit Farben gemacht....

Macht dann also 320 x 240 x 2bytes = 153600 bytes -> 128 pakete a 1200 
bytes

von Erwin D. (Gast)


Lesenswert?

OBS-Studio

von foobar (Gast)


Lesenswert?

Kenne die beteiltigten Libraries nicht, aber das Grabben und die 
Konvertierung sieht extrem ineffizient aus (insb die BMP-Konvertierung 
und der MemoryStream zwischendrin).

Außerdem: UDP hat keine Bandbreitenverwaltung - wenn Pakete schneller 
ankommen als sie verarbeitet/weitergeleitet werden können, werden sie 
einfach weggeschmissen.  Du schickst alles in einem Burst ...

von Timmo H. (masterfx)


Lesenswert?

einfach ffmpeg nutzen. FullHD via RDP mit 60 fps kein Problem.
Alternativ gstreamer für geringste Latenz inkl. HW Enc + Dec

: Bearbeitet durch User
von Tim T. (tim_taylor) Benutzerseite


Lesenswert?


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.