AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Schnelle Bildschirmübertragung per Netzwerk

Schnelle Bildschirmübertragung per Netzwerk

Offene Frage von "Mavarik"
Ein Thema von Zacherl · begonnen am 16. Okt 2012 · letzter Beitrag vom 11. Nov 2016
Antwort Antwort
Popov
(Gast)

n/a Beiträge
 
#1

AW: Schnelle Bildschirmübertragung per Netzwerk

  Alt 16. Okt 2012, 19:16
Den eigentlichen Codec kenne ich nicht mehr. Ist schon sehr lange her. Das war noch zu Win95 Zeit, wo Multimedia noch nicht so einfach klappte wie heute und ich eine Demo erstellen sollte die über CD verteilt auf allen Rechnern funktionieren sollte. Deshalb wollte ich etwas eigenes basteln.

Aber paar Jahre später habe ich bei TechSmith (SnagIt & Co) auch einen Codec gesehen der ähnlich arbeitete.

Aber letztendlich bleibt dir wohl nur noch Ockhams Rasiermesser, denn wenn du schon optimiert mit Vollbild arbeitest, aber TeamViewer schneller ist, dann stellt sich die Frage ob TeamViewer mit Vollbild oder mit Bildbereichen arbeitet.
  Mit Zitat antworten Zitat
Benutzerbild von olee
olee

Registriert seit: 16. Feb 2008
Ort: Boppard
540 Beiträge
 
Turbo Delphi für Win32
 
#2

AW: Schnelle Bildschirmübertragung per Netzwerk

  Alt 16. Okt 2012, 20:07
Ich habe erst vor kurzem eine sehr einfache aber effiziente Methode der Übertragung von Bildschirminhalt geschrieben.
Das Prinzip war folgendermaßen:

-> Mit Scanline letzten und nächten Frame vom Bildschirm pixelweise durchgehen.
---> Wenn ein (außreichend großer?) Unterschied von beiden Pixeln festgestellt wird, werden in den Stream die Pixelnummer (zeile*width+x) und ein Platzhalter für die Anzahl an Pixeln geschrieben
---> Solange die folgenden Pixel sich von dem Original unterscheiden (+ lookahead von 2 Pixeln) wird jeder weitere Pixel in den Stream geschrieben.
---> Wenn 3 aufeinanderfolgende Pixel wieder gleich sind, wird mit dem schreiben aufgehört.
---> Wenn der Schreibvorgang beendet wird, wird noch die Anzahl geschriebener Pixel an den Platzhalter geschrieben
---> Bei durchgehen aller Pixel werden dabei Zeilenenden ignoriert.
-> Der Finale Stream wird noch mit ZLib gepackt.

-> Das Wiederherstellen des Bildes beim Zielrechner geschieht analog.

Hier mal die beiden Funktionen dafür:
Delphi-Quellcode:
procedure compressStream(input, output: TStream);
var
  xx: TCompressionStream;
begin
  xx := TCompressionStream.Create(clmax, output);
  try
    input.Position := 0;
    xx.CopyFrom(input, input.Size);
  finally
    xx.Free;
    output.position := 0;
  end;
end;

procedure TForm1.WriteDiffPkg(last, next: TBitmap; zipPkg: TMemoryStream);
var
  w, h : Integer;
  ix, iy : Integer;
  pixpos : Cardinal;
  cnt : Cardinal;

  addr : Int64;
  pl, pn : PRGBTriple;
  diff : Boolean;

  pkg : TMemoryStream;
type
  PLongWord = ^LongWord;
begin
  pkg := TMemoryStream.Create;
  try
    w := last.Width;
    h := last.Height;

    pixpos := 0;
    diff := false;
    for iy := 0 to h - 1 do
    begin
      pl := last.ScanLine[iy];
      pn := next.ScanLine[iy];
      for ix := 0 to w - 1 do
      begin
        If ((PLongWord(pl)^ and $F0F0F0) = (PLongWord(pn)^ and $F0F0F0)) then
        begin
          If diff then
          begin
            inc(pl); inc(pn);
            If ((PLongWord(pl)^ and $F0F0F0) = (PLongWord(pn)^ and $F0F0F0)) then
            begin
              inc(pl); inc(pn);
              If ((PLongWord(pl)^ and $F0F0F0) = (PLongWord(pn)^ and $F0F0F0)) then
              begin
                PCardinal(Integer(Pkg.Memory) + addr)^ := cnt;
                diff := false;
              end;
              dec(pl); dec(pn);
            end;
            dec(pl); dec(pn);
            If diff then
            begin
              Pkg.Write(pn^, 3);
// pl^.rgbtRed := 0;
// pl^.rgbtGreen := 0;
// pl^.rgbtBlue := 0;
              inc(cnt);
            end;
          end;
        end
        else
        begin
          If not diff then
          begin
            cnt := 0;
            addr := Pkg.Size;
            Pkg.WriteCardinal(0);
            Pkg.WriteCardinal(pixpos);
            diff := true;
          end;
          Pkg.Write(pn^, 3);
// pl^.rgbtRed := 0;
// pl^.rgbtGreen := 0;
// pl^.rgbtBlue := 0;
          inc(cnt);
        end;
        inc(pixpos);
        inc(pl);
        inc(pn);
      end;
    end;
    Pkg.WriteCardinal(0);
  finally
    zipPkg.Clear;
    pkg.Position := 0;
    compressStream(pkg, zipPkg);
    pkg.Free;
  end;
end;

procedure TForm1.ReadDiffPkg(last: TBitmap; zipPkg: TStream);
var
  w, h : Integer;
  ix, iy : Integer;
  pixpos : Cardinal;
  cnt : Cardinal;

  addr : Cardinal;
  ssize : Int64;
  pix : PRGBTriple;

  pkg : TDecompressionStream;
type
  PLongWord = ^LongWord;
begin
  zipPkg.Position := 0;
  pkg := TDecompressionStream.Create(zipPkg);
  try
    w := last.Width;
    h := last.Height;

    ix := 0;
    iy := 0;
    pixpos := 0;
    pix := last.ScanLine[iy];
    //while Pkg.Position < Pkg.Size do
    while true do
    begin
      cnt := Pkg.ReadCardinal;
      If cnt = 0 then break;
      addr := Pkg.ReadCardinal;

      // Fast-forward to address
      ix := addr mod w;
      iy := addr div w;
      pix := last.ScanLine[iy];
      inc(pix, ix);

      // Write data
      while cnt > 0 do
        If (ix < w) then
        begin
          Pkg.Read(pix^, 3);
          inc(ix);
          inc(pixpos);

          dec(cnt);
          inc(pix);
        end
        else
        begin
          inc(iy);
          pix := last.ScanLine[iy];
          ix := 0;
        end;
    end;
  finally
    pkg.Free;
  end;
end;
Bei Interesse kann ich auch noch eine Variation der Funktion posten, welche per Flag nur jede gerade/ungerade Zeile verarbeitet, um schnellere Updates zu ermöglichen.
Diese Technik hat sich im Praxistest als unglaublich schnell für die Übertragung von Textinhalten erwiesen.
Man kann bestimmt das ganze durch Bittiefenreduzierung noch optimieren...
Björn Zeutzheim
Codename: Performancepumpe
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#3

AW: Schnelle Bildschirmübertragung per Netzwerk

  Alt 16. Okt 2012, 20:22
Für diejenigen, die diesen Praxitest selber durchführen wollen, hier...

[Jo, die Idee kam ihm als ich vorschlug, dass man Differenzbilder erzeugen kann und diese dann komprimiert; dadurch dass bei der Differenz ein großer Teil schwarz (nicht veränderter Teil) ist, sorgt das für eine sehr gute Komprimierung; daraufhin meinte er, dass man die schwarzen Teile direkt weglassen sollte (also wirklich nur die Daten schicken, die auch verändert wurden)]

Kleine Anmerkung - das ist nur ne Testanwendung; bei Fehlermeldungen ein Auge zudrücken

Implementiert von mir
Angehängte Dateien
Dateityp: rar ScreenStreamer - FINAL.rar (350,4 KB, 93x aufgerufen)
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG

Geändert von Aphton (16. Okt 2012 um 21:33 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von olee
olee

Registriert seit: 16. Feb 2008
Ort: Boppard
540 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Schnelle Bildschirmübertragung per Netzwerk

  Alt 16. Okt 2012, 20:22
Danke fürs posten
Björn Zeutzheim
Codename: Performancepumpe
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: Schnelle Bildschirmübertragung per Netzwerk

  Alt 16. Okt 2012, 23:16
Danke euch beiden, das sieht doch recht vielversprechend aus Ich werde mir die Funktion mal selbst für variable Bittiefen anpassen. Die Erweiterung für gerade und ungerade Zahöen ist einfach damit der Empfänger schonmal in der Hälfte der Zeit eine Änderung sieht? Wäre auf jeden Fall auch da an deiner Umsetzung interessiert.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#6

AW: Schnelle Bildschirmübertragung per Netzwerk

  Alt 17. Okt 2012, 00:03
Joa. Aufjedenfall kann ich mit ihm Videos im kleinen Player auf youtube mit 7-8fps mitkucken!

Bzgl der Aufnahme: bei mir (i7 3.4 ghz) kann ich mit 30~ fps im Schnitt per StretchBlt / BitBlt Bilder mit der Auflösung 1920x1080 aufzeichnen. Deaktiviere ich Aero, so steigt es auf ~150.

Also falls man da noch ein paar Frames rausholen will, könnte man dieses Bottleneck entfernen... DwmDisableComposition()
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
Benutzerbild von olee
olee

Registriert seit: 16. Feb 2008
Ort: Boppard
540 Beiträge
 
Turbo Delphi für Win32
 
#7

AW: Schnelle Bildschirmübertragung per Netzwerk

  Alt 17. Okt 2012, 01:14
Hi nochmal,

Dein Posting hier hatte nochmal mein Interesse geweckt und da hab ich schnell mal das alte Programm mit Aphton's Hilfe etwas überarbeitet und auch die unterscheidung zwischen den Bittiefen 8 / 24 Bit hinzugefügt, sowie mancher kleiner Extras.
Wenn du Interesse an diesem "Codec" hast, ich habe ihn als Unit angehangen.

EDIT: Schon irgendwie lustig, dass du dieses Thema anpackst, wo wir erst vor kurzem selbst drauf gekommen sind
Wäre cool, wenn du das ganze vielleicht noch schneller bekommen könntest!
Testen lässt sich das am besten mit ein paar ausgewählten Bildern, welche man laden, durch den Codec jagen und anschließend nach Paketgrößen prüfen kann.

EDIT-2: Der neue Code ist auch variabel auf einen *übertrage-jede-n-te-Zeile* mit Parameter 'n' einstellbar.

EDIT-3 (man bin ich vergesslich -.-'): Das neue Programm hat sich je nach Scenario sogar schneller als Teamviewer erwiesen. Scheint als wäre das der richtige Weg

Viel Spaß damit

MFG
Angehängte Dateien
Dateityp: zip ScreenShare.zip (268,1 KB, 81x aufgerufen)
Dateityp: pas ScreenShareCodec.pas (4,9 KB, 84x aufgerufen)
Björn Zeutzheim
Codename: Performancepumpe

Geändert von olee (17. Okt 2012 um 01:20 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:08 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz