Screen-Recording per UDP Streamen

Gast #6874416
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
Gast #6874535
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
Gast #6876483
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
          }
Gast #6876505
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?
Gast #6877007
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 ...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren