Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Firemonkey - ungültige Zeigeroperation (https://www.delphipraxis.net/179138-firemonkey-ungueltige-zeigeroperation.html)

Sir Rufo 20. Feb 2014 22:13

AW: Firemonkey - ungültige Zeigeroperation
 
Es wird im
Delphi-Quellcode:
else
-Zweig kein Thread aufgerufen, sondern aus dem aktuellen Thread-Kontext heraus wird synchronisiert die andere Methode aufgerufen.

Dieses geschieht aber auch nur dann, wenn der Aufruf nicht im Kontext des MainThreads erfolgt.

Der Aufruf erfolgt aber eben immer im MainThread-Kontext (darauf habe ich schon hingewiesen und auf die Dokumentation, die sagt, dass Synchronize im MainThread-Kontext böse ist).

Ich wollte damit nur verdeutlichen, wie man so einen synchronisierten Aufruf implementieren sollte, damit es eben nicht da zu Problemen führen kann.

Im Setter wird ein Vergleich gemacht und wenn das nicht passt, dann wird der Rest ausgeführt.
Aber du hast insofern Recht, weil dort der Setter und darin eine weitere Funktion aufgerufen wird. Und jeder call kostet durchaus Zeit.

Darum gibt es ja auch für performance-relevante Funktionen den Tipp, diese als
Delphi-Quellcode:
inline
zu deklarieren. Das macht die EXE zwar grösser aber auch schneller.

Harry Stahl 20. Feb 2014 22:25

AW: Firemonkey - ungültige Zeigeroperation
 
Zitat:

Zitat von Sir Rufo (Beitrag 1248889)
Aber du hast insofern Recht, weil dort der Setter und darin eine weitere Funktion aufgerufen wird. Und jeder call kostet durchaus Zeit.

Darum gibt es ja auch für performance-relevante Funktionen den Tipp, diese als
Delphi-Quellcode:
inline
zu deklarieren. Das macht die EXE zwar grösser aber auch schneller.

Da stimme ich Dir zu. Bei meinem Bildverarbeitungsprogramm, wo ich z.B. in der Ebenendarstellung ein unteres mit dem oberen Bild verrechnen muss, z.B. bezogen auf unterschiedliche Transparenzwerte im jeweiligen Bild, Deckungskraft der Ebenen, Masken und Filter ("Strahlendes Licht", etc). kommen ganz schnell mehrere 100 Mio. Berechnungsvorgänge beisammen. Ohne Inline geht das an bestimmten Stellen gar nicht mehr. Im normalen Programmablauf macht ein Call nichts aus, musst Du aber einen Call mehrere 100 Mio. mal aufrufen, evtl. sogar Parameter übergeben, dann merkt man es ganz heftig.

blawen 26. Feb 2014 12:05

AW: Firemonkey - ungültige Zeigeroperation
 
Beim ausführen des Programms bekomme ich nun keine Fehlermeldung mehr (beim beenden des Programms hingegen schon).

Ein grundlegendes Problem bleibt bei mir trotzdem (bei beiden Varianten):
Das Bild wird nach kurzer Zeit kurz eingefroren und geht dann wieder weiter. Das nächste Einfrieren findet anschliessend etwas früher statt, dafür dauert es aber etwas länger. Nach einer Minute oder so findet ein Bildwechsel nur noch alle x-Sekunden statt.

Sir Rufo 26. Feb 2014 23:33

AW: Firemonkey - ungültige Zeigeroperation
 
Ich denke wir haben hier primär ein Timing-Problem. Das hat Harry ja schon versucht mit dem
Delphi-Quellcode:
Sleep
in den Griff zu bekommen.

Das könnte sich aber auch wiederum negativ auf die Kommunikation mit der Kamera selber auswirken.

Um dem System jetzt wirklich Luft zu verschaffen, sollte es nicht für 100ms schlafen geschickt werden, sondern nur alle 100ms ein Bild von der Kamera auslesen.
Delphi-Quellcode:
type
  TForm2 = class( TForm )
    ...
  private
    FLastRead : TDateTime;
    ...
  end;

procedure TForm2.SampleBufferReady(Sender: TObject; const ATime: TMediaTime);
begin
  if MilliSecondsBetween( FLastRead, Now ) < 100 then
    Exit;

   VideoCamera.SampleBufferToBitmap(Image1.Bitmap, True);

  //Resize the image so that the video is buffered in its original size
  if (Image1.Width <> Image1.Bitmap.Width) or (Image1.Height <> Image1.Bitmap.height) then begin
    Image1.Width:=Image1.Bitmap.Width;
    Image1.Height:=Image1.Bitmap.Height;
  end;

  FLastRead := Now;
end;
Ungetestet aber einen Blick wert.

Auch wäre es einen Versuch wert den SampleBuffer nicht direkt in die Image-Komponente zu blasen, sondern in eine unabhängige
Delphi-Quellcode:
TBitmap
-Instanz zu laden und dann erst der Image-Komponente zuzuweisen. Macht aber nur Sinn, wenn diese Instanz von der Form vorgehalten wird und somit nicht ständig erzeugt und zerstört wird.

Ich habe jetzt nicht im Source nachgeschaut wie der SampleBuffer in das Bitmap geschoben wird, aber es ist denkbar, dass dabei ein mehrfaches Neuzeichnen der Image-Komponente provoziert wird.

Mit der Bitmap-Instanz dazwischen müsste man das zuverlässig auf ein Neuzeichnen reduzieren können.

Eine weitere Option wäre es das VideoCaptureDevice in einem eigenen Thread zu starten und auch dort den SampleBuffer auszulesen. Hier ist jetzt noch eine geschickte Logik gefragt, wie die Image-Komponente an das Bild kommt ohne den Capture-Thread auszubremsen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:16 Uhr.
Seite 2 von 2     12   

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 by Thomas Breitkreuz